1 /**
2 ******************************************************************************
3 * @file stm32h7rsxx_hal_spdifrx.c
4 * @author MCD Application Team
5 * @brief This file provides firmware functions to manage the following
6 * functionalities of the SPDIFRX audio interface:
7 * + Initialization and Configuration
8 * + Data transfers functions
9 * + DMA transfers management
10 * + Interrupts and flags management
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2022 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file
19 * in the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 *
22 ******************************************************************************
23 @verbatim
24 ===============================================================================
25 ##### How to use this driver #####
26 ===============================================================================
27 [..]
28 The SPDIFRX HAL driver can be used as follow:
29
30 (#) Declare SPDIFRX_HandleTypeDef handle structure.
31 (#) Initialize the SPDIFRX low level resources by implement the HAL_SPDIFRX_MspInit() API:
32 (##) Enable the SPDIFRX interface clock.
33 (##) SPDIFRX pins configuration:
34 (+++) Enable the clock for the SPDIFRX GPIOs.
35 (+++) Configure these SPDIFRX pins as alternate function pull-up.
36 (##) NVIC configuration if you need to use interrupt process (HAL_SPDIFRX_ReceiveCtrlFlow_IT() and
37 HAL_SPDIFRX_ReceiveDataFlow_IT() API's).
38 (+++) Configure the SPDIFRX interrupt priority.
39 (+++) Enable the NVIC SPDIFRX IRQ handle.
40 (##) DMA Configuration if you need to use DMA process (HAL_SPDIFRX_ReceiveDataFlow_DMA() and
41 HAL_SPDIFRX_ReceiveCtrlFlow_DMA() API's).
42 (+++) Declare a DMA handle structure for the reception of the Data Flow channel.
43 (+++) Declare a DMA handle structure for the reception of the Control Flow channel.
44 (+++) Enable the DMAx interface clock.
45 (+++) Configure the declared DMA handle structure CtrlRx/DataRx with the required parameters.
46 (+++) Configure the DMA Channel.
47 (+++) Associate the initialized DMA handle to the SPDIFRX DMA CtrlRx/DataRx handle.
48 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
49 DMA CtrlRx/DataRx channel.
50
51 (#) Program the input selection, re-tries number, wait for activity, channel status selection, data format,
52 stereo mode and masking of user bits using HAL_SPDIFRX_Init() function.
53
54 -@- The specific SPDIFRX interrupts (RXNE/CSRNE and Error Interrupts) will be managed using the macros
55 __SPDIFRX_ENABLE_IT() and __SPDIFRX_DISABLE_IT() inside the receive process.
56 -@- Make sure that ck_spdif clock is configured.
57
58 (#) Three operation modes are available within this driver :
59
60 *** Polling mode for reception operation (for debug purpose) ***
61 ================================================================
62 [..]
63 (+) Receive data flow in blocking mode using HAL_SPDIFRX_ReceiveDataFlow()
64 (+) Receive control flow of data in blocking mode using HAL_SPDIFRX_ReceiveCtrlFlow()
65
66 *** Interrupt mode for reception operation ***
67 =========================================
68 [..]
69 (+) Receive an amount of data (Data Flow) in non blocking mode using HAL_SPDIFRX_ReceiveDataFlow_IT()
70 (+) Receive an amount of data (Control Flow) in non blocking mode using HAL_SPDIFRX_ReceiveCtrlFlow_IT()
71 (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can
72 add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback
73 (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can
74 add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback
75 (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can
76 add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback
77
78 *** DMA mode for reception operation ***
79 ========================================
80 [..]
81 (+) Receive an amount of data (Data Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveDataFlow_DMA()
82 (+) Receive an amount of data (Control Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveCtrlFlow_DMA()
83 (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can
84 add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback
85 (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can
86 add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback
87 (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can
88 add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback
89 (+) Stop the DMA Transfer using HAL_SPDIFRX_DMAStop()
90
91 *** SPDIFRX HAL driver macros list ***
92 =============================================
93 [..]
94 Below the list of most used macros in SPDIFRX HAL driver.
95 (+) __HAL_SPDIFRX_IDLE: Disable the specified SPDIFRX peripheral (IDLE State)
96 (+) __HAL_SPDIFRX_SYNC: Enable the synchronization state of the specified SPDIFRX peripheral (SYNC State)
97 (+) __HAL_SPDIFRX_RCV: Enable the receive state of the specified SPDIFRX peripheral (RCV State)
98 (+) __HAL_SPDIFRX_ENABLE_IT : Enable the specified SPDIFRX interrupts
99 (+) __HAL_SPDIFRX_DISABLE_IT : Disable the specified SPDIFRX interrupts
100 (+) __HAL_SPDIFRX_GET_FLAG: Check whether the specified SPDIFRX flag is set or not.
101
102 [..]
103 (@) You can refer to the SPDIFRX HAL driver header file for more useful macros
104
105 *** Callback registration ***
106 =============================================
107
108 The compilation define USE_HAL_SPDIFRX_REGISTER_CALLBACKS when set to 1
109 allows the user to configure dynamically the driver callbacks.
110 Use HAL_SPDIFRX_RegisterCallback() function to register an interrupt callback.
111
112 The HAL_SPDIFRX_RegisterCallback() function allows to register the following callbacks:
113 (+) RxHalfCpltCallback : SPDIFRX Data flow half completed callback.
114 (+) RxCpltCallback : SPDIFRX Data flow completed callback.
115 (+) CxHalfCpltCallback : SPDIFRX Control flow half completed callback.
116 (+) CxCpltCallback : SPDIFRX Control flow completed callback.
117 (+) ErrorCallback : SPDIFRX error callback.
118 (+) MspInitCallback : SPDIFRX MspInit.
119 (+) MspDeInitCallback : SPDIFRX MspDeInit.
120 This function takes as parameters the HAL peripheral handle, the Callback ID
121 and a pointer to the user callback function.
122
123 Use HAL_SPDIFRX_UnRegisterCallback() function to reset a callback to the default
124 weak function.
125 The HAL_SPDIFRX_UnRegisterCallback() function takes as parameters the HAL peripheral handle,
126 and the Callback ID.
127 This function allows to reset the following callbacks:
128 (+) RxHalfCpltCallback : SPDIFRX Data flow half completed callback.
129 (+) RxCpltCallback : SPDIFRX Data flow completed callback.
130 (+) CxHalfCpltCallback : SPDIFRX Control flow half completed callback.
131 (+) CxCpltCallback : SPDIFRX Control flow completed callback.
132 (+) ErrorCallback : SPDIFRX error callback.
133 (+) MspInitCallback : SPDIFRX MspInit.
134 (+) MspDeInitCallback : SPDIFRX MspDeInit.
135
136 By default, after the HAL_SPDIFRX_Init() and when the state is HAL_SPDIFRX_STATE_RESET
137 all callbacks are set to the corresponding weak functions :
138 HAL_SPDIFRX_RxHalfCpltCallback() , HAL_SPDIFRX_RxCpltCallback(), HAL_SPDIFRX_CxHalfCpltCallback(),
139 HAL_SPDIFRX_CxCpltCallback() and HAL_SPDIFRX_ErrorCallback()
140 Exception done for MspInit and MspDeInit functions that are
141 reset to the legacy weak function in the HAL_SPDIFRX_Init()/ HAL_SPDIFRX_DeInit() only when
142 these callbacks pointers are NULL (not registered beforehand).
143 If not, MspInit or MspDeInit callbacks pointers are not null, the HAL_SPDIFRX_Init() / HAL_SPDIFRX_DeInit()
144 keep and use the user MspInit/MspDeInit functions (registered beforehand)
145
146 Callbacks can be registered/unregistered in HAL_SPDIFRX_STATE_READY state only.
147 Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
148 in HAL_SPDIFRX_STATE_READY or HAL_SPDIFRX_STATE_RESET state,
149 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
150 In that case first register the MspInit/MspDeInit user callbacks
151 using HAL_SPDIFRX_RegisterCallback() before calling HAL_SPDIFRX_DeInit()
152 or HAL_SPDIFRX_Init() function.
153
154 When The compilation define USE_HAL_SPDIFRX_REGISTER_CALLBACKS is set to 0 or
155 not defined, the callback registration feature is not available and all callbacks
156 are set to the corresponding weak functions.
157
158 @endverbatim
159 */
160
161 /* Includes ------------------------------------------------------------------*/
162 #include "stm32h7rsxx_hal.h"
163
164 /** @addtogroup STM32H7RSxx_HAL_Driver
165 * @{
166 */
167
168 /** @defgroup SPDIFRX SPDIFRX
169 * @brief SPDIFRX HAL module driver
170 * @{
171 */
172
173 #ifdef HAL_SPDIFRX_MODULE_ENABLED
174 #if defined (SPDIFRX)
175
176 /* Private typedef -----------------------------------------------------------*/
177 /* Private define ------------------------------------------------------------*/
178 /** @defgroup SPDIFRX_Private_Defines SPDIFRX Private Defines
179 * @{
180 */
181 #define SPDIFRX_TIMEOUT_VALUE 10U
182 /**
183 * @}
184 */
185 /* Private macro -------------------------------------------------------------*/
186 /* Private variables ---------------------------------------------------------*/
187 /* Private function prototypes -----------------------------------------------*/
188 /** @addtogroup SPDIFRX_Private_Functions
189 * @{
190 */
191 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma);
192 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
193 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma);
194 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma);
195 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma);
196 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif);
197 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif);
198 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag,
199 FlagStatus Status, uint32_t Timeout, uint32_t tickstart);
200 /**
201 * @}
202 */
203 /* Exported functions ---------------------------------------------------------*/
204
205 /** @defgroup SPDIFRX_Exported_Functions SPDIFRX Exported Functions
206 * @{
207 */
208
209 /** @defgroup SPDIFRX_Exported_Functions_Group1 Initialization and de-initialization functions
210 * @brief Initialization and Configuration functions
211 *
212 @verbatim
213 ===============================================================================
214 ##### Initialization and de-initialization functions #####
215 ===============================================================================
216 [..] This subsection provides a set of functions allowing to initialize and
217 de-initialize the SPDIFRX peripheral:
218
219 (+) User must Implement HAL_SPDIFRX_MspInit() function in which he configures
220 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
221
222 (+) Call the function HAL_SPDIFRX_Init() to configure the SPDIFRX peripheral with
223 the selected configuration:
224 (++) Input Selection (IN0, IN1,...)
225 (++) Maximum allowed re-tries during synchronization phase
226 (++) Wait for activity on SPDIF selected input
227 (++) Channel status selection (from channel A or B)
228 (++) Data format (LSB, MSB, ...)
229 (++) Stereo mode
230 (++) User bits masking (PT,C,U,V,...)
231
232 (+) Call the function HAL_SPDIFRX_DeInit() to restore the default configuration
233 of the selected SPDIFRXx peripheral.
234 @endverbatim
235 * @{
236 */
237
238 /**
239 * @brief Initializes the SPDIFRX according to the specified parameters
240 * in the SPDIFRX_InitTypeDef and create the associated handle.
241 * @param hspdif SPDIFRX handle
242 * @retval HAL status
243 */
HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef * hspdif)244 HAL_StatusTypeDef HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef *hspdif)
245 {
246 uint32_t tmpreg;
247
248 /* Check the SPDIFRX handle allocation */
249 if (hspdif == NULL)
250 {
251 return HAL_ERROR;
252 }
253
254 /* Check the SPDIFRX parameters */
255 assert_param(IS_STEREO_MODE(hspdif->Init.StereoMode));
256 assert_param(IS_SPDIFRX_INPUT_SELECT(hspdif->Init.InputSelection));
257 assert_param(IS_SPDIFRX_MAX_RETRIES(hspdif->Init.Retries));
258 assert_param(IS_SPDIFRX_WAIT_FOR_ACTIVITY(hspdif->Init.WaitForActivity));
259 assert_param(IS_SPDIFRX_CHANNEL(hspdif->Init.ChannelSelection));
260 assert_param(IS_SPDIFRX_DATA_FORMAT(hspdif->Init.DataFormat));
261 assert_param(IS_PREAMBLE_TYPE_MASK(hspdif->Init.PreambleTypeMask));
262 assert_param(IS_CHANNEL_STATUS_MASK(hspdif->Init.ChannelStatusMask));
263 assert_param(IS_VALIDITY_MASK(hspdif->Init.ValidityBitMask));
264 assert_param(IS_PARITY_ERROR_MASK(hspdif->Init.ParityErrorMask));
265 assert_param(IS_SYMBOL_CLOCK_GEN(hspdif->Init.SymbolClockGen));
266 assert_param(IS_SYMBOL_CLOCK_GEN(hspdif->Init.BackupSymbolClockGen));
267
268 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
269 if (hspdif->State == HAL_SPDIFRX_STATE_RESET)
270 {
271 /* Allocate lock resource and initialize it */
272 hspdif->Lock = HAL_UNLOCKED;
273
274 hspdif->RxHalfCpltCallback = HAL_SPDIFRX_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
275 hspdif->RxCpltCallback = HAL_SPDIFRX_RxCpltCallback; /* Legacy weak RxCpltCallback */
276 hspdif->CxHalfCpltCallback = HAL_SPDIFRX_CxHalfCpltCallback; /* Legacy weak CxHalfCpltCallback */
277 hspdif->CxCpltCallback = HAL_SPDIFRX_CxCpltCallback; /* Legacy weak CxCpltCallback */
278 hspdif->ErrorCallback = HAL_SPDIFRX_ErrorCallback; /* Legacy weak ErrorCallback */
279
280 if (hspdif->MspInitCallback == NULL)
281 {
282 hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit */
283 }
284
285 /* Init the low level hardware */
286 hspdif->MspInitCallback(hspdif);
287 }
288 #else
289 if (hspdif->State == HAL_SPDIFRX_STATE_RESET)
290 {
291 /* Allocate lock resource and initialize it */
292 hspdif->Lock = HAL_UNLOCKED;
293 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
294 HAL_SPDIFRX_MspInit(hspdif);
295 }
296 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
297
298 /* SPDIFRX peripheral state is BUSY */
299 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
300
301 /* Disable SPDIFRX interface (IDLE State) */
302 __HAL_SPDIFRX_IDLE(hspdif);
303
304 /* Reset the old SPDIFRX CR configuration */
305 tmpreg = hspdif->Instance->CR;
306
307 tmpreg &= ~(SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
308 SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK |
309 SPDIFRX_CR_CHSEL | SPDIFRX_CR_NBTR | SPDIFRX_CR_WFA |
310 SPDIFRX_CR_CKSEN | SPDIFRX_CR_CKSBKPEN |
311 SPDIFRX_CR_INSEL);
312
313 /* Sets the new configuration of the SPDIFRX peripheral */
314 tmpreg |= (hspdif->Init.StereoMode |
315 hspdif->Init.InputSelection |
316 hspdif->Init.Retries |
317 hspdif->Init.WaitForActivity |
318 hspdif->Init.ChannelSelection |
319 hspdif->Init.DataFormat |
320 hspdif->Init.PreambleTypeMask |
321 hspdif->Init.ChannelStatusMask |
322 hspdif->Init.ValidityBitMask |
323 hspdif->Init.ParityErrorMask
324 );
325
326 if (hspdif->Init.SymbolClockGen == ENABLE)
327 {
328 tmpreg |= SPDIFRX_CR_CKSEN;
329 }
330
331 if (hspdif->Init.BackupSymbolClockGen == ENABLE)
332 {
333 tmpreg |= SPDIFRX_CR_CKSBKPEN;
334 }
335
336 hspdif->Instance->CR = tmpreg;
337
338 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
339
340 /* SPDIFRX peripheral state is READY*/
341 hspdif->State = HAL_SPDIFRX_STATE_READY;
342
343 return HAL_OK;
344 }
345
346 /**
347 * @brief DeInitializes the SPDIFRX peripheral
348 * @param hspdif SPDIFRX handle
349 * @retval HAL status
350 */
HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef * hspdif)351 HAL_StatusTypeDef HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef *hspdif)
352 {
353 /* Check the SPDIFRX handle allocation */
354 if (hspdif == NULL)
355 {
356 return HAL_ERROR;
357 }
358
359 /* Check the parameters */
360 assert_param(IS_SPDIFRX_ALL_INSTANCE(hspdif->Instance));
361
362 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
363
364 /* Disable SPDIFRX interface (IDLE state) */
365 __HAL_SPDIFRX_IDLE(hspdif);
366
367 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
368 if (hspdif->MspDeInitCallback == NULL)
369 {
370 hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspDeInit */
371 }
372
373 /* DeInit the low level hardware */
374 hspdif->MspDeInitCallback(hspdif);
375 #else
376 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
377 HAL_SPDIFRX_MspDeInit(hspdif);
378 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
379
380 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
381
382 /* SPDIFRX peripheral state is RESET*/
383 hspdif->State = HAL_SPDIFRX_STATE_RESET;
384
385 /* Release Lock */
386 __HAL_UNLOCK(hspdif);
387
388 return HAL_OK;
389 }
390
391 /**
392 * @brief SPDIFRX MSP Init
393 * @param hspdif SPDIFRX handle
394 * @retval None
395 */
HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef * hspdif)396 __weak void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif)
397 {
398 /* Prevent unused argument(s) compilation warning */
399 UNUSED(hspdif);
400
401 /* NOTE : This function Should not be modified, when the callback is needed,
402 the HAL_SPDIFRX_MspInit could be implemented in the user file
403 */
404 }
405
406 /**
407 * @brief SPDIFRX MSP DeInit
408 * @param hspdif SPDIFRX handle
409 * @retval None
410 */
HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef * hspdif)411 __weak void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif)
412 {
413 /* Prevent unused argument(s) compilation warning */
414 UNUSED(hspdif);
415
416 /* NOTE : This function Should not be modified, when the callback is needed,
417 the HAL_SPDIFRX_MspDeInit could be implemented in the user file
418 */
419 }
420
421 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
422 /**
423 * @brief Register a User SPDIFRX Callback
424 * To be used instead of the weak predefined callback
425 * @param hspdif SPDIFRX handle
426 * @param CallbackID ID of the callback to be registered
427 * This parameter can be one of the following values:
428 * @arg @ref HAL_SPDIFRX_RX_HALF_CB_ID SPDIFRX Data flow half completed callback ID
429 * @arg @ref HAL_SPDIFRX_RX_CPLT_CB_ID SPDIFRX Data flow completed callback ID
430 * @arg @ref HAL_SPDIFRX_CX_HALF_CB_ID SPDIFRX Control flow half completed callback ID
431 * @arg @ref HAL_SPDIFRX_CX_CPLT_CB_ID SPDIFRX Control flow completed callback ID
432 * @arg @ref HAL_SPDIFRX_ERROR_CB_ID SPDIFRX error callback ID
433 * @arg @ref HAL_SPDIFRX_MSPINIT_CB_ID MspInit callback ID
434 * @arg @ref HAL_SPDIFRX_MSPDEINIT_CB_ID MspDeInit callback ID
435 * @param pCallback pointer to the Callback function
436 * @retval HAL status
437 */
HAL_SPDIFRX_RegisterCallback(SPDIFRX_HandleTypeDef * hspdif,HAL_SPDIFRX_CallbackIDTypeDef CallbackID,pSPDIFRX_CallbackTypeDef pCallback)438 HAL_StatusTypeDef HAL_SPDIFRX_RegisterCallback(SPDIFRX_HandleTypeDef *hspdif, HAL_SPDIFRX_CallbackIDTypeDef CallbackID,
439 pSPDIFRX_CallbackTypeDef pCallback)
440 {
441 HAL_StatusTypeDef status = HAL_OK;
442
443 if (pCallback == NULL)
444 {
445 /* Update the error code */
446 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
447 return HAL_ERROR;
448 }
449 /* Process locked */
450 __HAL_LOCK(hspdif);
451
452 if (HAL_SPDIFRX_STATE_READY == hspdif->State)
453 {
454 switch (CallbackID)
455 {
456 case HAL_SPDIFRX_RX_HALF_CB_ID :
457 hspdif->RxHalfCpltCallback = pCallback;
458 break;
459
460 case HAL_SPDIFRX_RX_CPLT_CB_ID :
461 hspdif->RxCpltCallback = pCallback;
462 break;
463
464 case HAL_SPDIFRX_CX_HALF_CB_ID :
465 hspdif->CxHalfCpltCallback = pCallback;
466 break;
467
468 case HAL_SPDIFRX_CX_CPLT_CB_ID :
469 hspdif->CxCpltCallback = pCallback;
470 break;
471
472 case HAL_SPDIFRX_ERROR_CB_ID :
473 hspdif->ErrorCallback = pCallback;
474 break;
475
476 case HAL_SPDIFRX_MSPINIT_CB_ID :
477 hspdif->MspInitCallback = pCallback;
478 break;
479
480 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
481 hspdif->MspDeInitCallback = pCallback;
482 break;
483
484 default :
485 /* Update the error code */
486 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
487 /* Return error status */
488 status = HAL_ERROR;
489 break;
490 }
491 }
492 else if (HAL_SPDIFRX_STATE_RESET == hspdif->State)
493 {
494 switch (CallbackID)
495 {
496 case HAL_SPDIFRX_MSPINIT_CB_ID :
497 hspdif->MspInitCallback = pCallback;
498 break;
499
500 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
501 hspdif->MspDeInitCallback = pCallback;
502 break;
503
504 default :
505 /* Update the error code */
506 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
507 /* Return error status */
508 status = HAL_ERROR;
509 break;
510 }
511 }
512 else
513 {
514 /* Update the error code */
515 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
516 /* Return error status */
517 status = HAL_ERROR;
518 }
519
520 /* Release Lock */
521 __HAL_UNLOCK(hspdif);
522 return status;
523 }
524
525 /**
526 * @brief Unregister a SPDIFRX Callback
527 * SPDIFRX callback is redirected to the weak predefined callback
528 * @param hspdif SPDIFRX handle
529 * @param CallbackID ID of the callback to be unregistered
530 * This parameter can be one of the following values:
531 * @arg @ref HAL_SPDIFRX_RX_HALF_CB_ID SPDIFRX Data flow half completed callback ID
532 * @arg @ref HAL_SPDIFRX_RX_CPLT_CB_ID SPDIFRX Data flow completed callback ID
533 * @arg @ref HAL_SPDIFRX_CX_HALF_CB_ID SPDIFRX Control flow half completed callback ID
534 * @arg @ref HAL_SPDIFRX_CX_CPLT_CB_ID SPDIFRX Control flow completed callback ID
535 * @arg @ref HAL_SPDIFRX_ERROR_CB_ID SPDIFRX error callback ID
536 * @arg @ref HAL_SPDIFRX_MSPINIT_CB_ID MspInit callback ID
537 * @arg @ref HAL_SPDIFRX_MSPDEINIT_CB_ID MspDeInit callback ID
538 * @retval HAL status
539 */
HAL_SPDIFRX_UnRegisterCallback(SPDIFRX_HandleTypeDef * hspdif,HAL_SPDIFRX_CallbackIDTypeDef CallbackID)540 HAL_StatusTypeDef HAL_SPDIFRX_UnRegisterCallback(SPDIFRX_HandleTypeDef *hspdif,
541 HAL_SPDIFRX_CallbackIDTypeDef CallbackID)
542 {
543 HAL_StatusTypeDef status = HAL_OK;
544
545 /* Process locked */
546 __HAL_LOCK(hspdif);
547
548 if (HAL_SPDIFRX_STATE_READY == hspdif->State)
549 {
550 switch (CallbackID)
551 {
552 case HAL_SPDIFRX_RX_HALF_CB_ID :
553 hspdif->RxHalfCpltCallback = HAL_SPDIFRX_RxHalfCpltCallback;
554 break;
555
556 case HAL_SPDIFRX_RX_CPLT_CB_ID :
557 hspdif->RxCpltCallback = HAL_SPDIFRX_RxCpltCallback;
558 break;
559
560 case HAL_SPDIFRX_CX_HALF_CB_ID :
561 hspdif->CxHalfCpltCallback = HAL_SPDIFRX_CxHalfCpltCallback;
562 break;
563
564 case HAL_SPDIFRX_CX_CPLT_CB_ID :
565 hspdif->CxCpltCallback = HAL_SPDIFRX_CxCpltCallback;
566 break;
567
568 case HAL_SPDIFRX_ERROR_CB_ID :
569 hspdif->ErrorCallback = HAL_SPDIFRX_ErrorCallback;
570 break;
571
572 default :
573 /* Update the error code */
574 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
575 /* Return error status */
576 status = HAL_ERROR;
577 break;
578 }
579 }
580 else if (HAL_SPDIFRX_STATE_RESET == hspdif->State)
581 {
582 switch (CallbackID)
583 {
584 case HAL_SPDIFRX_MSPINIT_CB_ID :
585 hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit */
586 break;
587
588 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
589 hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspInit */
590 break;
591
592 default :
593 /* Update the error code */
594 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
595 /* Return error status */
596 status = HAL_ERROR;
597 break;
598 }
599 }
600 else
601 {
602 /* Update the error code */
603 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
604 /* Return error status */
605 status = HAL_ERROR;
606 }
607
608 /* Release Lock */
609 __HAL_UNLOCK(hspdif);
610 return status;
611 }
612
613 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
614
615 /**
616 * @brief Set the SPDIFRX data format according to the specified parameters in the SPDIFRX_InitTypeDef.
617 * @param hspdif SPDIFRX handle
618 * @param sDataFormat SPDIFRX data format
619 * @retval HAL status
620 */
HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef * hspdif,SPDIFRX_SetDataFormatTypeDef sDataFormat)621 HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef sDataFormat)
622 {
623 uint32_t tmpreg;
624
625 /* Check the SPDIFRX handle allocation */
626 if (hspdif == NULL)
627 {
628 return HAL_ERROR;
629 }
630
631 /* Check the SPDIFRX parameters */
632 assert_param(IS_STEREO_MODE(sDataFormat.StereoMode));
633 assert_param(IS_SPDIFRX_DATA_FORMAT(sDataFormat.DataFormat));
634 assert_param(IS_PREAMBLE_TYPE_MASK(sDataFormat.PreambleTypeMask));
635 assert_param(IS_CHANNEL_STATUS_MASK(sDataFormat.ChannelStatusMask));
636 assert_param(IS_VALIDITY_MASK(sDataFormat.ValidityBitMask));
637 assert_param(IS_PARITY_ERROR_MASK(sDataFormat.ParityErrorMask));
638
639 /* Reset the old SPDIFRX CR configuration */
640 tmpreg = hspdif->Instance->CR;
641
642 if (((tmpreg & SPDIFRX_STATE_RCV) == SPDIFRX_STATE_RCV) &&
643 (((tmpreg & SPDIFRX_CR_DRFMT) != sDataFormat.DataFormat) ||
644 ((tmpreg & SPDIFRX_CR_RXSTEO) != sDataFormat.StereoMode)))
645 {
646 return HAL_ERROR;
647 }
648
649 tmpreg &= ~(SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
650 SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK);
651
652 /* Configure the new data format */
653 tmpreg |= (sDataFormat.StereoMode |
654 sDataFormat.DataFormat |
655 sDataFormat.PreambleTypeMask |
656 sDataFormat.ChannelStatusMask |
657 sDataFormat.ValidityBitMask |
658 sDataFormat.ParityErrorMask);
659
660 hspdif->Instance->CR = tmpreg;
661
662 return HAL_OK;
663 }
664
665 /**
666 * @}
667 */
668
669 /** @defgroup SPDIFRX_Exported_Functions_Group2 IO operation functions
670 * @brief Data transfers functions
671 *
672 @verbatim
673 ===============================================================================
674 ##### IO operation functions #####
675 ===============================================================================
676 [..]
677 This subsection provides a set of functions allowing to manage the SPDIFRX data
678 transfers.
679
680 (#) There is two mode of transfer:
681 (++) Blocking mode : The communication is performed in the polling mode.
682 The status of all data processing is returned by the same function
683 after finishing transfer.
684 (++) No-Blocking mode : The communication is performed using Interrupts
685 or DMA. These functions return the status of the transfer start-up.
686 The end of the data processing will be indicated through the
687 dedicated SPDIFRX IRQ when using Interrupt mode or the DMA IRQ when
688 using DMA mode.
689
690 (#) Blocking mode functions are :
691 (++) HAL_SPDIFRX_ReceiveDataFlow()
692 (++) HAL_SPDIFRX_ReceiveCtrlFlow()
693 (+@) Do not use blocking mode to receive both control and data flow at the same time.
694
695 (#) No-Blocking mode functions with Interrupt are :
696 (++) HAL_SPDIFRX_ReceiveCtrlFlow_IT()
697 (++) HAL_SPDIFRX_ReceiveDataFlow_IT()
698
699 (#) No-Blocking mode functions with DMA are :
700 (++) HAL_SPDIFRX_ReceiveCtrlFlow_DMA()
701 (++) HAL_SPDIFRX_ReceiveDataFlow_DMA()
702
703 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
704 (++) HAL_SPDIFRX_RxCpltCallback()
705 (++) HAL_SPDIFRX_CxCpltCallback()
706
707 @endverbatim
708 * @{
709 */
710
711 /**
712 * @brief Receives an amount of data (Data Flow) in blocking mode.
713 * @param hspdif pointer to SPDIFRX_HandleTypeDef structure that contains
714 * the configuration information for SPDIFRX module.
715 * @param pData Pointer to data buffer
716 * @param Size Amount of data to be received
717 * @param Timeout Timeout duration
718 * @retval HAL status
719 */
HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size,uint32_t Timeout)720 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size,
721 uint32_t Timeout)
722 {
723 uint32_t tickstart;
724 uint16_t sizeCounter = Size;
725 uint32_t *pTmpBuf = pData;
726
727 if ((pData == NULL) || (Size == 0U))
728 {
729 return HAL_ERROR;
730 }
731
732 if (hspdif->State == HAL_SPDIFRX_STATE_READY)
733 {
734 /* Process Locked */
735 __HAL_LOCK(hspdif);
736
737 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
738
739 /* Start synchronisation */
740 __HAL_SPDIFRX_SYNC(hspdif);
741
742 /* Get tick */
743 tickstart = HAL_GetTick();
744
745 /* Wait until SYNCD flag is set */
746 if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
747 {
748 return HAL_TIMEOUT;
749 }
750
751 /* Start reception */
752 __HAL_SPDIFRX_RCV(hspdif);
753
754 /* Receive data flow */
755 while (sizeCounter > 0U)
756 {
757 /* Get tick */
758 tickstart = HAL_GetTick();
759
760 /* Wait until RXNE flag is set */
761 if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
762 {
763 return HAL_TIMEOUT;
764 }
765
766 (*pTmpBuf) = hspdif->Instance->DR;
767 pTmpBuf++;
768 sizeCounter--;
769 }
770
771 /* SPDIFRX ready */
772 hspdif->State = HAL_SPDIFRX_STATE_READY;
773
774 /* Process Unlocked */
775 __HAL_UNLOCK(hspdif);
776
777 return HAL_OK;
778 }
779 else
780 {
781 return HAL_BUSY;
782 }
783 }
784
785 /**
786 * @brief Receives an amount of data (Control Flow) in blocking mode.
787 * @param hspdif pointer to a SPDIFRX_HandleTypeDef structure that contains
788 * the configuration information for SPDIFRX module.
789 * @param pData Pointer to data buffer
790 * @param Size Amount of data to be received
791 * @param Timeout Timeout duration
792 * @retval HAL status
793 */
HAL_SPDIFRX_ReceiveCtrlFlow(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size,uint32_t Timeout)794 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size,
795 uint32_t Timeout)
796 {
797 uint32_t tickstart;
798 uint16_t sizeCounter = Size;
799 uint32_t *pTmpBuf = pData;
800
801 if ((pData == NULL) || (Size == 0U))
802 {
803 return HAL_ERROR;
804 }
805
806 if (hspdif->State == HAL_SPDIFRX_STATE_READY)
807 {
808 /* Process Locked */
809 __HAL_LOCK(hspdif);
810
811 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
812
813 /* Start synchronization */
814 __HAL_SPDIFRX_SYNC(hspdif);
815
816 /* Get tick */
817 tickstart = HAL_GetTick();
818
819 /* Wait until SYNCD flag is set */
820 if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
821 {
822 return HAL_TIMEOUT;
823 }
824
825 /* Start reception */
826 __HAL_SPDIFRX_RCV(hspdif);
827
828 /* Receive control flow */
829 while (sizeCounter > 0U)
830 {
831 /* Get tick */
832 tickstart = HAL_GetTick();
833
834 /* Wait until CSRNE flag is set */
835 if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_CSRNE, RESET, Timeout, tickstart) != HAL_OK)
836 {
837 return HAL_TIMEOUT;
838 }
839
840 (*pTmpBuf) = hspdif->Instance->CSR;
841 pTmpBuf++;
842 sizeCounter--;
843 }
844
845 /* SPDIFRX ready */
846 hspdif->State = HAL_SPDIFRX_STATE_READY;
847
848 /* Process Unlocked */
849 __HAL_UNLOCK(hspdif);
850
851 return HAL_OK;
852 }
853 else
854 {
855 return HAL_BUSY;
856 }
857 }
858
859 /**
860 * @brief Receive an amount of data (Data Flow) in non-blocking mode with Interrupt
861 * @param hspdif SPDIFRX handle
862 * @param pData a 32-bit pointer to the Receive data buffer.
863 * @param Size number of data sample to be received .
864 * @retval HAL status
865 */
HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)866 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
867 {
868 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
869
870 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
871
872 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
873 {
874 if ((pData == NULL) || (Size == 0U))
875 {
876 return HAL_ERROR;
877 }
878
879 /* Process Locked */
880 __HAL_LOCK(hspdif);
881
882 hspdif->pRxBuffPtr = pData;
883 hspdif->RxXferSize = Size;
884 hspdif->RxXferCount = Size;
885
886 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
887
888 /* Check if a receive process is ongoing or not */
889 hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
890
891 /* Enable the SPDIFRX PE Error Interrupt */
892 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
893
894 /* Enable the SPDIFRX OVR Error Interrupt */
895 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
896
897 /* Enable the SPDIFRX RXNE interrupt */
898 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_RXNE);
899
900 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFRXEN) != SPDIFRX_STATE_RCV)
901 {
902 /* Start synchronization */
903 __HAL_SPDIFRX_SYNC(hspdif);
904
905 /* Wait until SYNCD flag is set */
906 do
907 {
908 if (count == 0U)
909 {
910 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
911 process */
912 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
913 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
914 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
915 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
916 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
917 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
918 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
919
920 hspdif->State = HAL_SPDIFRX_STATE_READY;
921
922 /* Process Unlocked */
923 __HAL_UNLOCK(hspdif);
924
925 return HAL_TIMEOUT;
926 }
927 count--;
928 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
929
930 /* Start reception */
931 __HAL_SPDIFRX_RCV(hspdif);
932 }
933
934 /* Process Unlocked */
935 __HAL_UNLOCK(hspdif);
936
937 return HAL_OK;
938 }
939 else
940 {
941 return HAL_BUSY;
942 }
943 }
944
945 /**
946 * @brief Receive an amount of data (Control Flow) with Interrupt
947 * @param hspdif SPDIFRX handle
948 * @param pData a 32-bit pointer to the Receive data buffer.
949 * @param Size number of data sample (Control Flow) to be received
950 * @retval HAL status
951 */
HAL_SPDIFRX_ReceiveCtrlFlow_IT(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)952 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
953 {
954 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
955
956 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
957
958 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
959 {
960 if ((pData == NULL) || (Size == 0U))
961 {
962 return HAL_ERROR;
963 }
964
965 /* Process Locked */
966 __HAL_LOCK(hspdif);
967
968 hspdif->pCsBuffPtr = pData;
969 hspdif->CsXferSize = Size;
970 hspdif->CsXferCount = Size;
971
972 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
973
974 /* Check if a receive process is ongoing or not */
975 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
976
977 /* Enable the SPDIFRX PE Error Interrupt */
978 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
979
980 /* Enable the SPDIFRX OVR Error Interrupt */
981 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
982
983 /* Enable the SPDIFRX CSRNE interrupt */
984 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
985
986 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFRXEN) != SPDIFRX_STATE_RCV)
987 {
988 /* Start synchronization */
989 __HAL_SPDIFRX_SYNC(hspdif);
990
991 /* Wait until SYNCD flag is set */
992 do
993 {
994 if (count == 0U)
995 {
996 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
997 process */
998 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
999 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1000 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1001 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1002 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1003 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1004 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1005
1006 hspdif->State = HAL_SPDIFRX_STATE_READY;
1007
1008 /* Process Unlocked */
1009 __HAL_UNLOCK(hspdif);
1010
1011 return HAL_TIMEOUT;
1012 }
1013 count--;
1014 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1015
1016 /* Start reception */
1017 __HAL_SPDIFRX_RCV(hspdif);
1018 }
1019
1020 /* Process Unlocked */
1021 __HAL_UNLOCK(hspdif);
1022
1023 return HAL_OK;
1024 }
1025 else
1026 {
1027 return HAL_BUSY;
1028 }
1029 }
1030
1031 /**
1032 * @brief Receive an amount of data (Data Flow) mode with DMA
1033 * @param hspdif SPDIFRX handle
1034 * @param pData a 32-bit pointer to the Receive data buffer.
1035 * @param Size number of data sample to be received
1036 * @retval HAL status
1037 */
HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)1038 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1039 {
1040 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1041
1042 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1043
1044 if ((pData == NULL) || (Size == 0U))
1045 {
1046 return HAL_ERROR;
1047 }
1048
1049 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
1050 {
1051 /* Process Locked */
1052 __HAL_LOCK(hspdif);
1053
1054 hspdif->pRxBuffPtr = pData;
1055 hspdif->RxXferSize = Size;
1056 hspdif->RxXferCount = Size;
1057
1058 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1059 hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
1060
1061 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1062 hspdif->hdmaDrRx->XferHalfCpltCallback = SPDIFRX_DMARxHalfCplt;
1063
1064 /* Set the SPDIFRX Rx DMA transfer complete callback */
1065 hspdif->hdmaDrRx->XferCpltCallback = SPDIFRX_DMARxCplt;
1066
1067 /* Set the DMA error callback */
1068 hspdif->hdmaDrRx->XferErrorCallback = SPDIFRX_DMAError;
1069
1070 /* Enable the DMA request */
1071 if ((hspdif->hdmaDrRx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1072 {
1073 if (hspdif->hdmaDrRx->LinkedListQueue != NULL)
1074 {
1075 hspdif->hdmaDrRx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = (uint32_t) Size * 4U;
1076 hspdif->hdmaDrRx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1077 (uint32_t) &hspdif->Instance->DR;
1078 hspdif->hdmaDrRx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1079 (uint32_t) hspdif->pRxBuffPtr;
1080
1081 if (HAL_DMAEx_List_Start_IT(hspdif->hdmaDrRx) != HAL_OK)
1082 {
1083 /* Set SPDIFRX error */
1084 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1085
1086 /* Set SPDIFRX state */
1087 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1088
1089 /* Process Unlocked */
1090 __HAL_UNLOCK(hspdif);
1091
1092 return HAL_ERROR;
1093 }
1094 }
1095 else
1096 {
1097 /* Set SPDIFRX error */
1098 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1099
1100 /* Set SPDIFRX state */
1101 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1102
1103 /* Process Unlocked */
1104 __HAL_UNLOCK(hspdif);
1105
1106 return HAL_ERROR;
1107 }
1108 }
1109 else
1110 {
1111 if (HAL_DMA_Start_IT(hspdif->hdmaDrRx, (uint32_t)&hspdif->Instance->DR, (uint32_t)hspdif->pRxBuffPtr,
1112 (uint32_t) Size * 4U) != HAL_OK)
1113 {
1114 /* Set SPDIFRX error */
1115 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1116
1117 /* Set SPDIFRX state */
1118 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1119
1120 /* Process Unlocked */
1121 __HAL_UNLOCK(hspdif);
1122
1123 return HAL_ERROR;
1124 }
1125 }
1126
1127 /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/
1128 hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN;
1129
1130 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFRXEN) != SPDIFRX_STATE_RCV)
1131 {
1132 /* Start synchronization */
1133 __HAL_SPDIFRX_SYNC(hspdif);
1134
1135 /* Wait until SYNCD flag is set */
1136 do
1137 {
1138 if (count == 0U)
1139 {
1140 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1141 process */
1142 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1143 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1144 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1145 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1146 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1147 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1148 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1149
1150 hspdif->State = HAL_SPDIFRX_STATE_READY;
1151
1152 /* Process Unlocked */
1153 __HAL_UNLOCK(hspdif);
1154
1155 return HAL_TIMEOUT;
1156 }
1157 count--;
1158 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1159
1160 /* Start reception */
1161 __HAL_SPDIFRX_RCV(hspdif);
1162 }
1163
1164 /* Process Unlocked */
1165 __HAL_UNLOCK(hspdif);
1166
1167 return HAL_OK;
1168 }
1169 else
1170 {
1171 return HAL_BUSY;
1172 }
1173 }
1174
1175 /**
1176 * @brief Receive an amount of data (Control Flow) with DMA
1177 * @param hspdif SPDIFRX handle
1178 * @param pData a 32-bit pointer to the Receive data buffer.
1179 * @param Size number of data (Control Flow) sample to be received
1180 * @retval HAL status
1181 */
HAL_SPDIFRX_ReceiveCtrlFlow_DMA(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)1182 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1183 {
1184 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1185
1186 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1187
1188 if ((pData == NULL) || (Size == 0U))
1189 {
1190 return HAL_ERROR;
1191 }
1192
1193 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
1194 {
1195 hspdif->pCsBuffPtr = pData;
1196 hspdif->CsXferSize = Size;
1197 hspdif->CsXferCount = Size;
1198
1199 /* Process Locked */
1200 __HAL_LOCK(hspdif);
1201
1202 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1203 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
1204
1205 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1206 hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt;
1207
1208 /* Set the SPDIFRX Rx DMA transfer complete callback */
1209 hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt;
1210
1211 /* Set the DMA error callback */
1212 hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError;
1213
1214 /* Enable the DMA request */
1215 if ((hspdif->hdmaCsRx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1216 {
1217 if (hspdif->hdmaCsRx->LinkedListQueue != NULL)
1218 {
1219 hspdif->hdmaCsRx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = (uint32_t) Size * 4U;
1220 hspdif->hdmaCsRx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1221 (uint32_t) &hspdif->Instance->CSR;
1222 hspdif->hdmaCsRx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1223 (uint32_t) hspdif->pCsBuffPtr;
1224
1225 if (HAL_DMAEx_List_Start_IT(hspdif->hdmaCsRx) != HAL_OK)
1226 {
1227 /* Set SPDIFRX error */
1228 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1229
1230 /* Set SPDIFRX state */
1231 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1232
1233 /* Process Unlocked */
1234 __HAL_UNLOCK(hspdif);
1235
1236 return HAL_ERROR;
1237 }
1238 }
1239 else
1240 {
1241 /* Set SPDIFRX error */
1242 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1243
1244 /* Set SPDIFRX state */
1245 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1246
1247 /* Process Unlocked */
1248 __HAL_UNLOCK(hspdif);
1249
1250 return HAL_ERROR;
1251 }
1252 }
1253 else
1254 {
1255 if (HAL_DMA_Start_IT(hspdif->hdmaCsRx, (uint32_t)&hspdif->Instance->CSR, (uint32_t)hspdif->pCsBuffPtr,
1256 (uint32_t) Size * 4U) != HAL_OK)
1257 {
1258 /* Set SPDIFRX error */
1259 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1260
1261 /* Set SPDIFRX state */
1262 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1263
1264 /* Process Unlocked */
1265 __HAL_UNLOCK(hspdif);
1266
1267 return HAL_ERROR;
1268 }
1269 }
1270
1271 /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/
1272 hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN;
1273
1274 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFRXEN) != SPDIFRX_STATE_RCV)
1275 {
1276 /* Start synchronization */
1277 __HAL_SPDIFRX_SYNC(hspdif);
1278
1279 /* Wait until SYNCD flag is set */
1280 do
1281 {
1282 if (count == 0U)
1283 {
1284 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1285 process */
1286 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1287 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1288 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1289 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1290 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1291 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1292 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1293
1294 hspdif->State = HAL_SPDIFRX_STATE_READY;
1295
1296 /* Process Unlocked */
1297 __HAL_UNLOCK(hspdif);
1298
1299 return HAL_TIMEOUT;
1300 }
1301 count--;
1302 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1303
1304 /* Start reception */
1305 __HAL_SPDIFRX_RCV(hspdif);
1306 }
1307
1308 /* Process Unlocked */
1309 __HAL_UNLOCK(hspdif);
1310
1311 return HAL_OK;
1312 }
1313 else
1314 {
1315 return HAL_BUSY;
1316 }
1317 }
1318
1319 /**
1320 * @brief stop the audio stream receive from the Media.
1321 * @param hspdif SPDIFRX handle
1322 * @retval None
1323 */
HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef * hspdif)1324 HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif)
1325 {
1326 /* Process Locked */
1327 __HAL_LOCK(hspdif);
1328
1329 /* Disable the SPDIFRX DMA requests */
1330 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1331 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1332
1333 /* Disable the SPDIFRX DMA channel */
1334 if (hspdif->hdmaDrRx != NULL)
1335 {
1336 __HAL_DMA_DISABLE(hspdif->hdmaDrRx);
1337 }
1338 if (hspdif->hdmaCsRx != NULL)
1339 {
1340 __HAL_DMA_DISABLE(hspdif->hdmaCsRx);
1341 }
1342
1343 /* Disable SPDIFRX peripheral */
1344 __HAL_SPDIFRX_IDLE(hspdif);
1345
1346 hspdif->State = HAL_SPDIFRX_STATE_READY;
1347
1348 /* Process Unlocked */
1349 __HAL_UNLOCK(hspdif);
1350
1351 return HAL_OK;
1352 }
1353
1354 /**
1355 * @brief This function handles SPDIFRX interrupt request.
1356 * @param hspdif SPDIFRX handle
1357 * @retval HAL status
1358 */
HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef * hspdif)1359 void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif)
1360 {
1361 uint32_t itFlag = hspdif->Instance->SR;
1362 uint32_t itSource = hspdif->Instance->IMR;
1363
1364 /* SPDIFRX in mode Data Flow Reception */
1365 if (((itFlag & SPDIFRX_FLAG_RXNE) == SPDIFRX_FLAG_RXNE) && ((itSource & SPDIFRX_IT_RXNE) == SPDIFRX_IT_RXNE))
1366 {
1367 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE);
1368 SPDIFRX_ReceiveDataFlow_IT(hspdif);
1369 }
1370
1371 /* SPDIFRX in mode Control Flow Reception */
1372 if (((itFlag & SPDIFRX_FLAG_CSRNE) == SPDIFRX_FLAG_CSRNE) && ((itSource & SPDIFRX_IT_CSRNE) == SPDIFRX_IT_CSRNE))
1373 {
1374 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE);
1375 SPDIFRX_ReceiveControlFlow_IT(hspdif);
1376 }
1377
1378 /* SPDIFRX Overrun error interrupt occurred */
1379 if (((itFlag & SPDIFRX_FLAG_OVR) == SPDIFRX_FLAG_OVR) && ((itSource & SPDIFRX_IT_OVRIE) == SPDIFRX_IT_OVRIE))
1380 {
1381 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_OVRIE);
1382
1383 /* Change the SPDIFRX error code */
1384 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR;
1385
1386 /* the transfer is not stopped */
1387 HAL_SPDIFRX_ErrorCallback(hspdif);
1388 }
1389
1390 /* SPDIFRX Parity error interrupt occurred */
1391 if (((itFlag & SPDIFRX_FLAG_PERR) == SPDIFRX_FLAG_PERR) && ((itSource & SPDIFRX_IT_PERRIE) == SPDIFRX_IT_PERRIE))
1392 {
1393 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_PERRIE);
1394
1395 /* Change the SPDIFRX error code */
1396 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE;
1397
1398 /* the transfer is not stopped */
1399 HAL_SPDIFRX_ErrorCallback(hspdif);
1400 }
1401 }
1402
1403 /**
1404 * @brief Rx Transfer (Data flow) half completed callbacks
1405 * @param hspdif SPDIFRX handle
1406 * @retval None
1407 */
HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1408 __weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1409 {
1410 /* Prevent unused argument(s) compilation warning */
1411 UNUSED(hspdif);
1412
1413 /* NOTE : This function Should not be modified, when the callback is needed,
1414 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1415 */
1416 }
1417
1418 /**
1419 * @brief Rx Transfer (Data flow) completed callbacks
1420 * @param hspdif SPDIFRX handle
1421 * @retval None
1422 */
HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1423 __weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1424 {
1425 /* Prevent unused argument(s) compilation warning */
1426 UNUSED(hspdif);
1427
1428 /* NOTE : This function Should not be modified, when the callback is needed,
1429 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1430 */
1431 }
1432
1433 /**
1434 * @brief Rx (Control flow) Transfer half completed callbacks
1435 * @param hspdif SPDIFRX handle
1436 * @retval None
1437 */
HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1438 __weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1439 {
1440 /* Prevent unused argument(s) compilation warning */
1441 UNUSED(hspdif);
1442
1443 /* NOTE : This function Should not be modified, when the callback is needed,
1444 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1445 */
1446 }
1447
1448 /**
1449 * @brief Rx Transfer (Control flow) completed callbacks
1450 * @param hspdif SPDIFRX handle
1451 * @retval None
1452 */
HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1453 __weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1454 {
1455 /* Prevent unused argument(s) compilation warning */
1456 UNUSED(hspdif);
1457
1458 /* NOTE : This function Should not be modified, when the callback is needed,
1459 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1460 */
1461 }
1462
1463 /**
1464 * @brief SPDIFRX error callbacks
1465 * @param hspdif SPDIFRX handle
1466 * @retval None
1467 */
HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef * hspdif)1468 __weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif)
1469 {
1470 /* Prevent unused argument(s) compilation warning */
1471 UNUSED(hspdif);
1472
1473 /* NOTE : This function Should not be modified, when the callback is needed,
1474 the HAL_SPDIFRX_ErrorCallback could be implemented in the user file
1475 */
1476 }
1477
1478 /**
1479 * @}
1480 */
1481
1482 /** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions
1483 * @brief Peripheral State functions
1484 *
1485 @verbatim
1486 ===============================================================================
1487 ##### Peripheral State and Errors functions #####
1488 ===============================================================================
1489 [..]
1490 This subsection permit to get in run-time the status of the peripheral
1491 and the data flow.
1492
1493 @endverbatim
1494 * @{
1495 */
1496
1497 /**
1498 * @brief Return the SPDIFRX state
1499 * @param hspdif SPDIFRX handle
1500 * @retval HAL state
1501 */
HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const * const hspdif)1502 HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const *const hspdif)
1503 {
1504 return hspdif->State;
1505 }
1506
1507 /**
1508 * @brief Return the SPDIFRX error code
1509 * @param hspdif SPDIFRX handle
1510 * @retval SPDIFRX Error Code
1511 */
HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const * const hspdif)1512 uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const *const hspdif)
1513 {
1514 return hspdif->ErrorCode;
1515 }
1516
1517 /**
1518 * @}
1519 */
1520
1521 /**
1522 * @brief DMA SPDIFRX receive process (Data flow) complete callback
1523 * @param hdma DMA handle
1524 * @retval None
1525 */
SPDIFRX_DMARxCplt(DMA_HandleTypeDef * hdma)1526 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma)
1527 {
1528 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1529
1530 /* Disable Rx DMA Request */
1531 if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
1532 {
1533 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1534 hspdif->RxXferCount = 0;
1535 hspdif->State = HAL_SPDIFRX_STATE_READY;
1536 }
1537 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1538 hspdif->RxCpltCallback(hspdif);
1539 #else
1540 HAL_SPDIFRX_RxCpltCallback(hspdif);
1541 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1542 }
1543
1544 /**
1545 * @brief DMA SPDIFRX receive process (Data flow) half complete callback
1546 * @param hdma DMA handle
1547 * @retval None
1548 */
SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1549 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1550 {
1551 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1552
1553 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1554 hspdif->RxHalfCpltCallback(hspdif);
1555 #else
1556 HAL_SPDIFRX_RxHalfCpltCallback(hspdif);
1557 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1558 }
1559
1560
1561 /**
1562 * @brief DMA SPDIFRX receive process (Control flow) complete callback
1563 * @param hdma DMA handle
1564 * @retval None
1565 */
SPDIFRX_DMACxCplt(DMA_HandleTypeDef * hdma)1566 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma)
1567 {
1568 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1569
1570 /* Disable Cb DMA Request */
1571 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1572 hspdif->CsXferCount = 0;
1573
1574 hspdif->State = HAL_SPDIFRX_STATE_READY;
1575 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1576 hspdif->CxCpltCallback(hspdif);
1577 #else
1578 HAL_SPDIFRX_CxCpltCallback(hspdif);
1579 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1580 }
1581
1582 /**
1583 * @brief DMA SPDIFRX receive process (Control flow) half complete callback
1584 * @param hdma DMA handle
1585 * @retval None
1586 */
SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef * hdma)1587 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma)
1588 {
1589 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1590
1591 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1592 hspdif->CxHalfCpltCallback(hspdif);
1593 #else
1594 HAL_SPDIFRX_CxHalfCpltCallback(hspdif);
1595 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1596 }
1597
1598 /**
1599 * @brief DMA SPDIFRX communication error callback
1600 * @param hdma DMA handle
1601 * @retval None
1602 */
SPDIFRX_DMAError(DMA_HandleTypeDef * hdma)1603 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma)
1604 {
1605 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1606
1607 /* Disable Rx and Cb DMA Request */
1608 hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN));
1609 hspdif->RxXferCount = 0;
1610
1611 hspdif->State = HAL_SPDIFRX_STATE_READY;
1612
1613 /* Set the error code and execute error callback*/
1614 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA;
1615
1616 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1617 /* The transfer is not stopped */
1618 hspdif->ErrorCallback(hspdif);
1619 #else
1620 /* The transfer is not stopped */
1621 HAL_SPDIFRX_ErrorCallback(hspdif);
1622 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1623 }
1624
1625 /**
1626 * @brief Receive an amount of data (Data Flow) with Interrupt
1627 * @param hspdif SPDIFRX handle
1628 * @retval None
1629 */
SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef * hspdif)1630 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1631 {
1632 /* Receive data */
1633 (*hspdif->pRxBuffPtr) = hspdif->Instance->DR;
1634 hspdif->pRxBuffPtr++;
1635 hspdif->RxXferCount--;
1636
1637 if (hspdif->RxXferCount == 0U)
1638 {
1639 /* Disable RXNE/PE and OVR interrupts */
1640 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE);
1641
1642 hspdif->State = HAL_SPDIFRX_STATE_READY;
1643
1644 /* Process Unlocked */
1645 __HAL_UNLOCK(hspdif);
1646
1647 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1648 hspdif->RxCpltCallback(hspdif);
1649 #else
1650 HAL_SPDIFRX_RxCpltCallback(hspdif);
1651 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1652 }
1653 }
1654
1655 /**
1656 * @brief Receive an amount of data (Control Flow) with Interrupt
1657 * @param hspdif SPDIFRX handle
1658 * @retval None
1659 */
SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef * hspdif)1660 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1661 {
1662 /* Receive data */
1663 (*hspdif->pCsBuffPtr) = hspdif->Instance->CSR;
1664 hspdif->pCsBuffPtr++;
1665 hspdif->CsXferCount--;
1666
1667 if (hspdif->CsXferCount == 0U)
1668 {
1669 /* Disable CSRNE interrupt */
1670 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1671
1672 hspdif->State = HAL_SPDIFRX_STATE_READY;
1673
1674 /* Process Unlocked */
1675 __HAL_UNLOCK(hspdif);
1676
1677 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1678 hspdif->CxCpltCallback(hspdif);
1679 #else
1680 HAL_SPDIFRX_CxCpltCallback(hspdif);
1681 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1682 }
1683 }
1684
1685 /**
1686 * @brief This function handles SPDIFRX Communication Timeout.
1687 * @param hspdif SPDIFRX handle
1688 * @param Flag Flag checked
1689 * @param Status Value of the flag expected
1690 * @param Timeout Duration of the timeout
1691 * @param tickstart Tick start value
1692 * @retval HAL status
1693 */
SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef * hspdif,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t tickstart)1694 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag,
1695 FlagStatus Status, uint32_t Timeout, uint32_t tickstart)
1696 {
1697 /* Wait until flag is set */
1698 while (__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == Status)
1699 {
1700 /* Check for the Timeout */
1701 if (Timeout != HAL_MAX_DELAY)
1702 {
1703 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1704 {
1705 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1706 process */
1707 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1708 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1709 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1710 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1711 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1712 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1713 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1714
1715 hspdif->State = HAL_SPDIFRX_STATE_READY;
1716
1717 /* Process Unlocked */
1718 __HAL_UNLOCK(hspdif);
1719
1720 return HAL_TIMEOUT;
1721 }
1722 }
1723 }
1724
1725 return HAL_OK;
1726 }
1727
1728 /**
1729 * @}
1730 */
1731
1732
1733 #endif /* SPDIFRX */
1734 #endif /* HAL_SPDIFRX_MODULE_ENABLED */
1735 /**
1736 * @}
1737 */
1738
1739 /**
1740 * @}
1741 */
1742