1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_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) 2016 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_ReceiveControlFlow_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_ReceiveControlFlow_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_ReceiveControlFlow()
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_ReceiveControlFlow_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_ReceiveControlFlow_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 "stm32f4xx_hal.h"
163 
164 /** @addtogroup STM32F4xx_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 #if defined(STM32F446xx)
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 
266 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
267   if (hspdif->State == HAL_SPDIFRX_STATE_RESET)
268   {
269     /* Allocate lock resource and initialize it */
270     hspdif->Lock = HAL_UNLOCKED;
271 
272     hspdif->RxHalfCpltCallback  = HAL_SPDIFRX_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
273     hspdif->RxCpltCallback      = HAL_SPDIFRX_RxCpltCallback;     /* Legacy weak RxCpltCallback     */
274     hspdif->CxHalfCpltCallback  = HAL_SPDIFRX_CxHalfCpltCallback; /* Legacy weak CxHalfCpltCallback */
275     hspdif->CxCpltCallback      = HAL_SPDIFRX_CxCpltCallback;     /* Legacy weak CxCpltCallback     */
276     hspdif->ErrorCallback       = HAL_SPDIFRX_ErrorCallback;      /* Legacy weak ErrorCallback      */
277 
278     if (hspdif->MspInitCallback == NULL)
279     {
280       hspdif->MspInitCallback = HAL_SPDIFRX_MspInit; /* Legacy weak MspInit  */
281     }
282 
283     /* Init the low level hardware */
284     hspdif->MspInitCallback(hspdif);
285   }
286 #else
287   if (hspdif->State == HAL_SPDIFRX_STATE_RESET)
288   {
289     /* Allocate lock resource and initialize it */
290     hspdif->Lock = HAL_UNLOCKED;
291     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
292     HAL_SPDIFRX_MspInit(hspdif);
293   }
294 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
295 
296   /* SPDIFRX peripheral state is BUSY */
297   hspdif->State = HAL_SPDIFRX_STATE_BUSY;
298 
299   /* Disable SPDIFRX interface (IDLE State) */
300   __HAL_SPDIFRX_IDLE(hspdif);
301 
302   /* Reset the old SPDIFRX CR configuration */
303   tmpreg = hspdif->Instance->CR;
304 
305   tmpreg &= ~(SPDIFRX_CR_RXSTEO  | SPDIFRX_CR_DRFMT  | SPDIFRX_CR_PMSK |
306               SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK  |
307               SPDIFRX_CR_CHSEL | SPDIFRX_CR_NBTR | SPDIFRX_CR_WFA |
308               SPDIFRX_CR_INSEL);
309 
310   /* Sets the new configuration of the SPDIFRX peripheral */
311   tmpreg |= (hspdif->Init.StereoMode |
312              hspdif->Init.InputSelection |
313              hspdif->Init.Retries |
314              hspdif->Init.WaitForActivity |
315              hspdif->Init.ChannelSelection |
316              hspdif->Init.DataFormat |
317              hspdif->Init.PreambleTypeMask |
318              hspdif->Init.ChannelStatusMask |
319              hspdif->Init.ValidityBitMask |
320              hspdif->Init.ParityErrorMask
321             );
322 
323 
324   hspdif->Instance->CR = tmpreg;
325 
326   hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
327 
328   /* SPDIFRX peripheral state is READY*/
329   hspdif->State = HAL_SPDIFRX_STATE_READY;
330 
331   return HAL_OK;
332 }
333 
334 /**
335   * @brief DeInitializes the SPDIFRX peripheral
336   * @param hspdif SPDIFRX handle
337   * @retval HAL status
338   */
HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef * hspdif)339 HAL_StatusTypeDef HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef *hspdif)
340 {
341   /* Check the SPDIFRX handle allocation */
342   if (hspdif == NULL)
343   {
344     return HAL_ERROR;
345   }
346 
347   /* Check the parameters */
348   assert_param(IS_SPDIFRX_ALL_INSTANCE(hspdif->Instance));
349 
350   hspdif->State = HAL_SPDIFRX_STATE_BUSY;
351 
352   /* Disable SPDIFRX interface (IDLE state) */
353   __HAL_SPDIFRX_IDLE(hspdif);
354 
355 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
356   if (hspdif->MspDeInitCallback == NULL)
357   {
358     hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit; /* Legacy weak MspDeInit  */
359   }
360 
361   /* DeInit the low level hardware */
362   hspdif->MspDeInitCallback(hspdif);
363 #else
364   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
365   HAL_SPDIFRX_MspDeInit(hspdif);
366 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
367 
368   hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
369 
370   /* SPDIFRX peripheral state is RESET*/
371   hspdif->State = HAL_SPDIFRX_STATE_RESET;
372 
373   /* Release Lock */
374   __HAL_UNLOCK(hspdif);
375 
376   return HAL_OK;
377 }
378 
379 /**
380   * @brief SPDIFRX MSP Init
381   * @param hspdif SPDIFRX handle
382   * @retval None
383   */
HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef * hspdif)384 __weak void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif)
385 {
386   /* Prevent unused argument(s) compilation warning */
387   UNUSED(hspdif);
388 
389   /* NOTE : This function Should not be modified, when the callback is needed,
390   the HAL_SPDIFRX_MspInit could be implemented in the user file
391   */
392 }
393 
394 /**
395   * @brief SPDIFRX MSP DeInit
396   * @param hspdif SPDIFRX handle
397   * @retval None
398   */
HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef * hspdif)399 __weak void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif)
400 {
401   /* Prevent unused argument(s) compilation warning */
402   UNUSED(hspdif);
403 
404   /* NOTE : This function Should not be modified, when the callback is needed,
405   the HAL_SPDIFRX_MspDeInit could be implemented in the user file
406   */
407 }
408 
409 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
410 /**
411   * @brief  Register a User SPDIFRX Callback
412   *         To be used instead of the weak predefined callback
413   * @param  hspdif SPDIFRX handle
414   * @param  CallbackID ID of the callback to be registered
415   *         This parameter can be one of the following values:
416   *          @arg @ref HAL_SPDIFRX_RX_HALF_CB_ID    SPDIFRX Data flow half completed callback ID
417   *          @arg @ref HAL_SPDIFRX_RX_CPLT_CB_ID    SPDIFRX Data flow completed callback ID
418   *          @arg @ref HAL_SPDIFRX_CX_HALF_CB_ID    SPDIFRX Control flow half completed callback ID
419   *          @arg @ref HAL_SPDIFRX_CX_CPLT_CB_ID    SPDIFRX Control flow completed callback ID
420   *          @arg @ref HAL_SPDIFRX_ERROR_CB_ID      SPDIFRX error callback ID
421   *          @arg @ref HAL_SPDIFRX_MSPINIT_CB_ID    MspInit callback ID
422   *          @arg @ref HAL_SPDIFRX_MSPDEINIT_CB_ID  MspDeInit callback ID
423   * @param  pCallback pointer to the Callback function
424   * @retval HAL status
425   */
HAL_SPDIFRX_RegisterCallback(SPDIFRX_HandleTypeDef * hspdif,HAL_SPDIFRX_CallbackIDTypeDef CallbackID,pSPDIFRX_CallbackTypeDef pCallback)426 HAL_StatusTypeDef HAL_SPDIFRX_RegisterCallback(SPDIFRX_HandleTypeDef *hspdif, HAL_SPDIFRX_CallbackIDTypeDef CallbackID,
427                                                pSPDIFRX_CallbackTypeDef pCallback)
428 {
429   HAL_StatusTypeDef status = HAL_OK;
430 
431   if (pCallback == NULL)
432   {
433     /* Update the error code */
434     hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
435     return HAL_ERROR;
436   }
437   /* Process locked */
438   __HAL_LOCK(hspdif);
439 
440   if (HAL_SPDIFRX_STATE_READY == hspdif->State)
441   {
442     switch (CallbackID)
443     {
444       case HAL_SPDIFRX_RX_HALF_CB_ID :
445         hspdif->RxHalfCpltCallback = pCallback;
446         break;
447 
448       case HAL_SPDIFRX_RX_CPLT_CB_ID :
449         hspdif->RxCpltCallback = pCallback;
450         break;
451 
452       case HAL_SPDIFRX_CX_HALF_CB_ID :
453         hspdif->CxHalfCpltCallback = pCallback;
454         break;
455 
456       case HAL_SPDIFRX_CX_CPLT_CB_ID :
457         hspdif->CxCpltCallback = pCallback;
458         break;
459 
460       case HAL_SPDIFRX_ERROR_CB_ID :
461         hspdif->ErrorCallback = pCallback;
462         break;
463 
464       case HAL_SPDIFRX_MSPINIT_CB_ID :
465         hspdif->MspInitCallback = pCallback;
466         break;
467 
468       case HAL_SPDIFRX_MSPDEINIT_CB_ID :
469         hspdif->MspDeInitCallback = pCallback;
470         break;
471 
472       default :
473         /* Update the error code */
474         hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
475         /* Return error status */
476         status =  HAL_ERROR;
477         break;
478     }
479   }
480   else if (HAL_SPDIFRX_STATE_RESET == hspdif->State)
481   {
482     switch (CallbackID)
483     {
484       case HAL_SPDIFRX_MSPINIT_CB_ID :
485         hspdif->MspInitCallback = pCallback;
486         break;
487 
488       case HAL_SPDIFRX_MSPDEINIT_CB_ID :
489         hspdif->MspDeInitCallback = pCallback;
490         break;
491 
492       default :
493         /* Update the error code */
494         hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
495         /* Return error status */
496         status =  HAL_ERROR;
497         break;
498     }
499   }
500   else
501   {
502     /* Update the error code */
503     hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
504     /* Return error status */
505     status =  HAL_ERROR;
506   }
507 
508   /* Release Lock */
509   __HAL_UNLOCK(hspdif);
510   return status;
511 }
512 
513 /**
514   * @brief  Unregister a SPDIFRX Callback
515   *         SPDIFRX callback is redirected to the weak predefined callback
516   * @param  hspdif SPDIFRX handle
517   * @param  CallbackID ID of the callback to be unregistered
518   *         This parameter can be one of the following values:
519   *          @arg @ref HAL_SPDIFRX_RX_HALF_CB_ID    SPDIFRX Data flow half completed callback ID
520   *          @arg @ref HAL_SPDIFRX_RX_CPLT_CB_ID    SPDIFRX Data flow completed callback ID
521   *          @arg @ref HAL_SPDIFRX_CX_HALF_CB_ID    SPDIFRX Control flow half completed callback ID
522   *          @arg @ref HAL_SPDIFRX_CX_CPLT_CB_ID    SPDIFRX Control flow completed callback ID
523   *          @arg @ref HAL_SPDIFRX_ERROR_CB_ID      SPDIFRX error callback ID
524   *          @arg @ref HAL_SPDIFRX_MSPINIT_CB_ID    MspInit callback ID
525   *          @arg @ref HAL_SPDIFRX_MSPDEINIT_CB_ID  MspDeInit callback ID
526   * @retval HAL status
527   */
HAL_SPDIFRX_UnRegisterCallback(SPDIFRX_HandleTypeDef * hspdif,HAL_SPDIFRX_CallbackIDTypeDef CallbackID)528 HAL_StatusTypeDef HAL_SPDIFRX_UnRegisterCallback(SPDIFRX_HandleTypeDef *hspdif,
529                                                  HAL_SPDIFRX_CallbackIDTypeDef CallbackID)
530 {
531   HAL_StatusTypeDef status = HAL_OK;
532 
533   /* Process locked */
534   __HAL_LOCK(hspdif);
535 
536   if (HAL_SPDIFRX_STATE_READY == hspdif->State)
537   {
538     switch (CallbackID)
539     {
540       case HAL_SPDIFRX_RX_HALF_CB_ID :
541         hspdif->RxHalfCpltCallback = HAL_SPDIFRX_RxHalfCpltCallback;
542         break;
543 
544       case HAL_SPDIFRX_RX_CPLT_CB_ID :
545         hspdif->RxCpltCallback = HAL_SPDIFRX_RxCpltCallback;
546         break;
547 
548       case HAL_SPDIFRX_CX_HALF_CB_ID :
549         hspdif->CxHalfCpltCallback = HAL_SPDIFRX_CxHalfCpltCallback;
550         break;
551 
552       case HAL_SPDIFRX_CX_CPLT_CB_ID :
553         hspdif->CxCpltCallback = HAL_SPDIFRX_CxCpltCallback;
554         break;
555 
556       case HAL_SPDIFRX_ERROR_CB_ID :
557         hspdif->ErrorCallback = HAL_SPDIFRX_ErrorCallback;
558         break;
559 
560       default :
561         /* Update the error code */
562         hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
563         /* Return error status */
564         status =  HAL_ERROR;
565         break;
566     }
567   }
568   else if (HAL_SPDIFRX_STATE_RESET == hspdif->State)
569   {
570     switch (CallbackID)
571     {
572       case HAL_SPDIFRX_MSPINIT_CB_ID :
573         hspdif->MspInitCallback = HAL_SPDIFRX_MspInit;  /* Legacy weak MspInit  */
574         break;
575 
576       case HAL_SPDIFRX_MSPDEINIT_CB_ID :
577         hspdif->MspDeInitCallback = HAL_SPDIFRX_MspDeInit;  /* Legacy weak MspInit  */
578         break;
579 
580       default :
581         /* Update the error code */
582         hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
583         /* Return error status */
584         status =  HAL_ERROR;
585         break;
586     }
587   }
588   else
589   {
590     /* Update the error code */
591     hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_INVALID_CALLBACK;
592     /* Return error status */
593     status =  HAL_ERROR;
594   }
595 
596   /* Release Lock */
597   __HAL_UNLOCK(hspdif);
598   return status;
599 }
600 
601 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
602 
603 /**
604   * @brief Set the SPDIFRX  data format according to the specified parameters in the SPDIFRX_InitTypeDef.
605   * @param hspdif SPDIFRX handle
606   * @param sDataFormat SPDIFRX data format
607   * @retval HAL status
608   */
HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef * hspdif,SPDIFRX_SetDataFormatTypeDef sDataFormat)609 HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef sDataFormat)
610 {
611   uint32_t tmpreg;
612 
613   /* Check the SPDIFRX handle allocation */
614   if (hspdif == NULL)
615   {
616     return HAL_ERROR;
617   }
618 
619   /* Check the SPDIFRX parameters */
620   assert_param(IS_STEREO_MODE(sDataFormat.StereoMode));
621   assert_param(IS_SPDIFRX_DATA_FORMAT(sDataFormat.DataFormat));
622   assert_param(IS_PREAMBLE_TYPE_MASK(sDataFormat.PreambleTypeMask));
623   assert_param(IS_CHANNEL_STATUS_MASK(sDataFormat.ChannelStatusMask));
624   assert_param(IS_VALIDITY_MASK(sDataFormat.ValidityBitMask));
625   assert_param(IS_PARITY_ERROR_MASK(sDataFormat.ParityErrorMask));
626 
627   /* Reset the old SPDIFRX CR configuration */
628   tmpreg = hspdif->Instance->CR;
629 
630   if (((tmpreg & SPDIFRX_STATE_RCV) == SPDIFRX_STATE_RCV) &&
631       (((tmpreg & SPDIFRX_CR_DRFMT) != sDataFormat.DataFormat) ||
632        ((tmpreg & SPDIFRX_CR_RXSTEO) != sDataFormat.StereoMode)))
633   {
634     return HAL_ERROR;
635   }
636 
637   tmpreg &= ~(SPDIFRX_CR_RXSTEO  | SPDIFRX_CR_DRFMT  | SPDIFRX_CR_PMSK |
638               SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK);
639 
640   /* Configure the new data format */
641   tmpreg |= (sDataFormat.StereoMode |
642              sDataFormat.DataFormat |
643              sDataFormat.PreambleTypeMask |
644              sDataFormat.ChannelStatusMask |
645              sDataFormat.ValidityBitMask |
646              sDataFormat.ParityErrorMask);
647 
648   hspdif->Instance->CR = tmpreg;
649 
650   return HAL_OK;
651 }
652 
653 /**
654   * @}
655   */
656 
657 /** @defgroup SPDIFRX_Exported_Functions_Group2 IO operation functions
658   *  @brief Data transfers functions
659   *
660 @verbatim
661 ===============================================================================
662                      ##### IO operation functions #####
663 ===============================================================================
664     [..]
665     This subsection provides a set of functions allowing to manage the SPDIFRX data
666     transfers.
667 
668     (#) There is two mode of transfer:
669         (++) Blocking mode : The communication is performed in the polling mode.
670              The status of all data processing is returned by the same function
671              after finishing transfer.
672         (++) No-Blocking mode : The communication is performed using Interrupts
673              or DMA. These functions return the status of the transfer start-up.
674              The end of the data processing will be indicated through the
675              dedicated SPDIFRX IRQ when using Interrupt mode or the DMA IRQ when
676              using DMA mode.
677 
678     (#) Blocking mode functions are :
679         (++) HAL_SPDIFRX_ReceiveDataFlow()
680         (++) HAL_SPDIFRX_ReceiveControlFlow()
681                 (+@) Do not use blocking mode to receive both control and data flow at the same time.
682 
683     (#) No-Blocking mode functions with Interrupt are :
684         (++) HAL_SPDIFRX_ReceiveControlFlow_IT()
685         (++) HAL_SPDIFRX_ReceiveDataFlow_IT()
686 
687     (#) No-Blocking mode functions with DMA are :
688         (++) HAL_SPDIFRX_ReceiveControlFlow_DMA()
689         (++) HAL_SPDIFRX_ReceiveDataFlow_DMA()
690 
691     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
692         (++) HAL_SPDIFRX_RxCpltCallback()
693         (++) HAL_SPDIFRX_CxCpltCallback()
694 
695 @endverbatim
696   * @{
697   */
698 
699 /**
700   * @brief  Receives an amount of data (Data Flow) in blocking mode.
701   * @param  hspdif pointer to SPDIFRX_HandleTypeDef structure that contains
702   *                 the configuration information for SPDIFRX module.
703   * @param  pData Pointer to data buffer
704   * @param  Size Amount of data to be received
705   * @param  Timeout Timeout duration
706   * @retval HAL status
707   */
HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size,uint32_t Timeout)708 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size,
709                                               uint32_t Timeout)
710 {
711   uint32_t tickstart;
712   uint16_t sizeCounter = Size;
713   uint32_t *pTmpBuf = pData;
714 
715   if ((pData == NULL) || (Size == 0U))
716   {
717     return  HAL_ERROR;
718   }
719 
720   if (hspdif->State == HAL_SPDIFRX_STATE_READY)
721   {
722     /* Process Locked */
723     __HAL_LOCK(hspdif);
724 
725     hspdif->State = HAL_SPDIFRX_STATE_BUSY;
726 
727     /* Start synchronisation */
728     __HAL_SPDIFRX_SYNC(hspdif);
729 
730     /* Get tick */
731     tickstart = HAL_GetTick();
732 
733     /* Wait until SYNCD flag is set */
734     if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
735     {
736       return HAL_TIMEOUT;
737     }
738 
739     /* Start reception */
740     __HAL_SPDIFRX_RCV(hspdif);
741 
742     /* Receive data flow */
743     while (sizeCounter > 0U)
744     {
745       /* Get tick */
746       tickstart = HAL_GetTick();
747 
748       /* Wait until RXNE flag is set */
749       if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
750       {
751         return HAL_TIMEOUT;
752       }
753 
754       (*pTmpBuf) = hspdif->Instance->DR;
755       pTmpBuf++;
756       sizeCounter--;
757     }
758 
759     /* SPDIFRX ready */
760     hspdif->State = HAL_SPDIFRX_STATE_READY;
761 
762     /* Process Unlocked */
763     __HAL_UNLOCK(hspdif);
764 
765     return HAL_OK;
766   }
767   else
768   {
769     return HAL_BUSY;
770   }
771 }
772 
773 /**
774   * @brief  Receives an amount of data (Control Flow) in blocking mode.
775   * @param  hspdif pointer to a SPDIFRX_HandleTypeDef structure that contains
776   *                 the configuration information for SPDIFRX module.
777   * @param  pData Pointer to data buffer
778   * @param  Size Amount of data to be received
779   * @param  Timeout Timeout duration
780   * @retval HAL status
781   */
HAL_SPDIFRX_ReceiveControlFlow(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size,uint32_t Timeout)782 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size,
783                                                  uint32_t Timeout)
784 {
785   uint32_t tickstart;
786   uint16_t sizeCounter = Size;
787   uint32_t *pTmpBuf = pData;
788 
789   if ((pData == NULL) || (Size == 0U))
790   {
791     return  HAL_ERROR;
792   }
793 
794   if (hspdif->State == HAL_SPDIFRX_STATE_READY)
795   {
796     /* Process Locked */
797     __HAL_LOCK(hspdif);
798 
799     hspdif->State = HAL_SPDIFRX_STATE_BUSY;
800 
801     /* Start synchronization */
802     __HAL_SPDIFRX_SYNC(hspdif);
803 
804     /* Get tick */
805     tickstart = HAL_GetTick();
806 
807     /* Wait until SYNCD flag is set */
808     if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
809     {
810       return HAL_TIMEOUT;
811     }
812 
813     /* Start reception */
814     __HAL_SPDIFRX_RCV(hspdif);
815 
816     /* Receive control flow */
817     while (sizeCounter > 0U)
818     {
819       /* Get tick */
820       tickstart = HAL_GetTick();
821 
822       /* Wait until CSRNE flag is set */
823       if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_CSRNE, RESET, Timeout, tickstart) != HAL_OK)
824       {
825         return HAL_TIMEOUT;
826       }
827 
828       (*pTmpBuf) = hspdif->Instance->CSR;
829       pTmpBuf++;
830       sizeCounter--;
831     }
832 
833     /* SPDIFRX ready */
834     hspdif->State = HAL_SPDIFRX_STATE_READY;
835 
836     /* Process Unlocked */
837     __HAL_UNLOCK(hspdif);
838 
839     return HAL_OK;
840   }
841   else
842   {
843     return HAL_BUSY;
844   }
845 }
846 
847 /**
848   * @brief Receive an amount of data (Data Flow) in non-blocking mode with Interrupt
849   * @param hspdif SPDIFRX handle
850   * @param pData a 32-bit pointer to the Receive data buffer.
851   * @param Size number of data sample to be received .
852   * @retval HAL status
853   */
HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)854 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
855 {
856   uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
857 
858   const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
859 
860   if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
861   {
862     if ((pData == NULL) || (Size == 0U))
863     {
864       return HAL_ERROR;
865     }
866 
867     /* Process Locked */
868     __HAL_LOCK(hspdif);
869 
870     hspdif->pRxBuffPtr = pData;
871     hspdif->RxXferSize = Size;
872     hspdif->RxXferCount = Size;
873 
874     hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
875 
876     /* Check if a receive process is ongoing or not */
877     hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
878 
879     /* Enable the SPDIFRX  PE Error Interrupt */
880     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
881 
882     /* Enable the SPDIFRX  OVR Error Interrupt */
883     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
884 
885     /* Enable the SPDIFRX RXNE interrupt */
886     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_RXNE);
887 
888     if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
889     {
890       /* Start synchronization */
891       __HAL_SPDIFRX_SYNC(hspdif);
892 
893       /* Wait until SYNCD flag is set */
894       do
895       {
896         if (count == 0U)
897         {
898           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
899              process */
900           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
901           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
902           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
903           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
904           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
905           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
906           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
907 
908           hspdif->State = HAL_SPDIFRX_STATE_READY;
909 
910           /* Process Unlocked */
911           __HAL_UNLOCK(hspdif);
912 
913           return HAL_TIMEOUT;
914         }
915         count--;
916       } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
917 
918       /* Start reception */
919       __HAL_SPDIFRX_RCV(hspdif);
920     }
921 
922     /* Process Unlocked */
923     __HAL_UNLOCK(hspdif);
924 
925     return HAL_OK;
926   }
927   else
928   {
929     return HAL_BUSY;
930   }
931 }
932 
933 /**
934   * @brief Receive an amount of data (Control Flow) with Interrupt
935   * @param hspdif SPDIFRX handle
936   * @param pData a 32-bit pointer to the Receive data buffer.
937   * @param Size number of data sample (Control Flow) to be received
938   * @retval HAL status
939   */
HAL_SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)940 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
941 {
942   uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
943 
944   const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
945 
946   if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
947   {
948     if ((pData == NULL) || (Size == 0U))
949     {
950       return HAL_ERROR;
951     }
952 
953     /* Process Locked */
954     __HAL_LOCK(hspdif);
955 
956     hspdif->pCsBuffPtr = pData;
957     hspdif->CsXferSize = Size;
958     hspdif->CsXferCount = Size;
959 
960     hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
961 
962     /* Check if a receive process is ongoing or not */
963     hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
964 
965     /* Enable the SPDIFRX PE Error Interrupt */
966     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
967 
968     /* Enable the SPDIFRX OVR Error Interrupt */
969     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
970 
971     /* Enable the SPDIFRX CSRNE interrupt */
972     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
973 
974     if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
975     {
976       /* Start synchronization */
977       __HAL_SPDIFRX_SYNC(hspdif);
978 
979       /* Wait until SYNCD flag is set */
980       do
981       {
982         if (count == 0U)
983         {
984           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
985              process */
986           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
987           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
988           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
989           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
990           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
991           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
992           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
993 
994           hspdif->State = HAL_SPDIFRX_STATE_READY;
995 
996           /* Process Unlocked */
997           __HAL_UNLOCK(hspdif);
998 
999           return HAL_TIMEOUT;
1000         }
1001         count--;
1002       } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1003 
1004       /* Start reception */
1005       __HAL_SPDIFRX_RCV(hspdif);
1006     }
1007 
1008     /* Process Unlocked */
1009     __HAL_UNLOCK(hspdif);
1010 
1011     return HAL_OK;
1012   }
1013   else
1014   {
1015     return HAL_BUSY;
1016   }
1017 }
1018 
1019 /**
1020   * @brief Receive an amount of data (Data Flow) mode with DMA
1021   * @param hspdif SPDIFRX handle
1022   * @param pData a 32-bit pointer to the Receive data buffer.
1023   * @param Size number of data sample to be received
1024   * @retval HAL status
1025   */
HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)1026 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1027 {
1028   uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1029 
1030   const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1031 
1032   if ((pData == NULL) || (Size == 0U))
1033   {
1034     return  HAL_ERROR;
1035   }
1036 
1037   if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_CX))
1038   {
1039     /* Process Locked */
1040     __HAL_LOCK(hspdif);
1041 
1042     hspdif->pRxBuffPtr = pData;
1043     hspdif->RxXferSize = Size;
1044     hspdif->RxXferCount = Size;
1045 
1046     hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1047     hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
1048 
1049     /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1050     hspdif->hdmaDrRx->XferHalfCpltCallback = SPDIFRX_DMARxHalfCplt;
1051 
1052     /* Set the SPDIFRX Rx DMA transfer complete callback */
1053     hspdif->hdmaDrRx->XferCpltCallback = SPDIFRX_DMARxCplt;
1054 
1055     /* Set the DMA error callback */
1056     hspdif->hdmaDrRx->XferErrorCallback = SPDIFRX_DMAError;
1057 
1058     /* Enable the DMA request */
1059     if (HAL_DMA_Start_IT(hspdif->hdmaDrRx, (uint32_t)&hspdif->Instance->DR, (uint32_t)hspdif->pRxBuffPtr, Size) !=
1060         HAL_OK)
1061     {
1062       /* Set SPDIFRX error */
1063       hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1064 
1065       /* Set SPDIFRX state */
1066       hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1067 
1068       /* Process Unlocked */
1069       __HAL_UNLOCK(hspdif);
1070 
1071       return HAL_ERROR;
1072     }
1073 
1074     /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/
1075     hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN;
1076 
1077     if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1078     {
1079       /* Start synchronization */
1080       __HAL_SPDIFRX_SYNC(hspdif);
1081 
1082       /* Wait until SYNCD flag is set */
1083       do
1084       {
1085         if (count == 0U)
1086         {
1087           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1088              process */
1089           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1090           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1091           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1092           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1093           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1094           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1095           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1096 
1097           hspdif->State = HAL_SPDIFRX_STATE_READY;
1098 
1099           /* Process Unlocked */
1100           __HAL_UNLOCK(hspdif);
1101 
1102           return HAL_TIMEOUT;
1103         }
1104         count--;
1105       } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1106 
1107       /* Start reception */
1108       __HAL_SPDIFRX_RCV(hspdif);
1109     }
1110 
1111     /* Process Unlocked */
1112     __HAL_UNLOCK(hspdif);
1113 
1114     return HAL_OK;
1115   }
1116   else
1117   {
1118     return HAL_BUSY;
1119   }
1120 }
1121 
1122 /**
1123   * @brief Receive an amount of data (Control Flow) with DMA
1124   * @param hspdif SPDIFRX handle
1125   * @param pData a 32-bit pointer to the Receive data buffer.
1126   * @param Size number of data (Control Flow) sample to be received
1127   * @retval HAL status
1128   */
HAL_SPDIFRX_ReceiveControlFlow_DMA(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)1129 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
1130 {
1131   uint32_t count = SPDIFRX_TIMEOUT_VALUE * (SystemCoreClock / 24U / 1000U);
1132 
1133   const HAL_SPDIFRX_StateTypeDef tempState = hspdif->State;
1134 
1135   if ((pData == NULL) || (Size == 0U))
1136   {
1137     return  HAL_ERROR;
1138   }
1139 
1140   if ((tempState == HAL_SPDIFRX_STATE_READY) || (tempState == HAL_SPDIFRX_STATE_BUSY_RX))
1141   {
1142     hspdif->pCsBuffPtr = pData;
1143     hspdif->CsXferSize = Size;
1144     hspdif->CsXferCount = Size;
1145 
1146     /* Process Locked */
1147     __HAL_LOCK(hspdif);
1148 
1149     hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
1150     hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
1151 
1152     /* Set the SPDIFRX Rx DMA Half transfer complete callback */
1153     hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt;
1154 
1155     /* Set the SPDIFRX Rx DMA transfer complete callback */
1156     hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt;
1157 
1158     /* Set the DMA error callback */
1159     hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError;
1160 
1161     /* Enable the DMA request */
1162     if (HAL_DMA_Start_IT(hspdif->hdmaCsRx, (uint32_t)&hspdif->Instance->CSR, (uint32_t)hspdif->pCsBuffPtr, Size) !=
1163         HAL_OK)
1164     {
1165       /* Set SPDIFRX error */
1166       hspdif->ErrorCode = HAL_SPDIFRX_ERROR_DMA;
1167 
1168       /* Set SPDIFRX state */
1169       hspdif->State = HAL_SPDIFRX_STATE_ERROR;
1170 
1171       /* Process Unlocked */
1172       __HAL_UNLOCK(hspdif);
1173 
1174       return HAL_ERROR;
1175     }
1176 
1177     /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/
1178     hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN;
1179 
1180     if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_RCV)
1181     {
1182       /* Start synchronization */
1183       __HAL_SPDIFRX_SYNC(hspdif);
1184 
1185       /* Wait until SYNCD flag is set */
1186       do
1187       {
1188         if (count == 0U)
1189         {
1190           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1191              process */
1192           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1193           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1194           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1195           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1196           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1197           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1198           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1199 
1200           hspdif->State = HAL_SPDIFRX_STATE_READY;
1201 
1202           /* Process Unlocked */
1203           __HAL_UNLOCK(hspdif);
1204 
1205           return HAL_TIMEOUT;
1206         }
1207         count--;
1208       } while (__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_SYNCD) == RESET);
1209 
1210       /* Start reception */
1211       __HAL_SPDIFRX_RCV(hspdif);
1212     }
1213 
1214     /* Process Unlocked */
1215     __HAL_UNLOCK(hspdif);
1216 
1217     return HAL_OK;
1218   }
1219   else
1220   {
1221     return HAL_BUSY;
1222   }
1223 }
1224 
1225 /**
1226   * @brief stop the audio stream receive from the Media.
1227   * @param hspdif SPDIFRX handle
1228   * @retval None
1229   */
HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef * hspdif)1230 HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif)
1231 {
1232   /* Process Locked */
1233   __HAL_LOCK(hspdif);
1234 
1235   /* Disable the SPDIFRX DMA requests */
1236   hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1237   hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1238 
1239   /* Disable the SPDIFRX DMA channel */
1240   if (hspdif->hdmaDrRx != NULL)
1241   {
1242     __HAL_DMA_DISABLE(hspdif->hdmaDrRx);
1243   }
1244   if (hspdif->hdmaCsRx != NULL)
1245   {
1246     __HAL_DMA_DISABLE(hspdif->hdmaCsRx);
1247   }
1248 
1249   /* Disable SPDIFRX peripheral */
1250   __HAL_SPDIFRX_IDLE(hspdif);
1251 
1252   hspdif->State = HAL_SPDIFRX_STATE_READY;
1253 
1254   /* Process Unlocked */
1255   __HAL_UNLOCK(hspdif);
1256 
1257   return HAL_OK;
1258 }
1259 
1260 /**
1261   * @brief  This function handles SPDIFRX interrupt request.
1262   * @param  hspdif SPDIFRX handle
1263   * @retval HAL status
1264   */
HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef * hspdif)1265 void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif)
1266 {
1267   uint32_t itFlag   = hspdif->Instance->SR;
1268   uint32_t itSource = hspdif->Instance->IMR;
1269 
1270   /* SPDIFRX in mode Data Flow Reception */
1271   if (((itFlag & SPDIFRX_FLAG_RXNE) == SPDIFRX_FLAG_RXNE) && ((itSource &  SPDIFRX_IT_RXNE) == SPDIFRX_IT_RXNE))
1272   {
1273     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE);
1274     SPDIFRX_ReceiveDataFlow_IT(hspdif);
1275   }
1276 
1277   /* SPDIFRX in mode Control Flow Reception */
1278   if (((itFlag & SPDIFRX_FLAG_CSRNE) == SPDIFRX_FLAG_CSRNE) && ((itSource &  SPDIFRX_IT_CSRNE) == SPDIFRX_IT_CSRNE))
1279   {
1280     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE);
1281     SPDIFRX_ReceiveControlFlow_IT(hspdif);
1282   }
1283 
1284   /* SPDIFRX Overrun error interrupt occurred */
1285   if (((itFlag & SPDIFRX_FLAG_OVR) == SPDIFRX_FLAG_OVR) && ((itSource &  SPDIFRX_IT_OVRIE) == SPDIFRX_IT_OVRIE))
1286   {
1287     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_OVRIE);
1288 
1289     /* Change the SPDIFRX error code */
1290     hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR;
1291 
1292     /* the transfer is not stopped */
1293     HAL_SPDIFRX_ErrorCallback(hspdif);
1294   }
1295 
1296   /* SPDIFRX Parity error interrupt occurred */
1297   if (((itFlag & SPDIFRX_FLAG_PERR) == SPDIFRX_FLAG_PERR) && ((itSource &  SPDIFRX_IT_PERRIE) == SPDIFRX_IT_PERRIE))
1298   {
1299     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_PERRIE);
1300 
1301     /* Change the SPDIFRX error code */
1302     hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE;
1303 
1304     /* the transfer is not stopped */
1305     HAL_SPDIFRX_ErrorCallback(hspdif);
1306   }
1307 }
1308 
1309 /**
1310   * @brief Rx Transfer (Data flow) half completed callbacks
1311   * @param hspdif SPDIFRX handle
1312   * @retval None
1313   */
HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1314 __weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1315 {
1316   /* Prevent unused argument(s) compilation warning */
1317   UNUSED(hspdif);
1318 
1319   /* NOTE : This function Should not be modified, when the callback is needed,
1320             the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1321   */
1322 }
1323 
1324 /**
1325   * @brief Rx Transfer (Data flow) completed callbacks
1326   * @param hspdif SPDIFRX handle
1327   * @retval None
1328   */
HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1329 __weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1330 {
1331   /* Prevent unused argument(s) compilation warning */
1332   UNUSED(hspdif);
1333 
1334   /* NOTE : This function Should not be modified, when the callback is needed,
1335             the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1336   */
1337 }
1338 
1339 /**
1340   * @brief Rx (Control flow) Transfer half completed callbacks
1341   * @param hspdif SPDIFRX handle
1342   * @retval None
1343   */
HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1344 __weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1345 {
1346   /* Prevent unused argument(s) compilation warning */
1347   UNUSED(hspdif);
1348 
1349   /* NOTE : This function Should not be modified, when the callback is needed,
1350             the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1351   */
1352 }
1353 
1354 /**
1355   * @brief Rx Transfer (Control flow) completed callbacks
1356   * @param hspdif SPDIFRX handle
1357   * @retval None
1358   */
HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef * hspdif)1359 __weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
1360 {
1361   /* Prevent unused argument(s) compilation warning */
1362   UNUSED(hspdif);
1363 
1364   /* NOTE : This function Should not be modified, when the callback is needed,
1365             the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
1366   */
1367 }
1368 
1369 /**
1370   * @brief SPDIFRX error callbacks
1371   * @param hspdif SPDIFRX handle
1372   * @retval None
1373   */
HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef * hspdif)1374 __weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif)
1375 {
1376   /* Prevent unused argument(s) compilation warning */
1377   UNUSED(hspdif);
1378 
1379   /* NOTE : This function Should not be modified, when the callback is needed,
1380             the HAL_SPDIFRX_ErrorCallback could be implemented in the user file
1381   */
1382 }
1383 
1384 /**
1385   * @}
1386   */
1387 
1388 /** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions
1389   *  @brief   Peripheral State functions
1390   *
1391 @verbatim
1392 ===============================================================================
1393 ##### Peripheral State and Errors functions #####
1394 ===============================================================================
1395 [..]
1396 This subsection permit to get in run-time the status of the peripheral
1397 and the data flow.
1398 
1399 @endverbatim
1400   * @{
1401   */
1402 
1403 /**
1404   * @brief  Return the SPDIFRX state
1405   * @param  hspdif SPDIFRX handle
1406   * @retval HAL state
1407   */
HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const * const hspdif)1408 HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef const *const hspdif)
1409 {
1410   return hspdif->State;
1411 }
1412 
1413 /**
1414   * @brief  Return the SPDIFRX error code
1415   * @param  hspdif SPDIFRX handle
1416   * @retval SPDIFRX Error Code
1417   */
HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const * const hspdif)1418 uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef const *const hspdif)
1419 {
1420   return hspdif->ErrorCode;
1421 }
1422 
1423 /**
1424   * @}
1425   */
1426 
1427 /**
1428   * @brief DMA SPDIFRX receive process (Data flow) complete callback
1429   * @param hdma DMA handle
1430   * @retval None
1431   */
SPDIFRX_DMARxCplt(DMA_HandleTypeDef * hdma)1432 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma)
1433 {
1434   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1435 
1436   /* Disable Rx DMA Request */
1437   if (hdma->Init.Mode != DMA_CIRCULAR)
1438   {
1439     hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1440     hspdif->RxXferCount = 0;
1441     hspdif->State = HAL_SPDIFRX_STATE_READY;
1442   }
1443 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1444   hspdif->RxCpltCallback(hspdif);
1445 #else
1446   HAL_SPDIFRX_RxCpltCallback(hspdif);
1447 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1448 }
1449 
1450 /**
1451   * @brief DMA SPDIFRX receive process (Data flow) half complete callback
1452   * @param hdma DMA handle
1453   * @retval None
1454   */
SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1455 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1456 {
1457   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1458 
1459 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1460   hspdif->RxHalfCpltCallback(hspdif);
1461 #else
1462   HAL_SPDIFRX_RxHalfCpltCallback(hspdif);
1463 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1464 }
1465 
1466 
1467 /**
1468   * @brief DMA SPDIFRX receive process (Control flow) complete callback
1469   * @param hdma DMA handle
1470   * @retval None
1471   */
SPDIFRX_DMACxCplt(DMA_HandleTypeDef * hdma)1472 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma)
1473 {
1474   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1475 
1476   /* Disable Cb DMA Request */
1477   hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1478   hspdif->CsXferCount = 0;
1479 
1480   hspdif->State = HAL_SPDIFRX_STATE_READY;
1481 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1482   hspdif->CxCpltCallback(hspdif);
1483 #else
1484   HAL_SPDIFRX_CxCpltCallback(hspdif);
1485 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1486 }
1487 
1488 /**
1489   * @brief DMA SPDIFRX receive process (Control flow) half complete callback
1490   * @param hdma DMA handle
1491   * @retval None
1492   */
SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef * hdma)1493 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma)
1494 {
1495   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1496 
1497 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1498   hspdif->CxHalfCpltCallback(hspdif);
1499 #else
1500   HAL_SPDIFRX_CxHalfCpltCallback(hspdif);
1501 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1502 }
1503 
1504 /**
1505   * @brief DMA SPDIFRX communication error callback
1506   * @param hdma DMA handle
1507   * @retval None
1508   */
SPDIFRX_DMAError(DMA_HandleTypeDef * hdma)1509 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma)
1510 {
1511   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1512 
1513   /* Disable Rx and Cb DMA Request */
1514   hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN));
1515   hspdif->RxXferCount = 0;
1516 
1517   hspdif->State = HAL_SPDIFRX_STATE_READY;
1518 
1519   /* Set the error code and execute error callback*/
1520   hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA;
1521 
1522 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1523   /* The transfer is not stopped */
1524   hspdif->ErrorCallback(hspdif);
1525 #else
1526   /* The transfer is not stopped */
1527   HAL_SPDIFRX_ErrorCallback(hspdif);
1528 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1529 }
1530 
1531 /**
1532   * @brief Receive an amount of data (Data Flow) with Interrupt
1533   * @param hspdif SPDIFRX handle
1534   * @retval None
1535   */
SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef * hspdif)1536 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1537 {
1538   /* Receive data */
1539   (*hspdif->pRxBuffPtr) = hspdif->Instance->DR;
1540   hspdif->pRxBuffPtr++;
1541   hspdif->RxXferCount--;
1542 
1543   if (hspdif->RxXferCount == 0U)
1544   {
1545     /* Disable RXNE/PE and OVR interrupts */
1546     __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE);
1547 
1548     hspdif->State = HAL_SPDIFRX_STATE_READY;
1549 
1550     /* Process Unlocked */
1551     __HAL_UNLOCK(hspdif);
1552 
1553 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1554     hspdif->RxCpltCallback(hspdif);
1555 #else
1556     HAL_SPDIFRX_RxCpltCallback(hspdif);
1557 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1558   }
1559 }
1560 
1561 /**
1562   * @brief Receive an amount of data (Control Flow) with Interrupt
1563   * @param hspdif SPDIFRX handle
1564   * @retval None
1565   */
SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef * hspdif)1566 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1567 {
1568   /* Receive data */
1569   (*hspdif->pCsBuffPtr) = hspdif->Instance->CSR;
1570   hspdif->pCsBuffPtr++;
1571   hspdif->CsXferCount--;
1572 
1573   if (hspdif->CsXferCount == 0U)
1574   {
1575     /* Disable CSRNE interrupt */
1576     __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1577 
1578     hspdif->State = HAL_SPDIFRX_STATE_READY;
1579 
1580     /* Process Unlocked */
1581     __HAL_UNLOCK(hspdif);
1582 
1583 #if (USE_HAL_SPDIFRX_REGISTER_CALLBACKS == 1)
1584     hspdif->CxCpltCallback(hspdif);
1585 #else
1586     HAL_SPDIFRX_CxCpltCallback(hspdif);
1587 #endif /* USE_HAL_SPDIFRX_REGISTER_CALLBACKS */
1588   }
1589 }
1590 
1591 /**
1592   * @brief This function handles SPDIFRX Communication Timeout.
1593   * @param hspdif SPDIFRX handle
1594   * @param Flag Flag checked
1595   * @param Status Value of the flag expected
1596   * @param Timeout Duration of the timeout
1597   * @param tickstart Tick start value
1598   * @retval HAL status
1599   */
SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef * hspdif,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t tickstart)1600 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag,
1601                                                         FlagStatus Status, uint32_t Timeout, uint32_t tickstart)
1602 {
1603   /* Wait until flag is set */
1604   while (__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == Status)
1605   {
1606     /* Check for the Timeout */
1607     if (Timeout != HAL_MAX_DELAY)
1608     {
1609       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1610       {
1611         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt
1612            process */
1613         __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1614         __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1615         __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1616         __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1617         __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1618         __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1619         __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1620 
1621         hspdif->State = HAL_SPDIFRX_STATE_READY;
1622 
1623         /* Process Unlocked */
1624         __HAL_UNLOCK(hspdif);
1625 
1626         return HAL_TIMEOUT;
1627       }
1628     }
1629   }
1630 
1631   return HAL_OK;
1632 }
1633 
1634 /**
1635   * @}
1636   */
1637 #endif /* STM32F446xx */
1638 
1639 #endif /* SPDIFRX */
1640 #endif /* HAL_SPDIFRX_MODULE_ENABLED */
1641 /**
1642   * @}
1643   */
1644 
1645 /**
1646   * @}
1647   */
1648