Updated and Validated
[betaflight.git] / lib / main / STM32F7 / Drivers / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_spdifrx.c
blob15c03ac3f9526b006a9e089406020d37400d6700
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_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_ReceiveControlFlow_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_ReceiveControlFlow_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_ReceiveControlFlow()
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_ReceiveControlFlow_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_ReceiveControlFlow_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 "stm32f7xx_hal.h"
162 /** @addtogroup STM32F7xx_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));
258 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
259 if(hspdif->State == HAL_SPDIFRX_STATE_RESET)
261 /* Allocate lock resource and initialize it */
262 hspdif->Lock = HAL_UNLOCKED;
264 hspdif->RxHalfCpltCallback = HAL_SPDIFRX_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
265 hspdif->RxCpltCallback = HAL_SPDIFRX_RxCpltCallback; /* Legacy weak RxCpltCallback */
266 hspdif->CxHalfCpltCallback = HAL_SPDIFRX_CxHalfCpltCallback; /* Legacy weak CxHalfCpltCallback */
267 hspdif->CxCpltCallback = HAL_SPDIFRX_CxCpltCallback; /* Legacy weak CxCpltCallback */
268 hspdif->ErrorCallback = HAL_SPDIFRX_ErrorCallback; /* Legacy weak ErrorCallback */
270 if(hspdif->MspInitCallback == NULL)
272 hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit */
275 /* Init the low level hardware */
276 hspdif->MspInitCallback(hspdif);
278 #else
279 if(hspdif->State == HAL_SPDIFRX_STATE_RESET)
281 /* Allocate lock resource and initialize it */
282 hspdif->Lock = HAL_UNLOCKED;
283 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
284 HAL_SPDIFRX_MspInit(hspdif);
286 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
288 /* SPDIFRX peripheral state is BUSY */
289 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
291 /* Disable SPDIFRX interface (IDLE State) */
292 __HAL_SPDIFRX_IDLE(hspdif);
294 /* Reset the old SPDIFRX CR configuration */
295 tmpreg = hspdif->Instance->CR;
297 tmpreg &= ~(SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
298 SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK |
299 SPDIFRX_CR_CHSEL | SPDIFRX_CR_NBTR | SPDIFRX_CR_WFA |
300 SPDIFRX_CR_INSEL);
302 /* Sets the new configuration of the SPDIFRX peripheral */
303 tmpreg |= (hspdif->Init.StereoMode |
304 hspdif->Init.InputSelection |
305 hspdif->Init.Retries |
306 hspdif->Init.WaitForActivity |
307 hspdif->Init.ChannelSelection |
308 hspdif->Init.DataFormat |
309 hspdif->Init.PreambleTypeMask |
310 hspdif->Init.ChannelStatusMask |
311 hspdif->Init.ValidityBitMask |
312 hspdif->Init.ParityErrorMask
316 hspdif->Instance->CR = tmpreg;
318 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
320 /* SPDIFRX peripheral state is READY*/
321 hspdif->State = HAL_SPDIFRX_STATE_READY;
323 return HAL_OK;
327 * @brief DeInitializes the SPDIFRX peripheral
328 * @param hspdif SPDIFRX handle
329 * @retval HAL status
331 HAL_StatusTypeDef HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef *hspdif)
333 /* Check the SPDIFRX handle allocation */
334 if(hspdif == NULL)
336 return HAL_ERROR;
339 /* Check the parameters */
340 assert_param(IS_SPDIFRX_ALL_INSTANCE(hspdif->Instance));
342 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
344 /* Disable SPDIFRX interface (IDLE state) */
345 __HAL_SPDIFRX_IDLE(hspdif);
347 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
348 if(hspdif->MspDeInitCallback == NULL)
350 hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspDeInit */
353 /* DeInit the low level hardware */
354 hspdif->MspDeInitCallback(hspdif);
355 #else
356 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
357 HAL_SPDIFRX_MspDeInit(hspdif);
358 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
360 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
362 /* SPDIFRX peripheral state is RESET*/
363 hspdif->State = HAL_SPDIFRX_STATE_RESET;
365 /* Release Lock */
366 __HAL_UNLOCK(hspdif);
368 return HAL_OK;
372 * @brief SPDIFRX MSP Init
373 * @param hspdif SPDIFRX handle
374 * @retval None
376 __weak void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif)
378 /* Prevent unused argument(s) compilation warning */
379 UNUSED(hspdif);
381 /* NOTE : This function Should not be modified, when the callback is needed,
382 the HAL_SPDIFRX_MspInit could be implemented in the user file
387 * @brief SPDIFRX MSP DeInit
388 * @param hspdif SPDIFRX handle
389 * @retval None
391 __weak void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif)
393 /* Prevent unused argument(s) compilation warning */
394 UNUSED(hspdif);
396 /* NOTE : This function Should not be modified, when the callback is needed,
397 the HAL_SPDIFRX_MspDeInit could be implemented in the user file
401 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
403 * @brief Register a User SPDIFRX Callback
404 * To be used instead of the weak predefined callback
405 * @param hspdif SPDIFRX handle
406 * @param CallbackID ID of the callback to be registered
407 * This parameter can be one of the following values:
408 * @arg @ref HAL_SPDIFRX_RX_HALF_CB_ID SPDIFRX Data flow half completed callback ID
409 * @arg @ref HAL_SPDIFRX_RX_CPLT_CB_ID SPDIFRX Data flow completed callback ID
410 * @arg @ref HAL_SPDIFRX_CX_HALF_CB_ID SPDIFRX Control flow half completed callback ID
411 * @arg @ref HAL_SPDIFRX_CX_CPLT_CB_ID SPDIFRX Control flow completed callback ID
412 * @arg @ref HAL_SPDIFRX_ERROR_CB_ID SPDIFRX error callback ID
413 * @arg @ref HAL_SPDIFRX_MSPINIT_CB_ID MspInit callback ID
414 * @arg @ref HAL_SPDIFRX_MSPDEINIT_CB_ID MspDeInit callback ID
415 * @param pCallback pointer to the Callback function
416 * @retval HAL status
418 HAL_StatusTypeDef HAL_SPDIFRX_RegisterCallback(SPDIFRX_HandleTypeDef *hspdif, HAL_SPDIFRX_CallbackIDTypeDef CallbackID, pSPDIFRX_CallbackTypeDef pCallback)
420 HAL_StatusTypeDef status = HAL_OK;
422 if(pCallback == NULL)
424 /* Update the error code */
425 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
426 return HAL_ERROR;
428 /* Process locked */
429 __HAL_LOCK(hspdif);
431 if(HAL_SPDIFRX_STATE_READY == hspdif->State)
433 switch (CallbackID)
435 case HAL_SPDIFRX_RX_HALF_CB_ID :
436 hspdif->RxHalfCpltCallback = pCallback;
437 break;
439 case HAL_SPDIFRX_RX_CPLT_CB_ID :
440 hspdif->RxCpltCallback = pCallback;
441 break;
443 case HAL_SPDIFRX_CX_HALF_CB_ID :
444 hspdif->CxHalfCpltCallback = pCallback;
445 break;
447 case HAL_SPDIFRX_CX_CPLT_CB_ID :
448 hspdif->CxCpltCallback = pCallback;
449 break;
451 case HAL_SPDIFRX_ERROR_CB_ID :
452 hspdif->ErrorCallback = pCallback;
453 break;
455 case HAL_SPDIFRX_MSPINIT_CB_ID :
456 hspdif->MspInitCallback = pCallback;
457 break;
459 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
460 hspdif->MspDeInitCallback = pCallback;
461 break;
463 default :
464 /* Update the error code */
465 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
466 /* Return error status */
467 status = HAL_ERROR;
468 break;
471 else if(HAL_SPDIFRX_STATE_RESET == hspdif->State)
473 switch (CallbackID)
475 case HAL_SPDIFRX_MSPINIT_CB_ID :
476 hspdif->MspInitCallback = pCallback;
477 break;
479 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
480 hspdif->MspDeInitCallback = pCallback;
481 break;
483 default :
484 /* Update the error code */
485 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
486 /* Return error status */
487 status = HAL_ERROR;
488 break;
491 else
493 /* Update the error code */
494 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
495 /* Return error status */
496 status = HAL_ERROR;
499 /* Release Lock */
500 __HAL_UNLOCK(hspdif);
501 return status;
505 * @brief Unregister a SPDIFRX Callback
506 * SPDIFRX callabck is redirected to the weak predefined callback
507 * @param hspdif SPDIFRX handle
508 * @param CallbackID ID of the callback to be unregistered
509 * This parameter can be one of the following values:
510 * @arg @ref HAL_SPDIFRX_RX_HALF_CB_ID SPDIFRX Data flow half completed callback ID
511 * @arg @ref HAL_SPDIFRX_RX_CPLT_CB_ID SPDIFRX Data flow completed callback ID
512 * @arg @ref HAL_SPDIFRX_CX_HALF_CB_ID SPDIFRX Control flow half completed callback ID
513 * @arg @ref HAL_SPDIFRX_CX_CPLT_CB_ID SPDIFRX Control flow completed callback ID
514 * @arg @ref HAL_SPDIFRX_ERROR_CB_ID SPDIFRX error callback ID
515 * @arg @ref HAL_SPDIFRX_MSPINIT_CB_ID MspInit callback ID
516 * @arg @ref HAL_SPDIFRX_MSPDEINIT_CB_ID MspDeInit callback ID
517 * @retval HAL status
519 HAL_StatusTypeDef HAL_SPDIFRX_UnRegisterCallback(SPDIFRX_HandleTypeDef *hspdif, HAL_SPDIFRX_CallbackIDTypeDef CallbackID)
521 HAL_StatusTypeDef status = HAL_OK;
523 /* Process locked */
524 __HAL_LOCK(hspdif);
526 if(HAL_SPDIFRX_STATE_READY == hspdif->State)
528 switch (CallbackID)
530 case HAL_SPDIFRX_RX_HALF_CB_ID :
531 hspdif->RxHalfCpltCallback = HAL_SPDIFRX_RxHalfCpltCallback;
532 break;
534 case HAL_SPDIFRX_RX_CPLT_CB_ID :
535 hspdif->RxCpltCallback = HAL_SPDIFRX_RxCpltCallback;
536 break;
538 case HAL_SPDIFRX_CX_HALF_CB_ID :
539 hspdif->CxHalfCpltCallback = HAL_SPDIFRX_CxHalfCpltCallback;
540 break;
542 case HAL_SPDIFRX_CX_CPLT_CB_ID :
543 hspdif->CxCpltCallback = HAL_SPDIFRX_CxCpltCallback;
544 break;
546 case HAL_SPDIFRX_ERROR_CB_ID :
547 hspdif->ErrorCallback = HAL_SPDIFRX_ErrorCallback;
548 break;
550 default :
551 /* Update the error code */
552 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
553 /* Return error status */
554 status = HAL_ERROR;
555 break;
558 else if(HAL_SPDIFRX_STATE_RESET == hspdif->State)
560 switch (CallbackID)
562 case HAL_SPDIFRX_MSPINIT_CB_ID :
563 hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit */
564 break;
566 case HAL_SPDIFRX_MSPDEINIT_CB_ID :
567 hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspInit */
568 break;
570 default :
571 /* Update the error code */
572 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
573 /* Return error status */
574 status = HAL_ERROR;
575 break;
578 else
580 /* Update the error code */
581 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
582 /* Return error status */
583 status = HAL_ERROR;
586 /* Release Lock */
587 __HAL_UNLOCK(hspdif);
588 return status;
591 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
594 * @brief Set the SPDIFRX data format according to the specified parameters in the SPDIFRX_InitTypeDef.
595 * @param hspdif SPDIFRX handle
596 * @param sDataFormat SPDIFRX data format
597 * @retval HAL status
599 HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef sDataFormat)
601 uint32_t tmpreg;
603 /* Check the SPDIFRX handle allocation */
604 if(hspdif == NULL)
606 return HAL_ERROR;
609 /* Check the SPDIFRX parameters */
610 assert_param(IS_STEREO_MODE(sDataFormat.StereoMode));
611 assert_param(IS_SPDIFRX_DATA_FORMAT(sDataFormat.DataFormat));
612 assert_param(IS_PREAMBLE_TYPE_MASK(sDataFormat.PreambleTypeMask));
613 assert_param(IS_CHANNEL_STATUS_MASK(sDataFormat.ChannelStatusMask));
614 assert_param(IS_VALIDITY_MASK(sDataFormat.ValidityBitMask));
615 assert_param(IS_PARITY_ERROR_MASK(sDataFormat.ParityErrorMask));
617 /* Reset the old SPDIFRX CR configuration */
618 tmpreg = hspdif->Instance->CR;
620 if(((tmpreg & SPDIFRX_STATE_RCV) == SPDIFRX_STATE_RCV) &&
621 (((tmpreg & SPDIFRX_CR_DRFMT) != sDataFormat.DataFormat) ||
622 ((tmpreg & SPDIFRX_CR_RXSTEO) != sDataFormat.StereoMode)))
624 return HAL_ERROR;
627 tmpreg &= ~(SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
628 SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK);
630 /* Configure the new data format */
631 tmpreg |= (sDataFormat.StereoMode |
632 sDataFormat.DataFormat |
633 sDataFormat.PreambleTypeMask |
634 sDataFormat.ChannelStatusMask |
635 sDataFormat.ValidityBitMask |
636 sDataFormat.ParityErrorMask);
638 hspdif->Instance->CR = tmpreg;
640 return HAL_OK;
644 * @}
647 /** @defgroup SPDIFRX_Exported_Functions_Group2 IO operation functions
648 * @brief Data transfers functions
650 @verbatim
651 ===============================================================================
652 ##### IO operation functions #####
653 ===============================================================================
654 [..]
655 This subsection provides a set of functions allowing to manage the SPDIFRX data
656 transfers.
658 (#) There is two mode of transfer:
659 (++) Blocking mode : The communication is performed in the polling mode.
660 The status of all data processing is returned by the same function
661 after finishing transfer.
662 (++) No-Blocking mode : The communication is performed using Interrupts
663 or DMA. These functions return the status of the transfer start-up.
664 The end of the data processing will be indicated through the
665 dedicated SPDIFRX IRQ when using Interrupt mode or the DMA IRQ when
666 using DMA mode.
668 (#) Blocking mode functions are :
669 (++) HAL_SPDIFRX_ReceiveDataFlow()
670 (++) HAL_SPDIFRX_ReceiveControlFlow()
671 (+@) Do not use blocking mode to receive both control and data flow at the same time.
673 (#) No-Blocking mode functions with Interrupt are :
674 (++) HAL_SPDIFRX_ReceiveControlFlow_IT()
675 (++) HAL_SPDIFRX_ReceiveDataFlow_IT()
677 (#) No-Blocking mode functions with DMA are :
678 (++) HAL_SPDIFRX_ReceiveControlFlow_DMA()
679 (++) HAL_SPDIFRX_ReceiveDataFlow_DMA()
681 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
682 (++) HAL_SPDIFRX_RxCpltCallback()
683 (++) HAL_SPDIFRX_CxCpltCallback()
685 @endverbatim
686 * @{
690 * @brief Receives an amount of data (Data Flow) in blocking mode.
691 * @param hspdif pointer to SPDIFRX_HandleTypeDef structure that contains
692 * the configuration information for SPDIFRX module.
693 * @param pData Pointer to data buffer
694 * @param Size Amount of data to be received
695 * @param Timeout Timeout duration
696 * @retval HAL status
698 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout)
700 uint32_t tickstart;
701 uint16_t sizeCounter = Size;
702 uint32_t *pTmpBuf = pData;
704 if((pData == NULL ) || (Size == 0U))
706 return HAL_ERROR;
709 if(hspdif->State == HAL_SPDIFRX_STATE_READY)
711 /* Process Locked */
712 __HAL_LOCK(hspdif);
714 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
716 /* Start synchronisation */
717 __HAL_SPDIFRX_SYNC(hspdif);
719 /* Get tick */
720 tickstart = HAL_GetTick();
722 /* Wait until SYNCD flag is set */
723 if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
725 return HAL_TIMEOUT;
728 /* Start reception */
729 __HAL_SPDIFRX_RCV(hspdif);
731 /* Receive data flow */
732 while(sizeCounter > 0U)
734 /* Get tick */
735 tickstart = HAL_GetTick();
737 /* Wait until RXNE flag is set */
738 if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
740 return HAL_TIMEOUT;
743 (*pTmpBuf) = hspdif->Instance->DR;
744 pTmpBuf++;
745 sizeCounter--;
748 /* SPDIFRX ready */
749 hspdif->State = HAL_SPDIFRX_STATE_READY;
751 /* Process Unlocked */
752 __HAL_UNLOCK(hspdif);
754 return HAL_OK;
756 else
758 return HAL_BUSY;
763 * @brief Receives an amount of data (Control Flow) in blocking mode.
764 * @param hspdif pointer to a SPDIFRX_HandleTypeDef structure that contains
765 * the configuration information for SPDIFRX module.
766 * @param pData Pointer to data buffer
767 * @param Size Amount of data to be received
768 * @param Timeout Timeout duration
769 * @retval HAL status
771 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout)
773 uint32_t tickstart;
774 uint16_t sizeCounter = Size;
775 uint32_t *pTmpBuf = pData;
777 if((pData == NULL ) || (Size == 0U))
779 return HAL_ERROR;
782 if(hspdif->State == HAL_SPDIFRX_STATE_READY)
784 /* Process Locked */
785 __HAL_LOCK(hspdif);
787 hspdif->State = HAL_SPDIFRX_STATE_BUSY;
789 /* Start synchronization */
790 __HAL_SPDIFRX_SYNC(hspdif);
792 /* Get tick */
793 tickstart = HAL_GetTick();
795 /* Wait until SYNCD flag is set */
796 if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
798 return HAL_TIMEOUT;
801 /* Start reception */
802 __HAL_SPDIFRX_RCV(hspdif);
804 /* Receive control flow */
805 while(sizeCounter > 0U)
807 /* Get tick */
808 tickstart = HAL_GetTick();
810 /* Wait until CSRNE flag is set */
811 if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_CSRNE, RESET, Timeout, tickstart) != HAL_OK)
813 return HAL_TIMEOUT;
816 (*pTmpBuf) = hspdif->Instance->CSR;
817 pTmpBuf++;
818 sizeCounter--;
821 /* SPDIFRX ready */
822 hspdif->State = HAL_SPDIFRX_STATE_READY;
824 /* Process Unlocked */
825 __HAL_UNLOCK(hspdif);
827 return HAL_OK;
829 else
831 return HAL_BUSY;
836 * @brief Receive an amount of data (Data Flow) in non-blocking mode with Interrupt
837 * @param hspdif SPDIFRX handle
838 * @param pData a 32-bit pointer to the Receive data buffer.
839 * @param Size number of data sample to be received .
840 * @retval HAL status
842 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
844 register uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
846 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
848 if((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
850 if((pData == NULL) || (Size == 0U))
852 return HAL_ERROR;
855 /* Process Locked */
856 __HAL_LOCK(hspdif);
858 hspdif->pRxBuffPtr = pData;
859 hspdif->RxXferSize = Size;
860 hspdif->RxXferCount = Size;
862 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
864 /* Check if a receive process is ongoing or not */
865 hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
867 /* Enable the SPDIFRX PE Error Interrupt */
868 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
870 /* Enable the SPDIFRX OVR Error Interrupt */
871 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
873 /* Enable the SPDIFRX RXNE interrupt */
874 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_RXNE);
876 if((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
878 /* Start synchronization */
879 __HAL_SPDIFRX_SYNC(hspdif);
881 /* Wait until SYNCD flag is set */
884 if (count == 0U)
886 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
887 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
888 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
889 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
890 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
891 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
892 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
893 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
895 hspdif->State= HAL_SPDIFRX_STATE_READY;
897 /* Process Unlocked */
898 __HAL_UNLOCK(hspdif);
900 return HAL_TIMEOUT;
902 count--;
903 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
905 /* Start reception */
906 __HAL_SPDIFRX_RCV(hspdif);
909 /* Process Unlocked */
910 __HAL_UNLOCK(hspdif);
912 return HAL_OK;
914 else
916 return HAL_BUSY;
921 * @brief Receive an amount of data (Control Flow) with Interrupt
922 * @param hspdif SPDIFRX handle
923 * @param pData a 32-bit pointer to the Receive data buffer.
924 * @param Size number of data sample (Control Flow) to be received
925 * @retval HAL status
927 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
929 register uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
931 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
933 if((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
935 if((pData == NULL ) || (Size == 0U))
937 return HAL_ERROR;
940 /* Process Locked */
941 __HAL_LOCK(hspdif);
943 hspdif->pCsBuffPtr = pData;
944 hspdif->CsXferSize = Size;
945 hspdif->CsXferCount = Size;
947 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
949 /* Check if a receive process is ongoing or not */
950 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
952 /* Enable the SPDIFRX PE Error Interrupt */
953 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
955 /* Enable the SPDIFRX OVR Error Interrupt */
956 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
958 /* Enable the SPDIFRX CSRNE interrupt */
959 __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
961 if((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
963 /* Start synchronization */
964 __HAL_SPDIFRX_SYNC(hspdif);
966 /* Wait until SYNCD flag is set */
969 if (count == 0U)
971 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
972 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
973 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
974 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
975 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
976 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
977 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
978 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
980 hspdif->State= HAL_SPDIFRX_STATE_READY;
982 /* Process Unlocked */
983 __HAL_UNLOCK(hspdif);
985 return HAL_TIMEOUT;
987 count--;
988 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
990 /* Start reception */
991 __HAL_SPDIFRX_RCV(hspdif);
994 /* Process Unlocked */
995 __HAL_UNLOCK(hspdif);
997 return HAL_OK;
999 else
1001 return HAL_BUSY;
1006 * @brief Receive an amount of data (Data Flow) mode with DMA
1007 * @param hspdif SPDIFRX handle
1008 * @param pData a 32-bit pointer to the Receive data buffer.
1009 * @param Size number of data sample to be received
1010 * @retval HAL status
1012 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1014 register uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1016 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1018 if((pData == NULL) || (Size == 0U))
1020 return HAL_ERROR;
1023 if((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
1025 /* Process Locked */
1026 __HAL_LOCK(hspdif);
1028 hspdif->pRxBuffPtr = pData;
1029 hspdif->RxXferSize = Size;
1030 hspdif->RxXferCount = Size;
1032 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1033 hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
1035 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1036 hspdif->hdmaDrRx->XferHalfCpltCallback = SPDIFRX_DMARxHalfCplt;
1038 /* Set the SPDIFRX Rx DMA transfer complete callback */
1039 hspdif->hdmaDrRx->XferCpltCallback = SPDIFRX_DMARxCplt;
1041 /* Set the DMA error callback */
1042 hspdif->hdmaDrRx->XferErrorCallback = SPDIFRX_DMAError;
1044 /* Enable the DMA request */
1045 if(HAL_DMA_Start_IT(hspdif->hdmaDrRx, (uint32_t)&hspdif->Instance->DR, (uint32_t)hspdif->pRxBuffPtr, Size) != HAL_OK)
1047 /* Set SPDIFRX error */
1048 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1050 /* Set SPDIFRX state */
1051 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1053 /* Process Unlocked */
1054 __HAL_UNLOCK(hspdif);
1056 return HAL_ERROR;
1059 /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/
1060 hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN;
1062 if((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1064 /* Start synchronization */
1065 __HAL_SPDIFRX_SYNC(hspdif);
1067 /* Wait until SYNCD flag is set */
1070 if (count == 0U)
1072 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1073 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1074 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1075 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1076 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1077 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1078 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1079 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1081 hspdif->State= HAL_SPDIFRX_STATE_READY;
1083 /* Process Unlocked */
1084 __HAL_UNLOCK(hspdif);
1086 return HAL_TIMEOUT;
1088 count--;
1089 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1091 /* Start reception */
1092 __HAL_SPDIFRX_RCV(hspdif);
1095 /* Process Unlocked */
1096 __HAL_UNLOCK(hspdif);
1098 return HAL_OK;
1100 else
1102 return HAL_BUSY;
1107 * @brief Receive an amount of data (Control Flow) with DMA
1108 * @param hspdif SPDIFRX handle
1109 * @param pData a 32-bit pointer to the Receive data buffer.
1110 * @param Size number of data (Control Flow) sample to be received
1111 * @retval HAL status
1113 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1115 register uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1117 const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1119 if((pData == NULL) || (Size == 0U))
1121 return HAL_ERROR;
1124 if((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
1126 hspdif->pCsBuffPtr = pData;
1127 hspdif->CsXferSize = Size;
1128 hspdif->CsXferCount = Size;
1130 /* Process Locked */
1131 __HAL_LOCK(hspdif);
1133 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1134 hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
1136 /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1137 hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt;
1139 /* Set the SPDIFRX Rx DMA transfer complete callback */
1140 hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt;
1142 /* Set the DMA error callback */
1143 hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError;
1145 /* Enable the DMA request */
1146 if(HAL_DMA_Start_IT(hspdif->hdmaCsRx, (uint32_t)&hspdif->Instance->CSR, (uint32_t)hspdif->pCsBuffPtr, Size) != HAL_OK)
1148 /* Set SPDIFRX error */
1149 hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1151 /* Set SPDIFRX state */
1152 hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1154 /* Process Unlocked */
1155 __HAL_UNLOCK(hspdif);
1157 return HAL_ERROR;
1160 /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/
1161 hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN;
1163 if((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1165 /* Start synchronization */
1166 __HAL_SPDIFRX_SYNC(hspdif);
1168 /* Wait until SYNCD flag is set */
1171 if (count == 0U)
1173 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1174 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1175 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1176 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1177 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1178 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1179 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1180 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1182 hspdif->State= HAL_SPDIFRX_STATE_READY;
1184 /* Process Unlocked */
1185 __HAL_UNLOCK(hspdif);
1187 return HAL_TIMEOUT;
1189 count--;
1190 } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1192 /* Start reception */
1193 __HAL_SPDIFRX_RCV(hspdif);
1196 /* Process Unlocked */
1197 __HAL_UNLOCK(hspdif);
1199 return HAL_OK;
1201 else
1203 return HAL_BUSY;
1208 * @brief stop the audio stream receive from the Media.
1209 * @param hspdif SPDIFRX handle
1210 * @retval None
1212 HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif)
1214 /* Process Locked */
1215 __HAL_LOCK(hspdif);
1217 /* Disable the SPDIFRX DMA requests */
1218 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1219 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1221 /* Disable the SPDIFRX DMA channel */
1222 __HAL_DMA_DISABLE(hspdif->hdmaDrRx);
1223 __HAL_DMA_DISABLE(hspdif->hdmaCsRx);
1225 /* Disable SPDIFRX peripheral */
1226 __HAL_SPDIFRX_IDLE(hspdif);
1228 hspdif->State = HAL_SPDIFRX_STATE_READY;
1230 /* Process Unlocked */
1231 __HAL_UNLOCK(hspdif);
1233 return HAL_OK;
1237 * @brief This function handles SPDIFRX interrupt request.
1238 * @param hspdif SPDIFRX handle
1239 * @retval HAL status
1241 void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif)
1243 uint32_t itFlag = hspdif->Instance->SR;
1244 uint32_t itSource = hspdif->Instance->IMR;
1246 /* SPDIFRX in mode Data Flow Reception */
1247 if(((itFlag & SPDIFRX_FLAG_RXNE) == SPDIFRX_FLAG_RXNE) && ((itSource & SPDIFRX_IT_RXNE) == SPDIFRX_IT_RXNE))
1249 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE);
1250 SPDIFRX_ReceiveDataFlow_IT(hspdif);
1253 /* SPDIFRX in mode Control Flow Reception */
1254 if(((itFlag & SPDIFRX_FLAG_CSRNE) == SPDIFRX_FLAG_CSRNE) && ((itSource & SPDIFRX_IT_CSRNE) == SPDIFRX_IT_CSRNE))
1256 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE);
1257 SPDIFRX_ReceiveControlFlow_IT(hspdif);
1260 /* SPDIFRX Overrun error interrupt occurred */
1261 if(((itFlag & SPDIFRX_FLAG_OVR) == SPDIFRX_FLAG_OVR) && ((itSource & SPDIFRX_IT_OVRIE) == SPDIFRX_IT_OVRIE))
1263 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_OVRIE);
1265 /* Change the SPDIFRX error code */
1266 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR;
1268 /* the transfer is not stopped */
1269 HAL_SPDIFRX_ErrorCallback(hspdif);
1272 /* SPDIFRX Parity error interrupt occurred */
1273 if(((itFlag & SPDIFRX_FLAG_PERR) == SPDIFRX_FLAG_PERR) && ((itSource & SPDIFRX_IT_PERRIE) == SPDIFRX_IT_PERRIE))
1275 __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_PERRIE);
1277 /* Change the SPDIFRX error code */
1278 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE;
1280 /* the transfer is not stopped */
1281 HAL_SPDIFRX_ErrorCallback(hspdif);
1286 * @brief Rx Transfer (Data flow) half completed callbacks
1287 * @param hspdif SPDIFRX handle
1288 * @retval None
1290 __weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1292 /* Prevent unused argument(s) compilation warning */
1293 UNUSED(hspdif);
1295 /* NOTE : This function Should not be modified, when the callback is needed,
1296 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1301 * @brief Rx Transfer (Data flow) completed callbacks
1302 * @param hspdif SPDIFRX handle
1303 * @retval None
1305 __weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1307 /* Prevent unused argument(s) compilation warning */
1308 UNUSED(hspdif);
1310 /* NOTE : This function Should not be modified, when the callback is needed,
1311 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1316 * @brief Rx (Control flow) Transfer half completed callbacks
1317 * @param hspdif SPDIFRX handle
1318 * @retval None
1320 __weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1322 /* Prevent unused argument(s) compilation warning */
1323 UNUSED(hspdif);
1325 /* NOTE : This function Should not be modified, when the callback is needed,
1326 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1331 * @brief Rx Transfer (Control flow) completed callbacks
1332 * @param hspdif SPDIFRX handle
1333 * @retval None
1335 __weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1337 /* Prevent unused argument(s) compilation warning */
1338 UNUSED(hspdif);
1340 /* NOTE : This function Should not be modified, when the callback is needed,
1341 the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1346 * @brief SPDIFRX error callbacks
1347 * @param hspdif SPDIFRX handle
1348 * @retval None
1350 __weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif)
1352 /* Prevent unused argument(s) compilation warning */
1353 UNUSED(hspdif);
1355 /* NOTE : This function Should not be modified, when the callback is needed,
1356 the HAL_SPDIFRX_ErrorCallback could be implemented in the user file
1361 * @}
1364 /** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions
1365 * @brief Peripheral State functions
1367 @verbatim
1368 ===============================================================================
1369 ##### Peripheral State and Errors functions #####
1370 ===============================================================================
1371 [..]
1372 This subsection permit to get in run-time the status of the peripheral
1373 and the data flow.
1375 @endverbatim
1376 * @{
1380 * @brief Return the SPDIFRX state
1381 * @param hspdif SPDIFRX handle
1382 * @retval HAL state
1384 HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const * const hspdif)
1386 return hspdif->State;
1390 * @brief Return the SPDIFRX error code
1391 * @param hspdif SPDIFRX handle
1392 * @retval SPDIFRX Error Code
1394 uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const * const hspdif)
1396 return hspdif->ErrorCode;
1400 * @}
1404 * @brief DMA SPDIFRX receive process (Data flow) complete callback
1405 * @param hdma DMA handle
1406 * @retval None
1408 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma)
1410 SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1412 /* Disable Rx DMA Request */
1413 if(hdma->Init.Mode != DMA_CIRCULAR)
1415 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1416 hspdif->RxXferCount = 0;
1417 hspdif->State = HAL_SPDIFRX_STATE_READY;
1419 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1420 hspdif->RxCpltCallback(hspdif);
1421 #else
1422 HAL_SPDIFRX_RxCpltCallback(hspdif);
1423 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1427 * @brief DMA SPDIFRX receive process (Data flow) half complete callback
1428 * @param hdma DMA handle
1429 * @retval None
1431 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1433 SPDIFRX_HandleTypeDef* hspdif = (SPDIFRX_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1435 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1436 hspdif->RxHalfCpltCallback(hspdif);
1437 #else
1438 HAL_SPDIFRX_RxHalfCpltCallback(hspdif);
1439 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1444 * @brief DMA SPDIFRX receive process (Control flow) complete callback
1445 * @param hdma DMA handle
1446 * @retval None
1448 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma)
1450 SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1452 /* Disable Cb DMA Request */
1453 hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1454 hspdif->CsXferCount = 0;
1456 hspdif->State = HAL_SPDIFRX_STATE_READY;
1457 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1458 hspdif->CxCpltCallback(hspdif);
1459 #else
1460 HAL_SPDIFRX_CxCpltCallback(hspdif);
1461 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1465 * @brief DMA SPDIFRX receive process (Control flow) half complete callback
1466 * @param hdma DMA handle
1467 * @retval None
1469 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma)
1471 SPDIFRX_HandleTypeDef* hspdif = (SPDIFRX_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1473 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1474 hspdif->CxHalfCpltCallback(hspdif);
1475 #else
1476 HAL_SPDIFRX_CxHalfCpltCallback(hspdif);
1477 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1481 * @brief DMA SPDIFRX communication error callback
1482 * @param hdma DMA handle
1483 * @retval None
1485 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma)
1487 SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1489 /* Disable Rx and Cb DMA Request */
1490 hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN));
1491 hspdif->RxXferCount = 0;
1493 hspdif->State= HAL_SPDIFRX_STATE_READY;
1495 /* Set the error code and execute error callback*/
1496 hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA;
1498 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1499 /* The transfer is not stopped */
1500 hspdif->ErrorCallback(hspdif);
1501 #else
1502 /* The transfer is not stopped */
1503 HAL_SPDIFRX_ErrorCallback(hspdif);
1504 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1508 * @brief Receive an amount of data (Data Flow) with Interrupt
1509 * @param hspdif SPDIFRX handle
1510 * @retval None
1512 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1514 /* Receive data */
1515 (*hspdif->pRxBuffPtr) = hspdif->Instance->DR;
1516 hspdif->pRxBuffPtr++;
1517 hspdif->RxXferCount--;
1519 if(hspdif->RxXferCount == 0U)
1521 /* Disable RXNE/PE and OVR interrupts */
1522 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE);
1524 hspdif->State = HAL_SPDIFRX_STATE_READY;
1526 /* Process Unlocked */
1527 __HAL_UNLOCK(hspdif);
1529 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1530 hspdif->RxCpltCallback(hspdif);
1531 #else
1532 HAL_SPDIFRX_RxCpltCallback(hspdif);
1533 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1538 * @brief Receive an amount of data (Control Flow) with Interrupt
1539 * @param hspdif SPDIFRX handle
1540 * @retval None
1542 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1544 /* Receive data */
1545 (*hspdif->pCsBuffPtr) = hspdif->Instance->CSR;
1546 hspdif->pCsBuffPtr++;
1547 hspdif->CsXferCount--;
1549 if(hspdif->CsXferCount == 0U)
1551 /* Disable CSRNE interrupt */
1552 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1554 hspdif->State = HAL_SPDIFRX_STATE_READY;
1556 /* Process Unlocked */
1557 __HAL_UNLOCK(hspdif);
1559 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1560 hspdif->CxCpltCallback(hspdif);
1561 #else
1562 HAL_SPDIFRX_CxCpltCallback(hspdif);
1563 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1568 * @brief This function handles SPDIFRX Communication Timeout.
1569 * @param hspdif SPDIFRX handle
1570 * @param Flag Flag checked
1571 * @param Status Value of the flag expected
1572 * @param Timeout Duration of the timeout
1573 * @param tickstart Tick start value
1574 * @retval HAL status
1576 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t tickstart)
1578 /* Wait until flag is set */
1579 while(__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == Status)
1581 /* Check for the Timeout */
1582 if(Timeout != HAL_MAX_DELAY)
1584 if(((HAL_GetTick() - tickstart ) > Timeout) || (Timeout == 0U))
1586 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1587 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1588 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1589 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1590 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1591 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1592 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1593 __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1595 hspdif->State= HAL_SPDIFRX_STATE_READY;
1597 /* Process Unlocked */
1598 __HAL_UNLOCK(hspdif);
1600 return HAL_TIMEOUT;
1605 return HAL_OK;
1609 * @}
1613 #endif /* SPDIFRX */
1614 #endif /* HAL_SPDIFRX_MODULE_ENABLED */
1616 * @}
1620 * @}
1623 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/