1 /**
2 ******************************************************************************
3 * @file stm32h7xx_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) 2017 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 "stm32h7xx_hal.h"
163
164 /** @addtogroup STM32H7xx_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_SPDIFEN) != 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_SPDIFEN) != 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 (HAL_DMA_Start_IT(hspdif->hdmaDrRx, (uint32_t)&hspdif->Instance->DR, (uint32_t)hspdif->pRxBuffPtr, Size) !=
1072 HAL_OK)
1073 {
1074 /* Set SPDIFRX error */
1075 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1076
1077 /* Set SPDIFRX state */
1078 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1079
1080 /* Process Unlocked */
1081 __HAL_UNLOCK(hspdif);
1082
1083 return HAL_ERROR;
1084 }
1085
1086 /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/
1087 hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN;
1088
1089 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1090 {
1091 /* Start synchronization */
1092 __HAL_SPDIFRX_SYNC(hspdif);
1093
1094 /* Wait until SYNCD flag is set */
1095 do
1096 {
1097 if (count == 0U)
1098 {
1099 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1100 process */
1101 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1102 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1103 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1104 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1105 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1106 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1107 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1108
1109 hspdif->State = HAL_SPDIFRX_STATE_READY;
1110
1111 /* Process Unlocked */
1112 __HAL_UNLOCK(hspdif);
1113
1114 return HAL_TIMEOUT;
1115 }
1116 count--;
1117 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1118
1119 /* Start reception */
1120 __HAL_SPDIFRX_RCV(hspdif);
1121 }
1122
1123 /* Process Unlocked */
1124 __HAL_UNLOCK(hspdif);
1125
1126 return HAL_OK;
1127 }
1128 else
1129 {
1130 return HAL_BUSY;
1131 }
1132 }
1133
1134 /**
1135 * @brief Receive an amount of data (Control Flow) with DMA
1136 * @param hspdif SPDIFRX handle
1137 * @param pData a 32-bit pointer to the Receive data buffer.
1138 * @param Size number of data (Control Flow) sample to be received
1139 * @retval HAL status
1140 */
HAL_SPDIFRX_ReceiveCtrlFlow_DMA(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)1141 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1142 {
1143 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1144
1145 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1146
1147 if ((pData == NULL) || (Size == 0U))
1148 {
1149 return HAL_ERROR;
1150 }
1151
1152 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
1153 {
1154 hspdif->pCsBuffPtr = pData;
1155 hspdif->CsXferSize = Size;
1156 hspdif->CsXferCount = Size;
1157
1158 /* Process Locked */
1159 __HAL_LOCK(hspdif);
1160
1161 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1162 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
1163
1164 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1165 hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt;
1166
1167 /* Set the SPDIFRX Rx DMA transfer complete callback */
1168 hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt;
1169
1170 /* Set the DMA error callback */
1171 hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError;
1172
1173 /* Enable the DMA request */
1174 if (HAL_DMA_Start_IT(hspdif->hdmaCsRx, (uint32_t)&hspdif->Instance->CSR, (uint32_t)hspdif->pCsBuffPtr, Size) !=
1175 HAL_OK)
1176 {
1177 /* Set SPDIFRX error */
1178 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1179
1180 /* Set SPDIFRX state */
1181 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1182
1183 /* Process Unlocked */
1184 __HAL_UNLOCK(hspdif);
1185
1186 return HAL_ERROR;
1187 }
1188
1189 /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/
1190 hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN;
1191
1192 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1193 {
1194 /* Start synchronization */
1195 __HAL_SPDIFRX_SYNC(hspdif);
1196
1197 /* Wait until SYNCD flag is set */
1198 do
1199 {
1200 if (count == 0U)
1201 {
1202 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1203 process */
1204 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1205 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1206 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1207 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1208 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1209 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1210 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1211
1212 hspdif->State = HAL_SPDIFRX_STATE_READY;
1213
1214 /* Process Unlocked */
1215 __HAL_UNLOCK(hspdif);
1216
1217 return HAL_TIMEOUT;
1218 }
1219 count--;
1220 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1221
1222 /* Start reception */
1223 __HAL_SPDIFRX_RCV(hspdif);
1224 }
1225
1226 /* Process Unlocked */
1227 __HAL_UNLOCK(hspdif);
1228
1229 return HAL_OK;
1230 }
1231 else
1232 {
1233 return HAL_BUSY;
1234 }
1235 }
1236
1237 /**
1238 * @brief stop the audio stream receive from the Media.
1239 * @param hspdif SPDIFRX handle
1240 * @retval None
1241 */
HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef * hspdif)1242 HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif)
1243 {
1244 /* Process Locked */
1245 __HAL_LOCK(hspdif);
1246
1247 /* Disable the SPDIFRX DMA requests */
1248 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1249 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1250
1251 /* Disable the SPDIFRX DMA channel */
1252 if (hspdif->hdmaDrRx != NULL)
1253 {
1254 __HAL_DMA_DISABLE(hspdif->hdmaDrRx);
1255 }
1256 if (hspdif->hdmaCsRx != NULL)
1257 {
1258 __HAL_DMA_DISABLE(hspdif->hdmaCsRx);
1259 }
1260
1261 /* Disable SPDIFRX peripheral */
1262 __HAL_SPDIFRX_IDLE(hspdif);
1263
1264 hspdif->State = HAL_SPDIFRX_STATE_READY;
1265
1266 /* Process Unlocked */
1267 __HAL_UNLOCK(hspdif);
1268
1269 return HAL_OK;
1270 }
1271
1272 /**
1273 * @brief This function handles SPDIFRX interrupt request.
1274 * @param hspdif SPDIFRX handle
1275 * @retval HAL status
1276 */
HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef * hspdif)1277 void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif)
1278 {
1279 uint32_t itFlag = hspdif->Instance->SR;
1280 uint32_t itSource = hspdif->Instance->IMR;
1281
1282 /* SPDIFRX in mode Data Flow Reception */
1283 if (((itFlag & SPDIFRX_FLAG_RXNE) == SPDIFRX_FLAG_RXNE) && ((itSource & SPDIFRX_IT_RXNE) == SPDIFRX_IT_RXNE))
1284 {
1285 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE);
1286 SPDIFRX_ReceiveDataFlow_IT(hspdif);
1287 }
1288
1289 /* SPDIFRX in mode Control Flow Reception */
1290 if (((itFlag & SPDIFRX_FLAG_CSRNE) == SPDIFRX_FLAG_CSRNE) && ((itSource & SPDIFRX_IT_CSRNE) == SPDIFRX_IT_CSRNE))
1291 {
1292 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE);
1293 SPDIFRX_ReceiveControlFlow_IT(hspdif);
1294 }
1295
1296 /* SPDIFRX Overrun error interrupt occurred */
1297 if (((itFlag & SPDIFRX_FLAG_OVR) == SPDIFRX_FLAG_OVR) && ((itSource & SPDIFRX_IT_OVRIE) == SPDIFRX_IT_OVRIE))
1298 {
1299 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_OVRIE);
1300
1301 /* Change the SPDIFRX error code */
1302 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR;
1303
1304 /* the transfer is not stopped */
1305 HAL_SPDIFRX_ErrorCallback(hspdif);
1306 }
1307
1308 /* SPDIFRX Parity error interrupt occurred */
1309 if (((itFlag & SPDIFRX_FLAG_PERR) == SPDIFRX_FLAG_PERR) && ((itSource & SPDIFRX_IT_PERRIE) == SPDIFRX_IT_PERRIE))
1310 {
1311 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_PERRIE);
1312
1313 /* Change the SPDIFRX error code */
1314 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE;
1315
1316 /* the transfer is not stopped */
1317 HAL_SPDIFRX_ErrorCallback(hspdif);
1318 }
1319 }
1320
1321 /**
1322 * @brief Rx Transfer (Data flow) half completed callbacks
1323 * @param hspdif SPDIFRX handle
1324 * @retval None
1325 */
HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1326 __weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1327 {
1328 /* Prevent unused argument(s) compilation warning */
1329 UNUSED(hspdif);
1330
1331 /* NOTE : This function Should not be modified, when the callback is needed,
1332 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1333 */
1334 }
1335
1336 /**
1337 * @brief Rx Transfer (Data flow) completed callbacks
1338 * @param hspdif SPDIFRX handle
1339 * @retval None
1340 */
HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1341 __weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1342 {
1343 /* Prevent unused argument(s) compilation warning */
1344 UNUSED(hspdif);
1345
1346 /* NOTE : This function Should not be modified, when the callback is needed,
1347 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1348 */
1349 }
1350
1351 /**
1352 * @brief Rx (Control flow) Transfer half completed callbacks
1353 * @param hspdif SPDIFRX handle
1354 * @retval None
1355 */
HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1356 __weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1357 {
1358 /* Prevent unused argument(s) compilation warning */
1359 UNUSED(hspdif);
1360
1361 /* NOTE : This function Should not be modified, when the callback is needed,
1362 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1363 */
1364 }
1365
1366 /**
1367 * @brief Rx Transfer (Control flow) completed callbacks
1368 * @param hspdif SPDIFRX handle
1369 * @retval None
1370 */
HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1371 __weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1372 {
1373 /* Prevent unused argument(s) compilation warning */
1374 UNUSED(hspdif);
1375
1376 /* NOTE : This function Should not be modified, when the callback is needed,
1377 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1378 */
1379 }
1380
1381 /**
1382 * @brief SPDIFRX error callbacks
1383 * @param hspdif SPDIFRX handle
1384 * @retval None
1385 */
HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef * hspdif)1386 __weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif)
1387 {
1388 /* Prevent unused argument(s) compilation warning */
1389 UNUSED(hspdif);
1390
1391 /* NOTE : This function Should not be modified, when the callback is needed,
1392 the HAL_SPDIFRX_ErrorCallback could be implemented in the user file
1393 */
1394 }
1395
1396 /**
1397 * @}
1398 */
1399
1400 /** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions
1401 * @brief Peripheral State functions
1402 *
1403 @verbatim
1404 ===============================================================================
1405 ##### Peripheral State and Errors functions #####
1406 ===============================================================================
1407 [..]
1408 This subsection permit to get in run-time the status of the peripheral
1409 and the data flow.
1410
1411 @endverbatim
1412 * @{
1413 */
1414
1415 /**
1416 * @brief Return the SPDIFRX state
1417 * @param hspdif SPDIFRX handle
1418 * @retval HAL state
1419 */
HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const * const hspdif)1420 HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const *const hspdif)
1421 {
1422 return hspdif->State;
1423 }
1424
1425 /**
1426 * @brief Return the SPDIFRX error code
1427 * @param hspdif SPDIFRX handle
1428 * @retval SPDIFRX Error Code
1429 */
HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const * const hspdif)1430 uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const *const hspdif)
1431 {
1432 return hspdif->ErrorCode;
1433 }
1434
1435 /**
1436 * @}
1437 */
1438
1439 /**
1440 * @brief DMA SPDIFRX receive process (Data flow) complete callback
1441 * @param hdma DMA handle
1442 * @retval None
1443 */
SPDIFRX_DMARxCplt(DMA_HandleTypeDef * hdma)1444 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma)
1445 {
1446 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1447
1448 /* Disable Rx DMA Request */
1449 if (hdma->Init.Mode != DMA_CIRCULAR)
1450 {
1451 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1452 hspdif->RxXferCount = 0;
1453 hspdif->State = HAL_SPDIFRX_STATE_READY;
1454 }
1455 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1456 hspdif->RxCpltCallback(hspdif);
1457 #else
1458 HAL_SPDIFRX_RxCpltCallback(hspdif);
1459 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1460 }
1461
1462 /**
1463 * @brief DMA SPDIFRX receive process (Data flow) half complete callback
1464 * @param hdma DMA handle
1465 * @retval None
1466 */
SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1467 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1468 {
1469 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1470
1471 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1472 hspdif->RxHalfCpltCallback(hspdif);
1473 #else
1474 HAL_SPDIFRX_RxHalfCpltCallback(hspdif);
1475 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1476 }
1477
1478
1479 /**
1480 * @brief DMA SPDIFRX receive process (Control flow) complete callback
1481 * @param hdma DMA handle
1482 * @retval None
1483 */
SPDIFRX_DMACxCplt(DMA_HandleTypeDef * hdma)1484 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma)
1485 {
1486 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1487
1488 /* Disable Cb DMA Request */
1489 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1490 hspdif->CsXferCount = 0;
1491
1492 hspdif->State = HAL_SPDIFRX_STATE_READY;
1493 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1494 hspdif->CxCpltCallback(hspdif);
1495 #else
1496 HAL_SPDIFRX_CxCpltCallback(hspdif);
1497 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1498 }
1499
1500 /**
1501 * @brief DMA SPDIFRX receive process (Control flow) half complete callback
1502 * @param hdma DMA handle
1503 * @retval None
1504 */
SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef * hdma)1505 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma)
1506 {
1507 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1508
1509 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1510 hspdif->CxHalfCpltCallback(hspdif);
1511 #else
1512 HAL_SPDIFRX_CxHalfCpltCallback(hspdif);
1513 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1514 }
1515
1516 /**
1517 * @brief DMA SPDIFRX communication error callback
1518 * @param hdma DMA handle
1519 * @retval None
1520 */
SPDIFRX_DMAError(DMA_HandleTypeDef * hdma)1521 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma)
1522 {
1523 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1524
1525 /* Disable Rx and Cb DMA Request */
1526 hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN));
1527 hspdif->RxXferCount = 0;
1528
1529 hspdif->State = HAL_SPDIFRX_STATE_READY;
1530
1531 /* Set the error code and execute error callback*/
1532 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA;
1533
1534 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1535 /* The transfer is not stopped */
1536 hspdif->ErrorCallback(hspdif);
1537 #else
1538 /* The transfer is not stopped */
1539 HAL_SPDIFRX_ErrorCallback(hspdif);
1540 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1541 }
1542
1543 /**
1544 * @brief Receive an amount of data (Data Flow) with Interrupt
1545 * @param hspdif SPDIFRX handle
1546 * @retval None
1547 */
SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef * hspdif)1548 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1549 {
1550 /* Receive data */
1551 (*hspdif->pRxBuffPtr) = hspdif->Instance->DR;
1552 hspdif->pRxBuffPtr++;
1553 hspdif->RxXferCount--;
1554
1555 if (hspdif->RxXferCount == 0U)
1556 {
1557 /* Disable RXNE/PE and OVR interrupts */
1558 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE);
1559
1560 hspdif->State = HAL_SPDIFRX_STATE_READY;
1561
1562 /* Process Unlocked */
1563 __HAL_UNLOCK(hspdif);
1564
1565 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1566 hspdif->RxCpltCallback(hspdif);
1567 #else
1568 HAL_SPDIFRX_RxCpltCallback(hspdif);
1569 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1570 }
1571 }
1572
1573 /**
1574 * @brief Receive an amount of data (Control Flow) with Interrupt
1575 * @param hspdif SPDIFRX handle
1576 * @retval None
1577 */
SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef * hspdif)1578 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1579 {
1580 /* Receive data */
1581 (*hspdif->pCsBuffPtr) = hspdif->Instance->CSR;
1582 hspdif->pCsBuffPtr++;
1583 hspdif->CsXferCount--;
1584
1585 if (hspdif->CsXferCount == 0U)
1586 {
1587 /* Disable CSRNE interrupt */
1588 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1589
1590 hspdif->State = HAL_SPDIFRX_STATE_READY;
1591
1592 /* Process Unlocked */
1593 __HAL_UNLOCK(hspdif);
1594
1595 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1596 hspdif->CxCpltCallback(hspdif);
1597 #else
1598 HAL_SPDIFRX_CxCpltCallback(hspdif);
1599 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1600 }
1601 }
1602
1603 /**
1604 * @brief This function handles SPDIFRX Communication Timeout.
1605 * @param hspdif SPDIFRX handle
1606 * @param Flag Flag checked
1607 * @param Status Value of the flag expected
1608 * @param Timeout Duration of the timeout
1609 * @param tickstart Tick start value
1610 * @retval HAL status
1611 */
SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef * hspdif,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t tickstart)1612 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag,
1613 FlagStatus Status, uint32_t Timeout, uint32_t tickstart)
1614 {
1615 /* Wait until flag is set */
1616 while (__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == Status)
1617 {
1618 /* Check for the Timeout */
1619 if (Timeout != HAL_MAX_DELAY)
1620 {
1621 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1622 {
1623 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1624 process */
1625 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1626 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1627 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1628 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1629 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1630 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1631 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1632
1633 hspdif->State = HAL_SPDIFRX_STATE_READY;
1634
1635 /* Process Unlocked */
1636 __HAL_UNLOCK(hspdif);
1637
1638 return HAL_TIMEOUT;
1639 }
1640 }
1641 }
1642
1643 return HAL_OK;
1644 }
1645
1646 /**
1647 * @}
1648 */
1649
1650
1651 #endif /* SPDIFRX */
1652 #endif /* HAL_SPDIFRX_MODULE_ENABLED */
1653 /**
1654 * @}
1655 */
1656
1657 /**
1658 * @}
1659 */
1660