Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_spdifrx.c
blob1f787273a0f6ebb89c02efc7dce209ffd74f7adc
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 @verbatim
12 ===============================================================================
13 ##### How to use this driver #####
14 ===============================================================================
15 [..]
16 The SPDIFRX HAL driver can be used as follow:
18 (#) Declare SPDIFRX_HandleTypeDef handle structure.
19 (#) Initialize the SPDIFRX low level resources by implement the HAL_SPDIFRX_MspInit() API:
20 (##) Enable the SPDIFRX interface clock.
21 (##) SPDIFRX pins configuration:
22 (+++) Enable the clock for the SPDIFRX GPIOs.
23 (+++) Configure these SPDIFRX pins as alternate function pull-up.
24 (##) NVIC configuration if you need to use interrupt process (HAL_SPDIFRX_ReceiveCtrlFlow_IT() and HAL_SPDIFRX_ReceiveDataFlow_IT() API's).
25 (+++) Configure the SPDIFRX interrupt priority.
26 (+++) Enable the NVIC SPDIFRX IRQ handle.
27 (##) DMA Configuration if you need to use DMA process (HAL_SPDIFRX_ReceiveDataFlow_DMA() and HAL_SPDIFRX_ReceiveCtrlFlow_DMA() API's).
28 (+++) Declare a DMA handle structure for the reception of the Data Flow channel.
29 (+++) Declare a DMA handle structure for the reception of the Control Flow channel.
30 (+++) Enable the DMAx interface clock.
31 (+++) Configure the declared DMA handle structure CtrlRx/DataRx with the required parameters.
32 (+++) Configure the DMA Channel.
33 (+++) Associate the initialized DMA handle to the SPDIFRX DMA CtrlRx/DataRx handle.
34 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
35 DMA CtrlRx/DataRx channel.
37 (#) Program the input selection, re-tries number, wait for activity, channel status selection, data format, stereo mode and masking of user bits
38 using HAL_SPDIFRX_Init() function.
40 -@- The specific SPDIFRX interrupts (RXNE/CSRNE and Error Interrupts) will be managed using the macros
41 __SPDIFRX_ENABLE_IT() and __SPDIFRX_DISABLE_IT() inside the receive process.
42 -@- Make sure that ck_spdif clock is configured.
44 (#) Three operation modes are available within this driver :
46 *** Polling mode for reception operation (for debug purpose) ***
47 ================================================================
48 [..]
49 (+) Receive data flow in blocking mode using HAL_SPDIFRX_ReceiveDataFlow()
50 (+) Receive control flow of data in blocking mode using HAL_SPDIFRX_ReceiveCtrlFlow()
52 *** Interrupt mode for reception operation ***
53 =========================================
54 [..]
55 (+) Receive an amount of data (Data Flow) in non blocking mode using HAL_SPDIFRX_ReceiveDataFlow_IT()
56 (+) Receive an amount of data (Control Flow) in non blocking mode using HAL_SPDIFRX_ReceiveCtrlFlow_IT()
57 (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can
58 add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback
59 (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can
60 add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback
61 (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can
62 add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback
64 *** DMA mode for reception operation ***
65 ========================================
66 [..]
67 (+) Receive an amount of data (Data Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveDataFlow_DMA()
68 (+) Receive an amount of data (Control Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveCtrlFlow_DMA()
69 (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can
70 add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback
71 (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can
72 add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback
73 (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can
74 add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback
75 (+) Stop the DMA Transfer using HAL_SPDIFRX_DMAStop()
77 *** SPDIFRX HAL driver macros list ***
78 =============================================
79 [..]
80 Below the list of most used macros in SPDIFRX HAL driver.
81 (+) __HAL_SPDIFRX_IDLE: Disable the specified SPDIFRX peripheral (IDEL State)
82 (+) __HAL_SPDIFRX_SYNC: Enable the synchronization state of the specified SPDIFRX peripheral (SYNC State)
83 (+) __HAL_SPDIFRX_RCV: Enable the receive state of the specified SPDIFRX peripheral (RCV State)
84 (+) __HAL_SPDIFRX_ENABLE_IT : Enable the specified SPDIFRX interrupts
85 (+) __HAL_SPDIFRX_DISABLE_IT : Disable the specified SPDIFRX interrupts
86 (+) __HAL_SPDIFRX_GET_FLAG: Check whether the specified SPDIFRX flag is set or not.
88 [..]
89 (@) You can refer to the SPDIFRX HAL driver header file for more useful macros
91 *** Callback registration ***
92 =============================================
94 The compilation define USE_HAL_SPDIFRX_REGISTER_CALLBACKS when set to 1
95 allows the user to configure dynamically the driver callbacks.
96 Use HAL_SPDIFRX_RegisterCallback() funtion to register an interrupt callback.
98 The HAL_SPDIFRX_RegisterCallback() function allows to register the following callbacks:
99 (+) RxHalfCpltCallback : SPDIFRX Data flow half completed callback.
100 (+) RxCpltCallback : SPDIFRX Data flow completed callback.
101 (+) CxHalfCpltCallback : SPDIFRX Control flow half completed callback.
102 (+) CxCpltCallback : SPDIFRX Control flow completed callback.
103 (+) ErrorCallback : SPDIFRX error callback.
104 (+) MspInitCallback : SPDIFRX MspInit.
105 (+) MspDeInitCallback : SPDIFRX MspDeInit.
106 This function takes as parameters the HAL peripheral handle, the Callback ID
107 and a pointer to the user callback function.
109 Use HAL_SPDIFRX_UnRegisterCallback() function to reset a callback to the default
110 weak function.
111 The HAL_SPDIFRX_UnRegisterCallback() function takes as parameters the HAL peripheral handle,
112 and the Callback ID.
113 This function allows to reset the following callbacks:
114 (+) RxHalfCpltCallback : SPDIFRX Data flow half completed callback.
115 (+) RxCpltCallback : SPDIFRX Data flow completed callback.
116 (+) CxHalfCpltCallback : SPDIFRX Control flow half completed callback.
117 (+) CxCpltCallback : SPDIFRX Control flow completed callback.
118 (+) ErrorCallback : SPDIFRX error callback.
119 (+) MspInitCallback : SPDIFRX MspInit.
120 (+) MspDeInitCallback : SPDIFRX MspDeInit.
122 By default, after the HAL_SPDIFRX_Init() and when the state is HAL_SPDIFRX_STATE_RESET
123 all callbacks are set to the corresponding weak functions :
124 HAL_SPDIFRX_RxHalfCpltCallback() , HAL_SPDIFRX_RxCpltCallback(), HAL_SPDIFRX_CxHalfCpltCallback(),
125 HAL_SPDIFRX_CxCpltCallback() and HAL_SPDIFRX_ErrorCallback()
126 Exception done for MspInit and MspDeInit functions that are
127 reset to the legacy weak function in the HAL_SPDIFRX_Init()/ HAL_SPDIFRX_DeInit() only when
128 these callbacks pointers are NULL (not registered beforehand).
129 If not, MspInit or MspDeInit callbacks pointers are not null, the HAL_SPDIFRX_Init() / HAL_SPDIFRX_DeInit()
130 keep and use the user MspInit/MspDeInit functions (registered beforehand)
132 Callbacks can be registered/unregistered in HAL_SPDIFRX_STATE_READY state only.
133 Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
134 in HAL_SPDIFRX_STATE_READY or HAL_SPDIFRX_STATE_RESET state,
135 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
136 In that case first register the MspInit/MspDeInit user callbacks
137 using HAL_SPDIFRX_RegisterCallback() before calling HAL_SPDIFRX_DeInit()
138 or HAL_SPDIFRX_Init() function.
140 When The compilation define USE_HAL_SPDIFRX_REGISTER_CALLBACKS is set to 0 or
141 not defined, the callback registration feature is not available and all callbacks
142 are set to the corresponding weak functions.
144 @endverbatim
145 ******************************************************************************
146 * @attention
148 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
149 * All rights reserved.</center></h2>
151 * This software component is licensed by ST under BSD 3-Clause license,
152 * the "License"; You may not use this file except in compliance with the
153 * License. You may obtain a copy of the License at:
154 * opensource.org/licenses/BSD-3-Clause
156 ******************************************************************************
159 /* Includes ------------------------------------------------------------------*/
160 #include "stm32h7xx_hal.h"
162 /** @addtogroup STM32H7xx_HAL_Driver
163 * @{
166 /** @defgroup SPDIFRX SPDIFRX
167 * @brief SPDIFRX HAL module driver
168 * @{
171 #ifdef HAL_SPDIFRX_MODULE_ENABLED
172 #if defined (SPDIFRX)
174 /* Private typedef -----------------------------------------------------------*/
175 /* Private define ------------------------------------------------------------*/
176 #define SPDIFRX_TIMEOUT_VALUE 0xFFFFU
178 /* Private macro -------------------------------------------------------------*/
179 /* Private variables ---------------------------------------------------------*/
180 /* Private function prototypes -----------------------------------------------*/
181 /** @addtogroup SPDIFRX_Private_Functions
182 * @{
184 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma);
185 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
186 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma);
187 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma);
188 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma);
189 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif);
190 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif);
191 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t tickstart);
193 * @}
195 /* Exported functions ---------------------------------------------------------*/
197 /** @defgroup SPDIFRX_Exported_Functions SPDIFRX Exported Functions
198 * @{
201 /** @defgroup SPDIFRX_Exported_Functions_Group1 Initialization and de-initialization functions
202 * @brief Initialization and Configuration functions
204 @verbatim
205 ===============================================================================
206 ##### Initialization and de-initialization functions #####
207 ===============================================================================
208 [..] This subsection provides a set of functions allowing to initialize and
209 de-initialize the SPDIFRX peripheral:
211 (+) User must Implement HAL_SPDIFRX_MspInit() function in which he configures
212 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
214 (+) Call the function HAL_SPDIFRX_Init() to configure the SPDIFRX peripheral with
215 the selected configuration:
216 (++) Input Selection (IN0, IN1,...)
217 (++) Maximum allowed re-tries during synchronization phase
218 (++) Wait for activity on SPDIF selected input
219 (++) Channel status selection (from channel A or B)
220 (++) Data format (LSB, MSB, ...)
221 (++) Stereo mode
222 (++) User bits masking (PT,C,U,V,...)
224 (+) Call the function HAL_SPDIFRX_DeInit() to restore the default configuration
225 of the selected SPDIFRXx peripheral.
226 @endverbatim
227 * @{
231 * @brief Initializes the SPDIFRX according to the specified parameters
232 * in the SPDIFRX_InitTypeDef and create the associated handle.
233 * @param hspdif SPDIFRX handle
234 * @retval HAL status
236 HAL_StatusTypeDef HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef *hspdif)
238 uint32_t tmpreg;
240 /* Check the SPDIFRX handle allocation */
241 if(hspdif == NULL)
243 return HAL_ERROR;
246 /* Check the SPDIFRX parameters */
247 assert_param(IS_STEREO_MODE(hspdif->Init.StereoMode));
248 assert_param(IS_SPDIFRX_INPUT_SELECT(hspdif->Init.InputSelection));
249 assert_param(IS_SPDIFRX_MAX_RETRIES(hspdif->Init.Retries));
250 assert_param(IS_SPDIFRX_WAIT_FOR_ACTIVITY(hspdif->Init.WaitForActivity));
251 assert_param(IS_SPDIFRX_CHANNEL(hspdif->Init.ChannelSelection));
252 assert_param(IS_SPDIFRX_DATA_FORMAT(hspdif->Init.DataFormat));
253 assert_param(IS_PREAMBLE_TYPE_MASK(hspdif->Init.PreambleTypeMask));
254 assert_param(IS_CHANNEL_STATUS_MASK(hspdif->Init.ChannelStatusMask));
255 assert_param(IS_VALIDITY_MASK(hspdif->Init.ValidityBitMask));
256 assert_param(IS_PARITY_ERROR_MASK(hspdif->Init.ParityErrorMask));
257 assert_param(IS_SYMBOL_CLOCK_GEN(hspdif->Init.SymbolClockGen));
258 assert_param(IS_SYMBOL_CLOCK_GEN(hspdif->Init.BackupSymbolClockGen));
260 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
261 if(hspdif->State == HAL_SPDIFRX_STATE_RESET)
263 /* Allocate lock resource and initialize it */
264 hspdif->Lock = HAL_UNLOCKED;
266 hspdif->RxHalfCpltCallback = HAL_SPDIFRX_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
267 hspdif->RxCpltCallback = HAL_SPDIFRX_RxCpltCallback; /* Legacy weak RxCpltCallback */
268 hspdif->CxHalfCpltCallback = HAL_SPDIFRX_CxHalfCpltCallback; /* Legacy weak CxHalfCpltCallback */
269 hspdif->CxCpltCallback = HAL_SPDIFRX_CxCpltCallback; /* Legacy weak CxCpltCallback */
270 hspdif->ErrorCallback = HAL_SPDIFRX_ErrorCallback; /* Legacy weak ErrorCallback */
272 if(hspdif->MspInitCallback == NULL)
274 hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit */
277 /* Init the low level hardware */
278 hspdif->MspInitCallback(hspdif);
280 #else
281 if(hspdif->State == HAL_SPDIFRX_STATE_RESET)
283 /* Allocate lock resource and initialize it */
284 hspdif->Lock = HAL_UNLOCKED;
285 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
286 HAL_SPDIFRX_MspInit(hspdif);
288 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
290 /* SPDIFRX peripheral state is BUSY */
291 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
293 /* Disable SPDIFRX interface (IDLE State) */
294 __HAL_SPDIFRX_IDLE(hspdif);
296 /* Reset the old SPDIFRX CR configuration */
297 tmpreg = hspdif->Instance->CR;
299 tmpreg &= ~(SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
300 SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK |
301 SPDIFRX_CR_CHSEL | SPDIFRX_CR_NBTR | SPDIFRX_CR_WFA |
302 SPDIFRX_CR_CKSEN | SPDIFRX_CR_CKSBKPEN |
303 SPDIFRX_CR_INSEL);
305 /* Sets the new configuration of the SPDIFRX peripheral */
306 tmpreg |= (hspdif->Init.StereoMode |
307 hspdif->Init.InputSelection |
308 hspdif->Init.Retries |
309 hspdif->Init.WaitForActivity |
310 hspdif->Init.ChannelSelection |
311 hspdif->Init.DataFormat |
312 hspdif->Init.PreambleTypeMask |
313 hspdif->Init.ChannelStatusMask |
314 hspdif->Init.ValidityBitMask |
315 hspdif->Init.ParityErrorMask
318 if(hspdif->Init.SymbolClockGen == ENABLE)
320 tmpreg |= SPDIFRX_CR_CKSEN;
323 if(hspdif->Init.BackupSymbolClockGen == ENABLE)
325 tmpreg |= SPDIFRX_CR_CKSBKPEN;
328 hspdif->Instance->CR = tmpreg;
330 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
332 /* SPDIFRX peripheral state is READY*/
333 hspdif->State = HAL_SPDIFRX_STATE_READY;
335 return HAL_OK;
339 * @brief DeInitializes the SPDIFRX peripheral
340 * @param hspdif SPDIFRX handle
341 * @retval HAL status
343 HAL_StatusTypeDef HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef *hspdif)
345 /* Check the SPDIFRX handle allocation */
346 if(hspdif == NULL)
348 return HAL_ERROR;
351 /* Check the parameters */
352 assert_param(IS_SPDIFRX_ALL_INSTANCE(hspdif->Instance));
354 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
356 /* Disable SPDIFRX interface (IDLE state) */
357 __HAL_SPDIFRX_IDLE(hspdif);
359 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
360 if(hspdif->MspDeInitCallback == NULL)
362 hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspDeInit */
365 /* DeInit the low level hardware */
366 hspdif->MspDeInitCallback(hspdif);
367 #else
368 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
369 HAL_SPDIFRX_MspDeInit(hspdif);
370 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
372 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
374 /* SPDIFRX peripheral state is RESET*/
375 hspdif->State = HAL_SPDIFRX_STATE_RESET;
377 /* Release Lock */
378 __HAL_UNLOCK(hspdif);
380 return HAL_OK;
384 * @brief SPDIFRX MSP Init
385 * @param hspdif SPDIFRX handle
386 * @retval None
388 __weak void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif)
390 /* Prevent unused argument(s) compilation warning */
391 UNUSED(hspdif);
393 /* NOTE : This function Should not be modified, when the callback is needed,
394 the HAL_SPDIFRX_MspInit could be implemented in the user file
399 * @brief SPDIFRX MSP DeInit
400 * @param hspdif SPDIFRX handle
401 * @retval None
403 __weak void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif)
405 /* Prevent unused argument(s) compilation warning */
406 UNUSED(hspdif);
408 /* NOTE : This function Should not be modified, when the callback is needed,
409 the HAL_SPDIFRX_MspDeInit could be implemented in the user file
413 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
415 * @brief Register a User SPDIFRX Callback
416 * To be used instead of the weak predefined callback
417 * @param hspdif SPDIFRX handle
418 * @param CallbackID ID of the callback to be registered
419 * This parameter can be one of the following values:
420 * @arg @ref HAL_SPDIFRX_RX_HALF_CB_ID SPDIFRX Data flow half completed callback ID
421 * @arg @ref HAL_SPDIFRX_RX_CPLT_CB_ID SPDIFRX Data flow completed callback ID
422 * @arg @ref HAL_SPDIFRX_CX_HALF_CB_ID SPDIFRX Control flow half completed callback ID
423 * @arg @ref HAL_SPDIFRX_CX_CPLT_CB_ID SPDIFRX Control flow completed callback ID
424 * @arg @ref HAL_SPDIFRX_ERROR_CB_ID SPDIFRX error callback ID
425 * @arg @ref HAL_SPDIFRX_MSPINIT_CB_ID MspInit callback ID
426 * @arg @ref HAL_SPDIFRX_MSPDEINIT_CB_ID MspDeInit callback ID
427 * @param pCallback pointer to the Callback function
428 * @retval HAL status
430 HAL_StatusTypeDef HAL_SPDIFRX_RegisterCallback(SPDIFRX_HandleTypeDef *hspdif, HAL_SPDIFRX_CallbackIDTypeDef CallbackID, pSPDIFRX_CallbackTypeDef pCallback)
432 HAL_StatusTypeDef status = HAL_OK;
434 if(pCallback == NULL)
436 /* Update the error code */
437 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
438 return HAL_ERROR;
440 /* Process locked */
441 __HAL_LOCK(hspdif);
443 if(HAL_SPDIFRX_STATE_READY == hspdif->State)
445 switch (CallbackID)
447 case HAL_SPDIFRX_RX_HALF_CB_ID :
448 hspdif->RxHalfCpltCallback = pCallback;
449 break;
451 case HAL_SPDIFRX_RX_CPLT_CB_ID :
452 hspdif->RxCpltCallback = pCallback;
453 break;
455 case HAL_SPDIFRX_CX_HALF_CB_ID :
456 hspdif->CxHalfCpltCallback = pCallback;
457 break;
459 case HAL_SPDIFRX_CX_CPLT_CB_ID :
460 hspdif->CxCpltCallback = pCallback;
461 break;
463 case HAL_SPDIFRX_ERROR_CB_ID :
464 hspdif->ErrorCallback = pCallback;
465 break;
467 case HAL_SPDIFRX_MSPINIT_CB_ID :
468 hspdif->MspInitCallback = pCallback;
469 break;
471 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
472 hspdif->MspDeInitCallback = pCallback;
473 break;
475 default :
476 /* Update the error code */
477 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
478 /* Return error status */
479 status = HAL_ERROR;
480 break;
483 else if(HAL_SPDIFRX_STATE_RESET == hspdif->State)
485 switch (CallbackID)
487 case HAL_SPDIFRX_MSPINIT_CB_ID :
488 hspdif->MspInitCallback = pCallback;
489 break;
491 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
492 hspdif->MspDeInitCallback = pCallback;
493 break;
495 default :
496 /* Update the error code */
497 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
498 /* Return error status */
499 status = HAL_ERROR;
500 break;
503 else
505 /* Update the error code */
506 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
507 /* Return error status */
508 status = HAL_ERROR;
511 /* Release Lock */
512 __HAL_UNLOCK(hspdif);
513 return status;
517 * @brief Unregister a SPDIFRX Callback
518 * SPDIFRX callabck is redirected to the weak predefined callback
519 * @param hspdif SPDIFRX handle
520 * @param CallbackID ID of the callback to be unregistered
521 * This parameter can be one of the following values:
522 * @arg @ref HAL_SPDIFRX_RX_HALF_CB_ID SPDIFRX Data flow half completed callback ID
523 * @arg @ref HAL_SPDIFRX_RX_CPLT_CB_ID SPDIFRX Data flow completed callback ID
524 * @arg @ref HAL_SPDIFRX_CX_HALF_CB_ID SPDIFRX Control flow half completed callback ID
525 * @arg @ref HAL_SPDIFRX_CX_CPLT_CB_ID SPDIFRX Control flow completed callback ID
526 * @arg @ref HAL_SPDIFRX_ERROR_CB_ID SPDIFRX error callback ID
527 * @arg @ref HAL_SPDIFRX_MSPINIT_CB_ID MspInit callback ID
528 * @arg @ref HAL_SPDIFRX_MSPDEINIT_CB_ID MspDeInit callback ID
529 * @retval HAL status
531 HAL_StatusTypeDef HAL_SPDIFRX_UnRegisterCallback(SPDIFRX_HandleTypeDef *hspdif, HAL_SPDIFRX_CallbackIDTypeDef CallbackID)
533 HAL_StatusTypeDef status = HAL_OK;
535 /* Process locked */
536 __HAL_LOCK(hspdif);
538 if(HAL_SPDIFRX_STATE_READY == hspdif->State)
540 switch (CallbackID)
542 case HAL_SPDIFRX_RX_HALF_CB_ID :
543 hspdif->RxHalfCpltCallback = HAL_SPDIFRX_RxHalfCpltCallback;
544 break;
546 case HAL_SPDIFRX_RX_CPLT_CB_ID :
547 hspdif->RxCpltCallback = HAL_SPDIFRX_RxCpltCallback;
548 break;
550 case HAL_SPDIFRX_CX_HALF_CB_ID :
551 hspdif->CxHalfCpltCallback = HAL_SPDIFRX_CxHalfCpltCallback;
552 break;
554 case HAL_SPDIFRX_CX_CPLT_CB_ID :
555 hspdif->CxCpltCallback = HAL_SPDIFRX_CxCpltCallback;
556 break;
558 case HAL_SPDIFRX_ERROR_CB_ID :
559 hspdif->ErrorCallback = HAL_SPDIFRX_ErrorCallback;
560 break;
562 default :
563 /* Update the error code */
564 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
565 /* Return error status */
566 status = HAL_ERROR;
567 break;
570 else if(HAL_SPDIFRX_STATE_RESET == hspdif->State)
572 switch (CallbackID)
574 case HAL_SPDIFRX_MSPINIT_CB_ID :
575 hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit */
576 break;
578 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
579 hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspInit */
580 break;
582 default :
583 /* Update the error code */
584 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
585 /* Return error status */
586 status = HAL_ERROR;
587 break;
590 else
592 /* Update the error code */
593 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
594 /* Return error status */
595 status = HAL_ERROR;
598 /* Release Lock */
599 __HAL_UNLOCK(hspdif);
600 return status;
603 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
606 * @brief Set the SPDIFRX data format according to the specified parameters in the SPDIFRX_InitTypeDef.
607 * @param hspdif SPDIFRX handle
608 * @param sDataFormat SPDIFRX data format
609 * @retval HAL status
611 HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef sDataFormat)
613 uint32_t tmpreg;
615 /* Check the SPDIFRX handle allocation */
616 if(hspdif == NULL)
618 return HAL_ERROR;
621 /* Check the SPDIFRX parameters */
622 assert_param(IS_STEREO_MODE(sDataFormat.StereoMode));
623 assert_param(IS_SPDIFRX_DATA_FORMAT(sDataFormat.DataFormat));
624 assert_param(IS_PREAMBLE_TYPE_MASK(sDataFormat.PreambleTypeMask));
625 assert_param(IS_CHANNEL_STATUS_MASK(sDataFormat.ChannelStatusMask));
626 assert_param(IS_VALIDITY_MASK(sDataFormat.ValidityBitMask));
627 assert_param(IS_PARITY_ERROR_MASK(sDataFormat.ParityErrorMask));
629 /* Reset the old SPDIFRX CR configuration */
630 tmpreg = hspdif->Instance->CR;
632 if(((tmpreg & SPDIFRX_STATE_RCV) == SPDIFRX_STATE_RCV) &&
633 (((tmpreg & SPDIFRX_CR_DRFMT) != sDataFormat.DataFormat) ||
634 ((tmpreg & SPDIFRX_CR_RXSTEO) != sDataFormat.StereoMode)))
636 return HAL_ERROR;
639 tmpreg &= ~(SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
640 SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK);
642 /* Configure the new data format */
643 tmpreg |= (sDataFormat.StereoMode |
644 sDataFormat.DataFormat |
645 sDataFormat.PreambleTypeMask |
646 sDataFormat.ChannelStatusMask |
647 sDataFormat.ValidityBitMask |
648 sDataFormat.ParityErrorMask);
650 hspdif->Instance->CR = tmpreg;
652 return HAL_OK;
656 * @}
659 /** @defgroup SPDIFRX_Exported_Functions_Group2 IO operation functions
660 * @brief Data transfers functions
662 @verbatim
663 ===============================================================================
664 ##### IO operation functions #####
665 ===============================================================================
666 [..]
667 This subsection provides a set of functions allowing to manage the SPDIFRX data
668 transfers.
670 (#) There is two mode of transfer:
671 (++) Blocking mode : The communication is performed in the polling mode.
672 The status of all data processing is returned by the same function
673 after finishing transfer.
674 (++) No-Blocking mode : The communication is performed using Interrupts
675 or DMA. These functions return the status of the transfer start-up.
676 The end of the data processing will be indicated through the
677 dedicated SPDIFRX IRQ when using Interrupt mode or the DMA IRQ when
678 using DMA mode.
680 (#) Blocking mode functions are :
681 (++) HAL_SPDIFRX_ReceiveDataFlow()
682 (++) HAL_SPDIFRX_ReceiveCtrlFlow()
683 (+@) Do not use blocking mode to receive both control and data flow at the same time.
685 (#) No-Blocking mode functions with Interrupt are :
686 (++) HAL_SPDIFRX_ReceiveCtrlFlow_IT()
687 (++) HAL_SPDIFRX_ReceiveDataFlow_IT()
689 (#) No-Blocking mode functions with DMA are :
690 (++) HAL_SPDIFRX_ReceiveCtrlFlow_DMA()
691 (++) HAL_SPDIFRX_ReceiveDataFlow_DMA()
693 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
694 (++) HAL_SPDIFRX_RxCpltCallback()
695 (++) HAL_SPDIFRX_CxCpltCallback()
697 @endverbatim
698 * @{
702 * @brief Receives an amount of data (Data Flow) in blocking mode.
703 * @param hspdif pointer to SPDIFRX_HandleTypeDef structure that contains
704 * the configuration information for SPDIFRX module.
705 * @param pData Pointer to data buffer
706 * @param Size Amount of data to be received
707 * @param Timeout Timeout duration
708 * @retval HAL status
710 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout)
712 uint32_t tickstart;
713 uint16_t sizeCounter = Size;
714 uint32_t *pTmpBuf = pData;
716 if((pData == NULL ) || (Size == 0U))
718 return HAL_ERROR;
721 if(hspdif->State == HAL_SPDIFRX_STATE_READY)
723 /* Process Locked */
724 __HAL_LOCK(hspdif);
726 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
728 /* Start synchronisation */
729 __HAL_SPDIFRX_SYNC(hspdif);
731 /* Get tick */
732 tickstart = HAL_GetTick();
734 /* Wait until SYNCD flag is set */
735 if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
737 return HAL_TIMEOUT;
740 /* Start reception */
741 __HAL_SPDIFRX_RCV(hspdif);
743 /* Receive data flow */
744 while(sizeCounter > 0U)
746 /* Get tick */
747 tickstart = HAL_GetTick();
749 /* Wait until RXNE flag is set */
750 if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
752 return HAL_TIMEOUT;
755 (*pTmpBuf) = hspdif->Instance->DR;
756 pTmpBuf++;
757 sizeCounter--;
760 /* SPDIFRX ready */
761 hspdif->State = HAL_SPDIFRX_STATE_READY;
763 /* Process Unlocked */
764 __HAL_UNLOCK(hspdif);
766 return HAL_OK;
768 else
770 return HAL_BUSY;
775 * @brief Receives an amount of data (Control Flow) in blocking mode.
776 * @param hspdif pointer to a SPDIFRX_HandleTypeDef structure that contains
777 * the configuration information for SPDIFRX module.
778 * @param pData Pointer to data buffer
779 * @param Size Amount of data to be received
780 * @param Timeout Timeout duration
781 * @retval HAL status
783 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout)
785 uint32_t tickstart;
786 uint16_t sizeCounter = Size;
787 uint32_t *pTmpBuf = pData;
789 if((pData == NULL ) || (Size == 0U))
791 return HAL_ERROR;
794 if(hspdif->State == HAL_SPDIFRX_STATE_READY)
796 /* Process Locked */
797 __HAL_LOCK(hspdif);
799 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
801 /* Start synchronization */
802 __HAL_SPDIFRX_SYNC(hspdif);
804 /* Get tick */
805 tickstart = HAL_GetTick();
807 /* Wait until SYNCD flag is set */
808 if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
810 return HAL_TIMEOUT;
813 /* Start reception */
814 __HAL_SPDIFRX_RCV(hspdif);
816 /* Receive control flow */
817 while(sizeCounter > 0U)
819 /* Get tick */
820 tickstart = HAL_GetTick();
822 /* Wait until CSRNE flag is set */
823 if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_CSRNE, RESET, Timeout, tickstart) != HAL_OK)
825 return HAL_TIMEOUT;
828 (*pTmpBuf) = hspdif->Instance->CSR;
829 pTmpBuf++;
830 sizeCounter--;
833 /* SPDIFRX ready */
834 hspdif->State = HAL_SPDIFRX_STATE_READY;
836 /* Process Unlocked */
837 __HAL_UNLOCK(hspdif);
839 return HAL_OK;
841 else
843 return HAL_BUSY;
848 * @brief Receive an amount of data (Data Flow) in non-blocking mode with Interrupt
849 * @param hspdif SPDIFRX handle
850 * @param pData a 32-bit pointer to the Receive data buffer.
851 * @param Size number of data sample to be received .
852 * @retval HAL status
854 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
856 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
858 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
860 if((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
862 if((pData == NULL) || (Size == 0U))
864 return HAL_ERROR;
867 /* Process Locked */
868 __HAL_LOCK(hspdif);
870 hspdif->pRxBuffPtr = pData;
871 hspdif->RxXferSize = Size;
872 hspdif->RxXferCount = Size;
874 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
876 /* Check if a receive process is ongoing or not */
877 hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
879 /* Enable the SPDIFRX PE Error Interrupt */
880 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
882 /* Enable the SPDIFRX OVR Error Interrupt */
883 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
885 /* Enable the SPDIFRX RXNE interrupt */
886 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_RXNE);
888 if((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
890 /* Start synchronization */
891 __HAL_SPDIFRX_SYNC(hspdif);
893 /* Wait until SYNCD flag is set */
896 if (count == 0U)
898 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
899 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
900 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
901 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
902 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
903 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
904 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
905 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
907 hspdif->State= HAL_SPDIFRX_STATE_READY;
909 /* Process Unlocked */
910 __HAL_UNLOCK(hspdif);
912 return HAL_TIMEOUT;
914 count--;
915 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
917 /* Start reception */
918 __HAL_SPDIFRX_RCV(hspdif);
921 /* Process Unlocked */
922 __HAL_UNLOCK(hspdif);
924 return HAL_OK;
926 else
928 return HAL_BUSY;
933 * @brief Receive an amount of data (Control Flow) with Interrupt
934 * @param hspdif SPDIFRX handle
935 * @param pData a 32-bit pointer to the Receive data buffer.
936 * @param Size number of data sample (Control Flow) to be received
937 * @retval HAL status
939 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
941 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
943 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
945 if((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
947 if((pData == NULL ) || (Size == 0U))
949 return HAL_ERROR;
952 /* Process Locked */
953 __HAL_LOCK(hspdif);
955 hspdif->pCsBuffPtr = pData;
956 hspdif->CsXferSize = Size;
957 hspdif->CsXferCount = Size;
959 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
961 /* Check if a receive process is ongoing or not */
962 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
964 /* Enable the SPDIFRX PE Error Interrupt */
965 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
967 /* Enable the SPDIFRX OVR Error Interrupt */
968 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
970 /* Enable the SPDIFRX CSRNE interrupt */
971 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
973 if((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
975 /* Start synchronization */
976 __HAL_SPDIFRX_SYNC(hspdif);
978 /* Wait until SYNCD flag is set */
981 if (count == 0U)
983 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
984 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
985 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
986 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
987 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
988 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
989 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
990 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
992 hspdif->State= HAL_SPDIFRX_STATE_READY;
994 /* Process Unlocked */
995 __HAL_UNLOCK(hspdif);
997 return HAL_TIMEOUT;
999 count--;
1000 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1002 /* Start reception */
1003 __HAL_SPDIFRX_RCV(hspdif);
1006 /* Process Unlocked */
1007 __HAL_UNLOCK(hspdif);
1009 return HAL_OK;
1011 else
1013 return HAL_BUSY;
1018 * @brief Receive an amount of data (Data Flow) mode with DMA
1019 * @param hspdif SPDIFRX handle
1020 * @param pData a 32-bit pointer to the Receive data buffer.
1021 * @param Size number of data sample to be received
1022 * @retval HAL status
1024 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1026 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1028 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1030 if((pData == NULL) || (Size == 0U))
1032 return HAL_ERROR;
1035 if((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
1037 /* Process Locked */
1038 __HAL_LOCK(hspdif);
1040 hspdif->pRxBuffPtr = pData;
1041 hspdif->RxXferSize = Size;
1042 hspdif->RxXferCount = Size;
1044 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1045 hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
1047 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1048 hspdif->hdmaDrRx->XferHalfCpltCallback = SPDIFRX_DMARxHalfCplt;
1050 /* Set the SPDIFRX Rx DMA transfer complete callback */
1051 hspdif->hdmaDrRx->XferCpltCallback = SPDIFRX_DMARxCplt;
1053 /* Set the DMA error callback */
1054 hspdif->hdmaDrRx->XferErrorCallback = SPDIFRX_DMAError;
1056 /* Enable the DMA request */
1057 if(HAL_DMA_Start_IT(hspdif->hdmaDrRx, (uint32_t)&hspdif->Instance->DR, (uint32_t)hspdif->pRxBuffPtr, Size) != HAL_OK)
1059 /* Set SPDIFRX error */
1060 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1062 /* Set SPDIFRX state */
1063 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1065 /* Process Unlocked */
1066 __HAL_UNLOCK(hspdif);
1068 return HAL_ERROR;
1071 /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/
1072 hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN;
1074 if((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1076 /* Start synchronization */
1077 __HAL_SPDIFRX_SYNC(hspdif);
1079 /* Wait until SYNCD flag is set */
1082 if (count == 0U)
1084 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1085 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1086 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1087 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1088 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1089 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1090 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1091 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1093 hspdif->State= HAL_SPDIFRX_STATE_READY;
1095 /* Process Unlocked */
1096 __HAL_UNLOCK(hspdif);
1098 return HAL_TIMEOUT;
1100 count--;
1101 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1103 /* Start reception */
1104 __HAL_SPDIFRX_RCV(hspdif);
1107 /* Process Unlocked */
1108 __HAL_UNLOCK(hspdif);
1110 return HAL_OK;
1112 else
1114 return HAL_BUSY;
1119 * @brief Receive an amount of data (Control Flow) with DMA
1120 * @param hspdif SPDIFRX handle
1121 * @param pData a 32-bit pointer to the Receive data buffer.
1122 * @param Size number of data (Control Flow) sample to be received
1123 * @retval HAL status
1125 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveCtrlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1127 uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1129 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1131 if((pData == NULL) || (Size == 0U))
1133 return HAL_ERROR;
1136 if((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
1138 hspdif->pCsBuffPtr = pData;
1139 hspdif->CsXferSize = Size;
1140 hspdif->CsXferCount = Size;
1142 /* Process Locked */
1143 __HAL_LOCK(hspdif);
1145 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1146 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
1148 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1149 hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt;
1151 /* Set the SPDIFRX Rx DMA transfer complete callback */
1152 hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt;
1154 /* Set the DMA error callback */
1155 hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError;
1157 /* Enable the DMA request */
1158 if(HAL_DMA_Start_IT(hspdif->hdmaCsRx, (uint32_t)&hspdif->Instance->CSR, (uint32_t)hspdif->pCsBuffPtr, Size) != HAL_OK)
1160 /* Set SPDIFRX error */
1161 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1163 /* Set SPDIFRX state */
1164 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1166 /* Process Unlocked */
1167 __HAL_UNLOCK(hspdif);
1169 return HAL_ERROR;
1172 /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/
1173 hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN;
1175 if((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1177 /* Start synchronization */
1178 __HAL_SPDIFRX_SYNC(hspdif);
1180 /* Wait until SYNCD flag is set */
1183 if (count == 0U)
1185 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1186 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1187 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1188 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1189 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1190 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1191 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1192 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1194 hspdif->State= HAL_SPDIFRX_STATE_READY;
1196 /* Process Unlocked */
1197 __HAL_UNLOCK(hspdif);
1199 return HAL_TIMEOUT;
1201 count--;
1202 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1204 /* Start reception */
1205 __HAL_SPDIFRX_RCV(hspdif);
1208 /* Process Unlocked */
1209 __HAL_UNLOCK(hspdif);
1211 return HAL_OK;
1213 else
1215 return HAL_BUSY;
1220 * @brief stop the audio stream receive from the Media.
1221 * @param hspdif SPDIFRX handle
1222 * @retval None
1224 HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif)
1226 /* Process Locked */
1227 __HAL_LOCK(hspdif);
1229 /* Disable the SPDIFRX DMA requests */
1230 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1231 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1233 /* Disable the SPDIFRX DMA channel */
1234 __HAL_DMA_DISABLE(hspdif->hdmaDrRx);
1235 __HAL_DMA_DISABLE(hspdif->hdmaCsRx);
1237 /* Disable SPDIFRX peripheral */
1238 __HAL_SPDIFRX_IDLE(hspdif);
1240 hspdif->State = HAL_SPDIFRX_STATE_READY;
1242 /* Process Unlocked */
1243 __HAL_UNLOCK(hspdif);
1245 return HAL_OK;
1249 * @brief This function handles SPDIFRX interrupt request.
1250 * @param hspdif SPDIFRX handle
1251 * @retval HAL status
1253 void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif)
1255 uint32_t itFlag = hspdif->Instance->SR;
1256 uint32_t itSource = hspdif->Instance->IMR;
1258 /* SPDIFRX in mode Data Flow Reception */
1259 if(((itFlag & SPDIFRX_FLAG_RXNE) == SPDIFRX_FLAG_RXNE) && ((itSource & SPDIFRX_IT_RXNE) == SPDIFRX_IT_RXNE))
1261 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE);
1262 SPDIFRX_ReceiveDataFlow_IT(hspdif);
1265 /* SPDIFRX in mode Control Flow Reception */
1266 if(((itFlag & SPDIFRX_FLAG_CSRNE) == SPDIFRX_FLAG_CSRNE) && ((itSource & SPDIFRX_IT_CSRNE) == SPDIFRX_IT_CSRNE))
1268 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE);
1269 SPDIFRX_ReceiveControlFlow_IT(hspdif);
1272 /* SPDIFRX Overrun error interrupt occurred */
1273 if(((itFlag & SPDIFRX_FLAG_OVR) == SPDIFRX_FLAG_OVR) && ((itSource & SPDIFRX_IT_OVRIE) == SPDIFRX_IT_OVRIE))
1275 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_OVRIE);
1277 /* Change the SPDIFRX error code */
1278 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR;
1280 /* the transfer is not stopped */
1281 HAL_SPDIFRX_ErrorCallback(hspdif);
1284 /* SPDIFRX Parity error interrupt occurred */
1285 if(((itFlag & SPDIFRX_FLAG_PERR) == SPDIFRX_FLAG_PERR) && ((itSource & SPDIFRX_IT_PERRIE) == SPDIFRX_IT_PERRIE))
1287 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_PERRIE);
1289 /* Change the SPDIFRX error code */
1290 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE;
1292 /* the transfer is not stopped */
1293 HAL_SPDIFRX_ErrorCallback(hspdif);
1298 * @brief Rx Transfer (Data flow) half completed callbacks
1299 * @param hspdif SPDIFRX handle
1300 * @retval None
1302 __weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1304 /* Prevent unused argument(s) compilation warning */
1305 UNUSED(hspdif);
1307 /* NOTE : This function Should not be modified, when the callback is needed,
1308 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1313 * @brief Rx Transfer (Data flow) completed callbacks
1314 * @param hspdif SPDIFRX handle
1315 * @retval None
1317 __weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1319 /* Prevent unused argument(s) compilation warning */
1320 UNUSED(hspdif);
1322 /* NOTE : This function Should not be modified, when the callback is needed,
1323 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1328 * @brief Rx (Control flow) Transfer half completed callbacks
1329 * @param hspdif SPDIFRX handle
1330 * @retval None
1332 __weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1334 /* Prevent unused argument(s) compilation warning */
1335 UNUSED(hspdif);
1337 /* NOTE : This function Should not be modified, when the callback is needed,
1338 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1343 * @brief Rx Transfer (Control flow) completed callbacks
1344 * @param hspdif SPDIFRX handle
1345 * @retval None
1347 __weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1349 /* Prevent unused argument(s) compilation warning */
1350 UNUSED(hspdif);
1352 /* NOTE : This function Should not be modified, when the callback is needed,
1353 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1358 * @brief SPDIFRX error callbacks
1359 * @param hspdif SPDIFRX handle
1360 * @retval None
1362 __weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif)
1364 /* Prevent unused argument(s) compilation warning */
1365 UNUSED(hspdif);
1367 /* NOTE : This function Should not be modified, when the callback is needed,
1368 the HAL_SPDIFRX_ErrorCallback could be implemented in the user file
1373 * @}
1376 /** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions
1377 * @brief Peripheral State functions
1379 @verbatim
1380 ===============================================================================
1381 ##### Peripheral State and Errors functions #####
1382 ===============================================================================
1383 [..]
1384 This subsection permit to get in run-time the status of the peripheral
1385 and the data flow.
1387 @endverbatim
1388 * @{
1392 * @brief Return the SPDIFRX state
1393 * @param hspdif SPDIFRX handle
1394 * @retval HAL state
1396 HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const * const hspdif)
1398 return hspdif->State;
1402 * @brief Return the SPDIFRX error code
1403 * @param hspdif SPDIFRX handle
1404 * @retval SPDIFRX Error Code
1406 uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const * const hspdif)
1408 return hspdif->ErrorCode;
1412 * @}
1416 * @brief DMA SPDIFRX receive process (Data flow) complete callback
1417 * @param hdma DMA handle
1418 * @retval None
1420 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma)
1422 SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1424 /* Disable Rx DMA Request */
1425 if(hdma->Init.Mode != DMA_CIRCULAR)
1427 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1428 hspdif->RxXferCount = 0;
1429 hspdif->State = HAL_SPDIFRX_STATE_READY;
1431 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1432 hspdif->RxCpltCallback(hspdif);
1433 #else
1434 HAL_SPDIFRX_RxCpltCallback(hspdif);
1435 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1439 * @brief DMA SPDIFRX receive process (Data flow) half complete callback
1440 * @param hdma DMA handle
1441 * @retval None
1443 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1445 SPDIFRX_HandleTypeDef* hspdif = (SPDIFRX_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1447 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1448 hspdif->RxHalfCpltCallback(hspdif);
1449 #else
1450 HAL_SPDIFRX_RxHalfCpltCallback(hspdif);
1451 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1456 * @brief DMA SPDIFRX receive process (Control flow) complete callback
1457 * @param hdma DMA handle
1458 * @retval None
1460 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma)
1462 SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1464 /* Disable Cb DMA Request */
1465 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1466 hspdif->CsXferCount = 0;
1468 hspdif->State = HAL_SPDIFRX_STATE_READY;
1469 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1470 hspdif->CxCpltCallback(hspdif);
1471 #else
1472 HAL_SPDIFRX_CxCpltCallback(hspdif);
1473 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1477 * @brief DMA SPDIFRX receive process (Control flow) half complete callback
1478 * @param hdma DMA handle
1479 * @retval None
1481 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma)
1483 SPDIFRX_HandleTypeDef* hspdif = (SPDIFRX_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1485 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1486 hspdif->CxHalfCpltCallback(hspdif);
1487 #else
1488 HAL_SPDIFRX_CxHalfCpltCallback(hspdif);
1489 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1493 * @brief DMA SPDIFRX communication error callback
1494 * @param hdma DMA handle
1495 * @retval None
1497 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma)
1499 SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1501 /* Disable Rx and Cb DMA Request */
1502 hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN));
1503 hspdif->RxXferCount = 0;
1505 hspdif->State= HAL_SPDIFRX_STATE_READY;
1507 /* Set the error code and execute error callback*/
1508 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA;
1510 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1511 /* The transfer is not stopped */
1512 hspdif->ErrorCallback(hspdif);
1513 #else
1514 /* The transfer is not stopped */
1515 HAL_SPDIFRX_ErrorCallback(hspdif);
1516 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1520 * @brief Receive an amount of data (Data Flow) with Interrupt
1521 * @param hspdif SPDIFRX handle
1522 * @retval None
1524 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1526 /* Receive data */
1527 (*hspdif->pRxBuffPtr) = hspdif->Instance->DR;
1528 hspdif->pRxBuffPtr++;
1529 hspdif->RxXferCount--;
1531 if(hspdif->RxXferCount == 0U)
1533 /* Disable RXNE/PE and OVR interrupts */
1534 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE);
1536 hspdif->State = HAL_SPDIFRX_STATE_READY;
1538 /* Process Unlocked */
1539 __HAL_UNLOCK(hspdif);
1541 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1542 hspdif->RxCpltCallback(hspdif);
1543 #else
1544 HAL_SPDIFRX_RxCpltCallback(hspdif);
1545 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1550 * @brief Receive an amount of data (Control Flow) with Interrupt
1551 * @param hspdif SPDIFRX handle
1552 * @retval None
1554 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1556 /* Receive data */
1557 (*hspdif->pCsBuffPtr) = hspdif->Instance->CSR;
1558 hspdif->pCsBuffPtr++;
1559 hspdif->CsXferCount--;
1561 if(hspdif->CsXferCount == 0U)
1563 /* Disable CSRNE interrupt */
1564 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1566 hspdif->State = HAL_SPDIFRX_STATE_READY;
1568 /* Process Unlocked */
1569 __HAL_UNLOCK(hspdif);
1571 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1572 hspdif->CxCpltCallback(hspdif);
1573 #else
1574 HAL_SPDIFRX_CxCpltCallback(hspdif);
1575 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1580 * @brief This function handles SPDIFRX Communication Timeout.
1581 * @param hspdif SPDIFRX handle
1582 * @param Flag Flag checked
1583 * @param Status Value of the flag expected
1584 * @param Timeout Duration of the timeout
1585 * @param tickstart Tick start value
1586 * @retval HAL status
1588 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t tickstart)
1590 /* Wait until flag is set */
1591 while(__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == Status)
1593 /* Check for the Timeout */
1594 if(Timeout != HAL_MAX_DELAY)
1596 if(((HAL_GetTick() - tickstart ) > Timeout) || (Timeout == 0U))
1598 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1599 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1600 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1601 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1602 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1603 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1604 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1605 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1607 hspdif->State= HAL_SPDIFRX_STATE_READY;
1609 /* Process Unlocked */
1610 __HAL_UNLOCK(hspdif);
1612 return HAL_TIMEOUT;
1617 return HAL_OK;
1621 * @}
1625 #endif /* SPDIFRX */
1626 #endif /* HAL_SPDIFRX_MODULE_ENABLED */
1628 * @}
1632 * @}
1635 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/