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