Merge maintenance-8.x.x fixes into master
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_spdifrx.c
blobbf61ef937a0147b4842fca256ee9984685eb7718
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
12 ******************************************************************************
13 * @attention
15 * Copyright (c) 2017 STMicroelectronics.
16 * All rights reserved.
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.
22 ******************************************************************************
23 @verbatim
24 ===============================================================================
25 ##### How to use this driver #####
26 ===============================================================================
27 [..]
28 The SPDIFRX HAL driver can be used as follow:
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.
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.
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.
58 (#) Three operation modes are available within this driver :
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()
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
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()
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.
102 [..]
103 (@) You can refer to the SPDIFRX HAL driver header file for more useful macros
105 *** Callback registration ***
106 =============================================
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.
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.
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.
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)
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.
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.
158 @endverbatim
161 /* Includes ------------------------------------------------------------------*/
162 #include "stm32h7xx_hal.h"
164 /** @addtogroup STM32H7xx_HAL_Driver
165 * @{
168 /** @defgroup SPDIFRX SPDIFRX
169 * @brief SPDIFRX HAL module driver
170 * @{
173 #ifdef HAL_SPDIFRX_MODULE_ENABLED
174 #if defined (SPDIFRX)
176 /* Private typedef -----------------------------------------------------------*/
177 /* Private define ------------------------------------------------------------*/
178 /** @defgroup SPDIFRX_Private_Defines SPDIFRX Private Defines
179 * @{
181 #define SPDIFRX_TIMEOUT_VALUE 10U
183 * @}
185 /* Private macro -------------------------------------------------------------*/
186 /* Private variables ---------------------------------------------------------*/
187 /* Private function prototypes -----------------------------------------------*/
188 /** @addtogroup SPDIFRX_Private_Functions
189 * @{
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);
201 * @}
203 /* Exported functions ---------------------------------------------------------*/
205 /** @defgroup SPDIFRX_Exported_Functions SPDIFRX Exported Functions
206 * @{
209 /** @defgroup SPDIFRX_Exported_Functions_Group1 Initialization and de-initialization functions
210 * @brief Initialization and Configuration functions
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:
219 (+) User must Implement HAL_SPDIFRX_MspInit() function in which he configures
220 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
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,...)
232 (+) Call the function HAL_SPDIFRX_DeInit() to restore the default configuration
233 of the selected SPDIFRXx peripheral.
234 @endverbatim
235 * @{
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
244 HAL_StatusTypeDef HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef *hspdif)
246 uint32_t tmpreg;
248 /* Check the SPDIFRX handle allocation */
249 if (hspdif == NULL)
251 return HAL_ERROR;
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));
268 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
269 if (hspdif->State == HAL_SPDIFRX_STATE_RESET)
271 /* Allocate lock resource and initialize it */
272 hspdif->Lock = HAL_UNLOCKED;
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 */
280 if (hspdif->MspInitCallback == NULL)
282 hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit */
285 /* Init the low level hardware */
286 hspdif->MspInitCallback(hspdif);
288 #else
289 if (hspdif->State == HAL_SPDIFRX_STATE_RESET)
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);
296 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
298 /* SPDIFRX peripheral state is BUSY */
299 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
301 /* Disable SPDIFRX interface (IDLE State) */
302 __HAL_SPDIFRX_IDLE(hspdif);
304 /* Reset the old SPDIFRX CR configuration */
305 tmpreg = hspdif->Instance->CR;
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);
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
326 if (hspdif->Init.SymbolClockGen == ENABLE)
328 tmpreg |= SPDIFRX_CR_CKSEN;
331 if (hspdif->Init.BackupSymbolClockGen == ENABLE)
333 tmpreg |= SPDIFRX_CR_CKSBKPEN;
336 hspdif->Instance->CR = tmpreg;
338 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
340 /* SPDIFRX peripheral state is READY*/
341 hspdif->State = HAL_SPDIFRX_STATE_READY;
343 return HAL_OK;
347 * @brief DeInitializes the SPDIFRX peripheral
348 * @param hspdif SPDIFRX handle
349 * @retval HAL status
351 HAL_StatusTypeDef HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef *hspdif)
353 /* Check the SPDIFRX handle allocation */
354 if (hspdif == NULL)
356 return HAL_ERROR;
359 /* Check the parameters */
360 assert_param(IS_SPDIFRX_ALL_INSTANCE(hspdif->Instance));
362 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
364 /* Disable SPDIFRX interface (IDLE state) */
365 __HAL_SPDIFRX_IDLE(hspdif);
367 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
368 if (hspdif->MspDeInitCallback == NULL)
370 hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspDeInit */
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 */
380 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
382 /* SPDIFRX peripheral state is RESET*/
383 hspdif->State = HAL_SPDIFRX_STATE_RESET;
385 /* Release Lock */
386 __HAL_UNLOCK(hspdif);
388 return HAL_OK;
392 * @brief SPDIFRX MSP Init
393 * @param hspdif SPDIFRX handle
394 * @retval None
396 __weak void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif)
398 /* Prevent unused argument(s) compilation warning */
399 UNUSED(hspdif);
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
407 * @brief SPDIFRX MSP DeInit
408 * @param hspdif SPDIFRX handle
409 * @retval None
411 __weak void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif)
413 /* Prevent unused argument(s) compilation warning */
414 UNUSED(hspdif);
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
421 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
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
438 HAL_StatusTypeDef HAL_SPDIFRX_RegisterCallback(SPDIFRX_HandleTypeDef *hspdif, HAL_SPDIFRX_CallbackIDTypeDef CallbackID,
439 pSPDIFRX_CallbackTypeDef pCallback)
441 HAL_StatusTypeDef status = HAL_OK;
443 if (pCallback == NULL)
445 /* Update the error code */
446 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
447 return HAL_ERROR;
449 /* Process locked */
450 __HAL_LOCK(hspdif);
452 if (HAL_SPDIFRX_STATE_READY == hspdif->State)
454 switch (CallbackID)
456 case HAL_SPDIFRX_RX_HALF_CB_ID :
457 hspdif->RxHalfCpltCallback = pCallback;
458 break;
460 case HAL_SPDIFRX_RX_CPLT_CB_ID :
461 hspdif->RxCpltCallback = pCallback;
462 break;
464 case HAL_SPDIFRX_CX_HALF_CB_ID :
465 hspdif->CxHalfCpltCallback = pCallback;
466 break;
468 case HAL_SPDIFRX_CX_CPLT_CB_ID :
469 hspdif->CxCpltCallback = pCallback;
470 break;
472 case HAL_SPDIFRX_ERROR_CB_ID :
473 hspdif->ErrorCallback = pCallback;
474 break;
476 case HAL_SPDIFRX_MSPINIT_CB_ID :
477 hspdif->MspInitCallback = pCallback;
478 break;
480 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
481 hspdif->MspDeInitCallback = pCallback;
482 break;
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;
492 else if (HAL_SPDIFRX_STATE_RESET == hspdif->State)
494 switch (CallbackID)
496 case HAL_SPDIFRX_MSPINIT_CB_ID :
497 hspdif->MspInitCallback = pCallback;
498 break;
500 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
501 hspdif->MspDeInitCallback = pCallback;
502 break;
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;
512 else
514 /* Update the error code */
515 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
516 /* Return error status */
517 status = HAL_ERROR;
520 /* Release Lock */
521 __HAL_UNLOCK(hspdif);
522 return status;
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
540 HAL_StatusTypeDef HAL_SPDIFRX_UnRegisterCallback(SPDIFRX_HandleTypeDef *hspdif,
541 HAL_SPDIFRX_CallbackIDTypeDef CallbackID)
543 HAL_StatusTypeDef status = HAL_OK;
545 /* Process locked */
546 __HAL_LOCK(hspdif);
548 if (HAL_SPDIFRX_STATE_READY == hspdif->State)
550 switch (CallbackID)
552 case HAL_SPDIFRX_RX_HALF_CB_ID :
553 hspdif->RxHalfCpltCallback = HAL_SPDIFRX_RxHalfCpltCallback;
554 break;
556 case HAL_SPDIFRX_RX_CPLT_CB_ID :
557 hspdif->RxCpltCallback = HAL_SPDIFRX_RxCpltCallback;
558 break;
560 case HAL_SPDIFRX_CX_HALF_CB_ID :
561 hspdif->CxHalfCpltCallback = HAL_SPDIFRX_CxHalfCpltCallback;
562 break;
564 case HAL_SPDIFRX_CX_CPLT_CB_ID :
565 hspdif->CxCpltCallback = HAL_SPDIFRX_CxCpltCallback;
566 break;
568 case HAL_SPDIFRX_ERROR_CB_ID :
569 hspdif->ErrorCallback = HAL_SPDIFRX_ErrorCallback;
570 break;
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;
580 else if (HAL_SPDIFRX_STATE_RESET == hspdif->State)
582 switch (CallbackID)
584 case HAL_SPDIFRX_MSPINIT_CB_ID :
585 hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit */
586 break;
588 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
589 hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspInit */
590 break;
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;
600 else
602 /* Update the error code */
603 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
604 /* Return error status */
605 status = HAL_ERROR;
608 /* Release Lock */
609 __HAL_UNLOCK(hspdif);
610 return status;
613 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
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
621 HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef sDataFormat)
623 uint32_t tmpreg;
625 /* Check the SPDIFRX handle allocation */
626 if (hspdif == NULL)
628 return HAL_ERROR;
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));
639 /* Reset the old SPDIFRX CR configuration */
640 tmpreg = hspdif->Instance->CR;
642 if (((tmpreg & SPDIFRX_STATE_RCV) == SPDIFRX_STATE_RCV) &&
643 (((tmpreg & SPDIFRX_CR_DRFMT) != sDataFormat.DataFormat) ||
644 ((tmpreg & SPDIFRX_CR_RXSTEO) != sDataFormat.StereoMode)))
646 return HAL_ERROR;
649 tmpreg &= ~(SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
650 SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK);
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);
660 hspdif->Instance->CR = tmpreg;
662 return HAL_OK;
666 * @}
669 /** @defgroup SPDIFRX_Exported_Functions_Group2 IO operation functions
670 * @brief Data transfers functions
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.
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.
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.
695 (#) No-Blocking mode functions with Interrupt are :
696 (++) HAL_SPDIFRX_ReceiveCtrlFlow_IT()
697 (++) HAL_SPDIFRX_ReceiveDataFlow_IT()
699 (#) No-Blocking mode functions with DMA are :
700 (++) HAL_SPDIFRX_ReceiveCtrlFlow_DMA()
701 (++) HAL_SPDIFRX_ReceiveDataFlow_DMA()
703 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
704 (++) HAL_SPDIFRX_RxCpltCallback()
705 (++) HAL_SPDIFRX_CxCpltCallback()
707 @endverbatim
708 * @{
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
720 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size,
721 uint32_t Timeout)
723 uint32_t tickstart;
724 uint16_t sizeCounter = Size;
725 uint32_t *pTmpBuf = pData;
727 if ((pData == NULL) || (Size == 0U))
729 return HAL_ERROR;
732 if (hspdif->State == HAL_SPDIFRX_STATE_READY)
734 /* Process Locked */
735 __HAL_LOCK(hspdif);
737 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
739 /* Start synchronisation */
740 __HAL_SPDIFRX_SYNC(hspdif);
742 /* Get tick */
743 tickstart = HAL_GetTick();
745 /* Wait until SYNCD flag is set */
746 if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
748 return HAL_TIMEOUT;
751 /* Start reception */
752 __HAL_SPDIFRX_RCV(hspdif);
754 /* Receive data flow */
755 while (sizeCounter > 0U)
757 /* Get tick */
758 tickstart = HAL_GetTick();
760 /* Wait until RXNE flag is set */
761 if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
763 return HAL_TIMEOUT;
766 (*pTmpBuf) = hspdif->Instance->DR;
767 pTmpBuf++;
768 sizeCounter--;
771 /* SPDIFRX ready */
772 hspdif->State = HAL_SPDIFRX_STATE_READY;
774 /* Process Unlocked */
775 __HAL_UNLOCK(hspdif);
777 return HAL_OK;
779 else
781 return HAL_BUSY;
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
794 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size,
795 uint32_t Timeout)
797 uint32_t tickstart;
798 uint16_t sizeCounter = Size;
799 uint32_t *pTmpBuf = pData;
801 if ((pData == NULL) || (Size == 0U))
803 return HAL_ERROR;
806 if (hspdif->State == HAL_SPDIFRX_STATE_READY)
808 /* Process Locked */
809 __HAL_LOCK(hspdif);
811 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
813 /* Start synchronization */
814 __HAL_SPDIFRX_SYNC(hspdif);
816 /* Get tick */
817 tickstart = HAL_GetTick();
819 /* Wait until SYNCD flag is set */
820 if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
822 return HAL_TIMEOUT;
825 /* Start reception */
826 __HAL_SPDIFRX_RCV(hspdif);
828 /* Receive control flow */
829 while (sizeCounter > 0U)
831 /* Get tick */
832 tickstart = HAL_GetTick();
834 /* Wait until CSRNE flag is set */
835 if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_CSRNE, RESET, Timeout, tickstart) != HAL_OK)
837 return HAL_TIMEOUT;
840 (*pTmpBuf) = hspdif->Instance->CSR;
841 pTmpBuf++;
842 sizeCounter--;
845 /* SPDIFRX ready */
846 hspdif->State = HAL_SPDIFRX_STATE_READY;
848 /* Process Unlocked */
849 __HAL_UNLOCK(hspdif);
851 return HAL_OK;
853 else
855 return HAL_BUSY;
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
866 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
868 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
870 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
872 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
874 if ((pData == NULL) || (Size == 0U))
876 return HAL_ERROR;
879 /* Process Locked */
880 __HAL_LOCK(hspdif);
882 hspdif->pRxBuffPtr = pData;
883 hspdif->RxXferSize = Size;
884 hspdif->RxXferCount = Size;
886 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
888 /* Check if a receive process is ongoing or not */
889 hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
891 /* Enable the SPDIFRX PE Error Interrupt */
892 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
894 /* Enable the SPDIFRX OVR Error Interrupt */
895 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
897 /* Enable the SPDIFRX RXNE interrupt */
898 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_RXNE);
900 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
902 /* Start synchronization */
903 __HAL_SPDIFRX_SYNC(hspdif);
905 /* Wait until SYNCD flag is set */
908 if (count == 0U)
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);
920 hspdif->State = HAL_SPDIFRX_STATE_READY;
922 /* Process Unlocked */
923 __HAL_UNLOCK(hspdif);
925 return HAL_TIMEOUT;
927 count--;
928 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
930 /* Start reception */
931 __HAL_SPDIFRX_RCV(hspdif);
934 /* Process Unlocked */
935 __HAL_UNLOCK(hspdif);
937 return HAL_OK;
939 else
941 return HAL_BUSY;
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
952 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
954 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
956 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
958 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
960 if ((pData == NULL) || (Size == 0U))
962 return HAL_ERROR;
965 /* Process Locked */
966 __HAL_LOCK(hspdif);
968 hspdif->pCsBuffPtr = pData;
969 hspdif->CsXferSize = Size;
970 hspdif->CsXferCount = Size;
972 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
974 /* Check if a receive process is ongoing or not */
975 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
977 /* Enable the SPDIFRX PE Error Interrupt */
978 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
980 /* Enable the SPDIFRX OVR Error Interrupt */
981 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
983 /* Enable the SPDIFRX CSRNE interrupt */
984 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
986 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
988 /* Start synchronization */
989 __HAL_SPDIFRX_SYNC(hspdif);
991 /* Wait until SYNCD flag is set */
994 if (count == 0U)
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);
1006 hspdif->State = HAL_SPDIFRX_STATE_READY;
1008 /* Process Unlocked */
1009 __HAL_UNLOCK(hspdif);
1011 return HAL_TIMEOUT;
1013 count--;
1014 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1016 /* Start reception */
1017 __HAL_SPDIFRX_RCV(hspdif);
1020 /* Process Unlocked */
1021 __HAL_UNLOCK(hspdif);
1023 return HAL_OK;
1025 else
1027 return HAL_BUSY;
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
1038 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1040 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1042 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1044 if ((pData == NULL) || (Size == 0U))
1046 return HAL_ERROR;
1049 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
1051 /* Process Locked */
1052 __HAL_LOCK(hspdif);
1054 hspdif->pRxBuffPtr = pData;
1055 hspdif->RxXferSize = Size;
1056 hspdif->RxXferCount = Size;
1058 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1059 hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
1061 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1062 hspdif->hdmaDrRx->XferHalfCpltCallback = SPDIFRX_DMARxHalfCplt;
1064 /* Set the SPDIFRX Rx DMA transfer complete callback */
1065 hspdif->hdmaDrRx->XferCpltCallback = SPDIFRX_DMARxCplt;
1067 /* Set the DMA error callback */
1068 hspdif->hdmaDrRx->XferErrorCallback = SPDIFRX_DMAError;
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)
1074 /* Set SPDIFRX error */
1075 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1077 /* Set SPDIFRX state */
1078 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1080 /* Process Unlocked */
1081 __HAL_UNLOCK(hspdif);
1083 return HAL_ERROR;
1086 /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/
1087 hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN;
1089 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1091 /* Start synchronization */
1092 __HAL_SPDIFRX_SYNC(hspdif);
1094 /* Wait until SYNCD flag is set */
1097 if (count == 0U)
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);
1109 hspdif->State = HAL_SPDIFRX_STATE_READY;
1111 /* Process Unlocked */
1112 __HAL_UNLOCK(hspdif);
1114 return HAL_TIMEOUT;
1116 count--;
1117 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1119 /* Start reception */
1120 __HAL_SPDIFRX_RCV(hspdif);
1123 /* Process Unlocked */
1124 __HAL_UNLOCK(hspdif);
1126 return HAL_OK;
1128 else
1130 return HAL_BUSY;
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
1141 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1143 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1145 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1147 if ((pData == NULL) || (Size == 0U))
1149 return HAL_ERROR;
1152 if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
1154 hspdif->pCsBuffPtr = pData;
1155 hspdif->CsXferSize = Size;
1156 hspdif->CsXferCount = Size;
1158 /* Process Locked */
1159 __HAL_LOCK(hspdif);
1161 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1162 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
1164 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1165 hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt;
1167 /* Set the SPDIFRX Rx DMA transfer complete callback */
1168 hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt;
1170 /* Set the DMA error callback */
1171 hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError;
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)
1177 /* Set SPDIFRX error */
1178 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1180 /* Set SPDIFRX state */
1181 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1183 /* Process Unlocked */
1184 __HAL_UNLOCK(hspdif);
1186 return HAL_ERROR;
1189 /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/
1190 hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN;
1192 if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1194 /* Start synchronization */
1195 __HAL_SPDIFRX_SYNC(hspdif);
1197 /* Wait until SYNCD flag is set */
1200 if (count == 0U)
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);
1212 hspdif->State = HAL_SPDIFRX_STATE_READY;
1214 /* Process Unlocked */
1215 __HAL_UNLOCK(hspdif);
1217 return HAL_TIMEOUT;
1219 count--;
1220 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1222 /* Start reception */
1223 __HAL_SPDIFRX_RCV(hspdif);
1226 /* Process Unlocked */
1227 __HAL_UNLOCK(hspdif);
1229 return HAL_OK;
1231 else
1233 return HAL_BUSY;
1238 * @brief stop the audio stream receive from the Media.
1239 * @param hspdif SPDIFRX handle
1240 * @retval None
1242 HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif)
1244 /* Process Locked */
1245 __HAL_LOCK(hspdif);
1247 /* Disable the SPDIFRX DMA requests */
1248 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1249 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1251 /* Disable the SPDIFRX DMA channel */
1252 if (hspdif->hdmaDrRx != NULL)
1254 __HAL_DMA_DISABLE(hspdif->hdmaDrRx);
1256 if (hspdif->hdmaCsRx != NULL)
1258 __HAL_DMA_DISABLE(hspdif->hdmaCsRx);
1261 /* Disable SPDIFRX peripheral */
1262 __HAL_SPDIFRX_IDLE(hspdif);
1264 hspdif->State = HAL_SPDIFRX_STATE_READY;
1266 /* Process Unlocked */
1267 __HAL_UNLOCK(hspdif);
1269 return HAL_OK;
1273 * @brief This function handles SPDIFRX interrupt request.
1274 * @param hspdif SPDIFRX handle
1275 * @retval HAL status
1277 void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif)
1279 uint32_t itFlag = hspdif->Instance->SR;
1280 uint32_t itSource = hspdif->Instance->IMR;
1282 /* SPDIFRX in mode Data Flow Reception */
1283 if (((itFlag & SPDIFRX_FLAG_RXNE) == SPDIFRX_FLAG_RXNE) && ((itSource & SPDIFRX_IT_RXNE) == SPDIFRX_IT_RXNE))
1285 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE);
1286 SPDIFRX_ReceiveDataFlow_IT(hspdif);
1289 /* SPDIFRX in mode Control Flow Reception */
1290 if (((itFlag & SPDIFRX_FLAG_CSRNE) == SPDIFRX_FLAG_CSRNE) && ((itSource & SPDIFRX_IT_CSRNE) == SPDIFRX_IT_CSRNE))
1292 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE);
1293 SPDIFRX_ReceiveControlFlow_IT(hspdif);
1296 /* SPDIFRX Overrun error interrupt occurred */
1297 if (((itFlag & SPDIFRX_FLAG_OVR) == SPDIFRX_FLAG_OVR) && ((itSource & SPDIFRX_IT_OVRIE) == SPDIFRX_IT_OVRIE))
1299 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_OVRIE);
1301 /* Change the SPDIFRX error code */
1302 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR;
1304 /* the transfer is not stopped */
1305 HAL_SPDIFRX_ErrorCallback(hspdif);
1308 /* SPDIFRX Parity error interrupt occurred */
1309 if (((itFlag & SPDIFRX_FLAG_PERR) == SPDIFRX_FLAG_PERR) && ((itSource & SPDIFRX_IT_PERRIE) == SPDIFRX_IT_PERRIE))
1311 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_PERRIE);
1313 /* Change the SPDIFRX error code */
1314 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE;
1316 /* the transfer is not stopped */
1317 HAL_SPDIFRX_ErrorCallback(hspdif);
1322 * @brief Rx Transfer (Data flow) half completed callbacks
1323 * @param hspdif SPDIFRX handle
1324 * @retval None
1326 __weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1328 /* Prevent unused argument(s) compilation warning */
1329 UNUSED(hspdif);
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
1337 * @brief Rx Transfer (Data flow) completed callbacks
1338 * @param hspdif SPDIFRX handle
1339 * @retval None
1341 __weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1343 /* Prevent unused argument(s) compilation warning */
1344 UNUSED(hspdif);
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
1352 * @brief Rx (Control flow) Transfer half completed callbacks
1353 * @param hspdif SPDIFRX handle
1354 * @retval None
1356 __weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1358 /* Prevent unused argument(s) compilation warning */
1359 UNUSED(hspdif);
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
1367 * @brief Rx Transfer (Control flow) completed callbacks
1368 * @param hspdif SPDIFRX handle
1369 * @retval None
1371 __weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1373 /* Prevent unused argument(s) compilation warning */
1374 UNUSED(hspdif);
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
1382 * @brief SPDIFRX error callbacks
1383 * @param hspdif SPDIFRX handle
1384 * @retval None
1386 __weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif)
1388 /* Prevent unused argument(s) compilation warning */
1389 UNUSED(hspdif);
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
1397 * @}
1400 /** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions
1401 * @brief Peripheral State functions
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.
1411 @endverbatim
1412 * @{
1416 * @brief Return the SPDIFRX state
1417 * @param hspdif SPDIFRX handle
1418 * @retval HAL state
1420 HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const *const hspdif)
1422 return hspdif->State;
1426 * @brief Return the SPDIFRX error code
1427 * @param hspdif SPDIFRX handle
1428 * @retval SPDIFRX Error Code
1430 uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const *const hspdif)
1432 return hspdif->ErrorCode;
1436 * @}
1440 * @brief DMA SPDIFRX receive process (Data flow) complete callback
1441 * @param hdma DMA handle
1442 * @retval None
1444 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma)
1446 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1448 /* Disable Rx DMA Request */
1449 if (hdma->Init.Mode != DMA_CIRCULAR)
1451 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1452 hspdif->RxXferCount = 0;
1453 hspdif->State = HAL_SPDIFRX_STATE_READY;
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 */
1463 * @brief DMA SPDIFRX receive process (Data flow) half complete callback
1464 * @param hdma DMA handle
1465 * @retval None
1467 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1469 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
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 */
1480 * @brief DMA SPDIFRX receive process (Control flow) complete callback
1481 * @param hdma DMA handle
1482 * @retval None
1484 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma)
1486 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1488 /* Disable Cb DMA Request */
1489 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1490 hspdif->CsXferCount = 0;
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 */
1501 * @brief DMA SPDIFRX receive process (Control flow) half complete callback
1502 * @param hdma DMA handle
1503 * @retval None
1505 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma)
1507 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
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 */
1517 * @brief DMA SPDIFRX communication error callback
1518 * @param hdma DMA handle
1519 * @retval None
1521 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma)
1523 SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1525 /* Disable Rx and Cb DMA Request */
1526 hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN));
1527 hspdif->RxXferCount = 0;
1529 hspdif->State = HAL_SPDIFRX_STATE_READY;
1531 /* Set the error code and execute error callback*/
1532 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA;
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 */
1544 * @brief Receive an amount of data (Data Flow) with Interrupt
1545 * @param hspdif SPDIFRX handle
1546 * @retval None
1548 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1550 /* Receive data */
1551 (*hspdif->pRxBuffPtr) = hspdif->Instance->DR;
1552 hspdif->pRxBuffPtr++;
1553 hspdif->RxXferCount--;
1555 if (hspdif->RxXferCount == 0U)
1557 /* Disable RXNE/PE and OVR interrupts */
1558 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE);
1560 hspdif->State = HAL_SPDIFRX_STATE_READY;
1562 /* Process Unlocked */
1563 __HAL_UNLOCK(hspdif);
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 */
1574 * @brief Receive an amount of data (Control Flow) with Interrupt
1575 * @param hspdif SPDIFRX handle
1576 * @retval None
1578 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1580 /* Receive data */
1581 (*hspdif->pCsBuffPtr) = hspdif->Instance->CSR;
1582 hspdif->pCsBuffPtr++;
1583 hspdif->CsXferCount--;
1585 if (hspdif->CsXferCount == 0U)
1587 /* Disable CSRNE interrupt */
1588 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1590 hspdif->State = HAL_SPDIFRX_STATE_READY;
1592 /* Process Unlocked */
1593 __HAL_UNLOCK(hspdif);
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 */
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
1612 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag,
1613 FlagStatus Status, uint32_t Timeout, uint32_t tickstart)
1615 /* Wait until flag is set */
1616 while (__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == Status)
1618 /* Check for the Timeout */
1619 if (Timeout != HAL_MAX_DELAY)
1621 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
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);
1633 hspdif->State = HAL_SPDIFRX_STATE_READY;
1635 /* Process Unlocked */
1636 __HAL_UNLOCK(hspdif);
1638 return HAL_TIMEOUT;
1643 return HAL_OK;
1647 * @}
1651 #endif /* SPDIFRX */
1652 #endif /* HAL_SPDIFRX_MODULE_ENABLED */
1654 * @}
1658 * @}