1 /**
2   ******************************************************************************
3   * @file    stm32mp1xx_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   * @attention
13   *
14   * Copyright (c) 2019 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23  ===============================================================================
24                   ##### How to use this driver #####
25  ===============================================================================
26  [..]
27     The SPDIFRX HAL driver can be used as follow:
28 
29     (#) Declare SPDIFRX_HandleTypeDef handle structure.
30     (#) Initialize the SPDIFRX low level resources by implement the HAL_SPDIFRX_MspInit() API:
31         (##) Enable the SPDIFRX interface clock.
32         (##) SPDIFRX pins configuration:
33             (+++) Enable the clock for the SPDIFRX GPIOs.
34             (+++) Configure these SPDIFRX pins as alternate function pull-up.
35         (##) NVIC configuration if you need to use interrupt process (HAL_SPDIFRX_ReceiveControlFlow_IT() and HAL_SPDIFRX_ReceiveDataFlow_IT() API's).
36             (+++) Configure the SPDIFRX interrupt priority.
37             (+++) Enable the NVIC SPDIFRX IRQ handle.
38         (##) DMA Configuration if you need to use DMA process (HAL_SPDIFRX_ReceiveDataFlow_DMA() and HAL_SPDIFRX_ReceiveControlFlow_DMA() API's).
39             (+++) Declare a DMA handle structure for the reception of the Data Flow channel.
40             (+++) Declare a DMA handle structure for the reception of the Control Flow channel.
41             (+++) Enable the DMAx interface clock.
42             (+++) Configure the declared DMA handle structure CtrlRx/DataRx with the required parameters.
43             (+++) Configure the DMA Channel.
44             (+++) Associate the initialized DMA handle to the SPDIFRX DMA CtrlRx/DataRx handle.
45             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
46                 DMA CtrlRx/DataRx channel.
47 
48    (#) Program the input selection, re-tries number, wait for activity, channel status selection, data format, stereo mode and masking of user bits
49        using HAL_SPDIFRX_Init() function.
50 
51    -@- The specific SPDIFRX interrupts (RXNE/CSRNE and Error Interrupts) will be managed using the macros
52        __SPDIFRX_ENABLE_IT() and __SPDIFRX_DISABLE_IT() inside the receive process.
53    -@- Make sure that ck_spdif clock is configured.
54 
55    (#) Three operation modes are available within this driver :
56 
57    *** Polling mode for reception operation (for debug purpose) ***
58    ================================================================
59    [..]
60      (+) Receive data flow in blocking mode using HAL_SPDIFRX_ReceiveDataFlow()
61          (+) Receive control flow of data in blocking mode using HAL_SPDIFRX_ReceiveControlFlow()
62 
63    *** Interrupt mode for reception operation ***
64    =========================================
65    [..]
66      (+) Receive an amount of data (Data Flow) in non blocking mode using HAL_SPDIFRX_ReceiveDataFlow_IT()
67          (+) Receive an amount of data (Control Flow) in non blocking mode using HAL_SPDIFRX_ReceiveControlFlow_IT()
68      (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can
69          add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback
70      (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can
71          add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback
72      (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can
73          add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback
74 
75    *** DMA mode for reception operation ***
76    ========================================
77    [..]
78      (+) Receive an amount of data (Data Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveDataFlow_DMA()
79          (+) Receive an amount of data (Control Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveControlFlow_DMA()
80      (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can
81          add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback
82      (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can
83          add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback
84      (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can
85          add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback
86      (+) Stop the DMA Transfer using HAL_SPDIFRX_DMAStop()
87 
88    *** SPDIFRX HAL driver macros list ***
89    =============================================
90    [..]
91      Below the list of most used macros in USART HAL driver.
92       (+) __HAL_SPDIFRX_IDLE: Disable the specified SPDIFRX peripheral (IDEL State)
93       (+) __HAL_SPDIFRX_SYNC: Enable the synchronization state of the specified SPDIFRX peripheral (SYNC State)
94       (+) __HAL_SPDIFRX_RCV: Enable the receive state of the specified SPDIFRX peripheral (RCV State)
95       (+) __HAL_SPDIFRX_ENABLE_IT : Enable the specified SPDIFRX interrupts
96       (+) __HAL_SPDIFRX_DISABLE_IT : Disable the specified SPDIFRX interrupts
97       (+) __HAL_SPDIFRX_GET_FLAG: Check whether the specified SPDIFRX flag is set or not.
98 
99     [..]
100       (@) You can refer to the SPDIFRX HAL driver header file for more useful macros
101 
102   @endverbatim
103   ******************************************************************************
104   */
105 
106 /* Includes ------------------------------------------------------------------*/
107 #include "stm32mp1xx_hal.h"
108 
109 /** @addtogroup STM32MP1xx_HAL_Driver
110   * @{
111   */
112 /** @defgroup SPDIFRX SPDIFRX
113 * @brief SPDIFRX HAL module driver
114 * @{
115 */
116 
117 #ifdef HAL_SPDIFRX_MODULE_ENABLED
118 #if defined (SPDIFRX)
119 
120 /* Private typedef -----------------------------------------------------------*/
121 /* Private define ------------------------------------------------------------*/
122 /** @addtogroup SPDIFRX_Private_Define SPDIFRX Private Define
123   * @{
124   */
125 #define SPDIFRX_TIMEOUT_VALUE  0xFFFF
126 /**
127   * @}
128   */
129 
130 /* Private macro -------------------------------------------------------------*/
131 /* Private variables ---------------------------------------------------------*/
132 /* Private function prototypes -----------------------------------------------*/
133 /** @addtogroup SPDIFRX_Private_Functions
134   * @{
135   */
136 static void  SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma);
137 static void  SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
138 static void  SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma);
139 static void  SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma);
140 static void  SPDIFRX_DMAError(DMA_HandleTypeDef *hdma);
141 static void  SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif);
142 static void  SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif);
143 static HAL_StatusTypeDef  SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t tickstart);
144 /**
145   * @}
146   */
147 /* Exported functions ---------------------------------------------------------*/
148 
149 /** @defgroup SPDIFRX_Exported_Functions SPDIFRX Exported Functions
150   * @{
151   */
152 
153 /** @defgroup  SPDIFRX_Exported_Functions_Group1 Initialization and de-initialization functions
154   *  @brief    Initialization and Configuration functions
155   *
156   @verbatim
157   ===============================================================================
158   ##### Initialization and de-initialization functions #####
159   ===============================================================================
160   [..]  This subsection provides a set of functions allowing to initialize and
161   de-initialize the SPDIFRX peripheral:
162 
163   (+) User must Implement HAL_SPDIFRX_MspInit() function in which he configures
164   all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
165 
166   (+) Call the function HAL_SPDIFRX_Init() to configure the SPDIFRX peripheral with
167   the selected configuration:
168   (++) Input Selection (IN0, IN1,...)
169   (++) Maximum allowed re-tries during synchronization phase
170   (++) Wait for activity on SPDIF selected input
171   (++) Channel status selection (from channel A or B)
172   (++) Data format (LSB, MSB, ...)
173   (++) Stereo mode
174   (++) User bits masking (PT,C,U,V,...)
175 
176   (+) Call the function HAL_SPDIFRX_DeInit() to restore the default configuration
177   of the selected SPDIFRXx peripheral.
178   @endverbatim
179   * @{
180   */
181 
182 /**
183   * @brief Initializes the SPDIFRX according to the specified parameters
184   *        in the SPDIFRX_InitTypeDef and create the associated handle.
185   * @param hspdif: SPDIFRX handle
186   * @retval HAL status
187   */
HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef * hspdif)188 HAL_StatusTypeDef HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef *hspdif)
189 {
190   uint32_t tmpreg = 0;
191 
192   /* Check the SPDIFRX handle allocation */
193   if (hspdif == NULL)
194   {
195     return HAL_ERROR;
196   }
197 
198   /* Check the SPDIFRX parameters */
199   assert_param(IS_STEREO_MODE(hspdif->Init.StereoMode));
200   assert_param(IS_SPDIFRX_INPUT_SELECT(hspdif->Init.InputSelection));
201   assert_param(IS_SPDIFRX_MAX_RETRIES(hspdif->Init.Retries));
202   assert_param(IS_SPDIFRX_WAIT_FOR_ACTIVITY(hspdif->Init.WaitForActivity));
203   assert_param(IS_SPDIFRX_CHANNEL(hspdif->Init.ChannelSelection));
204   assert_param(IS_SPDIFRX_DATA_FORMAT(hspdif->Init.DataFormat));
205   assert_param(IS_PREAMBLE_TYPE_MASK(hspdif->Init.PreambleTypeMask));
206   assert_param(IS_CHANNEL_STATUS_MASK(hspdif->Init.ChannelStatusMask));
207   assert_param(IS_VALIDITY_MASK(hspdif->Init.ValidityBitMask));
208   assert_param(IS_PARITY_ERROR_MASK(hspdif->Init.ParityErrorMask));
209 
210   if (hspdif->State == HAL_SPDIFRX_STATE_RESET)
211   {
212     /* Allocate lock resource and initialize it */
213     hspdif->Lock = HAL_UNLOCKED;
214     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
215     HAL_SPDIFRX_MspInit(hspdif);
216   }
217 
218   /* SPDIFRX peripheral state is BUSY*/
219   hspdif->State = HAL_SPDIFRX_STATE_BUSY;
220 
221   /* Disable SPDIFRX interface (IDLE State) */
222   __HAL_SPDIFRX_IDLE(hspdif);
223 
224   /* Reset the old SPDIFRX CR configuration */
225   tmpreg = hspdif->Instance->CR;
226 
227   tmpreg &= ~((uint16_t) SPDIFRX_CR_RXSTEO  | SPDIFRX_CR_DRFMT  | SPDIFRX_CR_PMSK |
228               SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK  |
229               SPDIFRX_CR_CHSEL | SPDIFRX_CR_NBTR | SPDIFRX_CR_WFA | SPDIFRX_CR_INSEL);
230 
231   /* Sets the new configuration of the SPDIFRX peripheral */
232   tmpreg |= ((uint16_t) hspdif->Init.StereoMode |
233              hspdif->Init.InputSelection |
234              hspdif->Init.Retries |
235              hspdif->Init.WaitForActivity |
236              hspdif->Init.ChannelSelection |
237              hspdif->Init.DataFormat |
238              hspdif->Init.PreambleTypeMask |
239              hspdif->Init.ChannelStatusMask |
240              hspdif->Init.ValidityBitMask |
241              hspdif->Init.ParityErrorMask);
242 
243   hspdif->Instance->CR = tmpreg;
244 
245   hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
246 
247   /* SPDIFRX peripheral state is READY*/
248   hspdif->State = HAL_SPDIFRX_STATE_READY;
249 
250   return HAL_OK;
251 }
252 
253 /**
254   * @brief DeInitializes the SPDIFRX peripheral
255   * @param hspdif: SPDIFRX handle
256   * @retval HAL status
257   */
HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef * hspdif)258 HAL_StatusTypeDef HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef *hspdif)
259 {
260   /* Check the SPDIFRX handle allocation */
261   if (hspdif == NULL)
262   {
263     return HAL_ERROR;
264   }
265 
266   /* Check the parameters */
267   assert_param(IS_SPDIFRX_ALL_INSTANCE(hspdif->Instance));
268 
269   hspdif->State = HAL_SPDIFRX_STATE_BUSY;
270 
271   /* Disable SPDIFRX interface (IDLE state) */
272   __HAL_SPDIFRX_IDLE(hspdif);
273 
274   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
275   HAL_SPDIFRX_MspDeInit(hspdif);
276 
277   hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
278 
279   /* SPDIFRX peripheral state is RESET*/
280   hspdif->State = HAL_SPDIFRX_STATE_RESET;
281 
282   /* Release Lock */
283   __HAL_UNLOCK(hspdif);
284 
285   return HAL_OK;
286 }
287 
288 /**
289   * @brief SPDIFRX MSP Init
290   * @param hspdif: SPDIFRX handle
291   * @retval None
292   */
HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef * hspdif)293 __weak void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif)
294 {
295   /* Prevent unused argument(s) compilation warning */
296   UNUSED(hspdif);
297 
298   /* NOTE : This function Should not be modified, when the callback is needed,
299   the HAL_SPDIFRX_MspInit could be implemented in the user file
300   */
301 }
302 
303 /**
304   * @brief SPDIFRX MSP DeInit
305   * @param hspdif: SPDIFRX handle
306   * @retval None
307   */
HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef * hspdif)308 __weak void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif)
309 {
310   /* Prevent unused argument(s) compilation warning */
311   UNUSED(hspdif);
312 
313   /* NOTE : This function Should not be modified, when the callback is needed,
314   the HAL_SPDIFRX_MspDeInit could be implemented in the user file
315   */
316 }
317 
318 /**
319   * @brief Sets the SPDIFRX  dtat format according to the specified parameters
320   *        in the SPDIFRX_InitTypeDef.
321   * @param hspdif: SPDIFRX handle
322   * @param sDataFormat: SPDIFRX data format
323   * @retval HAL status
324   */
HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef * hspdif,SPDIFRX_SetDataFormatTypeDef sDataFormat)325 HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef  sDataFormat)
326 {
327   uint32_t tmpreg = 0;
328 
329   /* Check the SPDIFRX handle allocation */
330   if (hspdif == NULL)
331   {
332     return HAL_ERROR;
333   }
334 
335   /* Check the SPDIFRX parameters */
336   assert_param(IS_STEREO_MODE(sDataFormat.StereoMode));
337   assert_param(IS_SPDIFRX_DATA_FORMAT(sDataFormat.DataFormat));
338   assert_param(IS_PREAMBLE_TYPE_MASK(sDataFormat.PreambleTypeMask));
339   assert_param(IS_CHANNEL_STATUS_MASK(sDataFormat.ChannelStatusMask));
340   assert_param(IS_VALIDITY_MASK(sDataFormat.ValidityBitMask));
341   assert_param(IS_PARITY_ERROR_MASK(sDataFormat.ParityErrorMask));
342 
343   /* Reset the old SPDIFRX CR configuration */
344   tmpreg = hspdif->Instance->CR;
345 
346   if (((tmpreg & SPDIFRX_STATE_RCV) == SPDIFRX_STATE_RCV) &&
347       (((tmpreg & SPDIFRX_CR_DRFMT) != sDataFormat.DataFormat) ||
348        ((tmpreg & SPDIFRX_CR_RXSTEO) != sDataFormat.StereoMode)))
349   {
350     return HAL_ERROR;
351   }
352 
353   tmpreg &= ~((uint16_t) SPDIFRX_CR_RXSTEO  | SPDIFRX_CR_DRFMT  | SPDIFRX_CR_PMSK |
354               SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK);
355 
356   /* Sets the new configuration of the SPDIFRX peripheral */
357   tmpreg |= ((uint16_t) sDataFormat.StereoMode |
358              sDataFormat.DataFormat |
359              sDataFormat.PreambleTypeMask |
360              sDataFormat.ChannelStatusMask |
361              sDataFormat.ValidityBitMask |
362              sDataFormat.ParityErrorMask);
363 
364   hspdif->Instance->CR = tmpreg;
365 
366   return HAL_OK;
367 }
368 
369 /**
370   * @}
371   */
372 
373 /** @defgroup SPDIFRX_Exported_Functions_Group2 IO operation functions
374   *  @brief Data transfers functions
375   *
376 @verbatim
377 ===============================================================================
378                      ##### IO operation functions #####
379 ===============================================================================
380     [..]
381     This subsection provides a set of functions allowing to manage the SPDIFRX data
382     transfers.
383 
384     (#) There is two mode of transfer:
385         (++) Blocking mode : The communication is performed in the polling mode.
386              The status of all data processing is returned by the same function
387              after finishing transfer.
388         (++) No-Blocking mode : The communication is performed using Interrupts
389              or DMA. These functions return the status of the transfer start-up.
390              The end of the data processing will be indicated through the
391              dedicated SPDIFRX IRQ when using Interrupt mode or the DMA IRQ when
392              using DMA mode.
393 
394     (#) Blocking mode functions are :
395         (++) HAL_SPDIFRX_ReceiveDataFlow()
396         (++) HAL_SPDIFRX_ReceiveControlFlow()
397                 (+@) Do not use blocking mode to receive both control and data flow at the same time.
398 
399     (#) No-Blocking mode functions with Interrupt are :
400         (++) HAL_SPDIFRX_ReceiveControlFlow_IT()
401         (++) HAL_SPDIFRX_ReceiveDataFlow_IT()
402 
403     (#) No-Blocking mode functions with DMA are :
404         (++) HAL_SPDIFRX_ReceiveControlFlow_DMA()
405         (++) HAL_SPDIFRX_ReceiveDataFlow_DMA()
406 
407     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
408         (++) HAL_SPDIFRX_RxCpltCallback()
409         (++) HAL_SPDIFRX_ErrorCallback()
410 
411 @endverbatim
412 * @{
413 */
414 
415 
416 /**
417   * @brief  Receives an amount of data (Data Flow) in blocking mode.
418   * @param  hspdif: pointer to SPDIFRX_HandleTypeDef structure that contains
419   *                 the configuration information for SPDIFRX module.
420   * @param  pData: Pointer to data buffer
421   * @param  Size: Amount of data to be received
422   * @param  Timeout: Timeout duration
423   * @retval HAL status
424   */
HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size,uint32_t Timeout)425 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout)
426 {
427   uint32_t tickstart = 0U;
428 
429   if ((pData == NULL) || (Size == 0U))
430   {
431     return  HAL_ERROR;
432   }
433 
434   if (hspdif->State == HAL_SPDIFRX_STATE_READY)
435   {
436     /* Process Locked */
437     __HAL_LOCK(hspdif);
438 
439     hspdif->State = HAL_SPDIFRX_STATE_BUSY;
440 
441     /* Start synchronisation */
442     __HAL_SPDIFRX_SYNC(hspdif);
443 
444     /* Get tick */
445     tickstart = HAL_GetTick();
446 
447     /* Wait until SYNCD flag is set */
448     if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
449     {
450       return HAL_TIMEOUT;
451     }
452 
453     /* Start reception */
454     __HAL_SPDIFRX_RCV(hspdif);
455 
456     /* Receive data flow */
457     while (Size > 0U)
458     {
459       /* Get tick */
460       tickstart = HAL_GetTick();
461 
462       /* Wait until RXNE flag is set */
463       if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
464       {
465         return HAL_TIMEOUT;
466       }
467 
468       (*pData++) = hspdif->Instance->DR;
469       Size--;
470     }
471 
472     /* SPDIFRX ready */
473     hspdif->State = HAL_SPDIFRX_STATE_READY;
474 
475     /* Process Unlocked */
476     __HAL_UNLOCK(hspdif);
477 
478     return HAL_OK;
479   }
480   else
481   {
482     return HAL_BUSY;
483   }
484 }
485 
486 /**
487   * @brief  Receives an amount of data (Control Flow) in blocking mode.
488   * @param  hspdif: pointer to a SPDIFRX_HandleTypeDef structure that contains
489   *                 the configuration information for SPDIFRX module.
490   * @param  pData: Pointer to data buffer
491   * @param  Size: Amount of data to be received
492   * @param  Timeout: Timeout duration
493   * @retval HAL status
494   */
HAL_SPDIFRX_ReceiveControlFlow(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size,uint32_t Timeout)495 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout)
496 {
497   uint32_t tickstart = 0U;
498 
499   if ((pData == NULL) || (Size == 0U))
500   {
501     return  HAL_ERROR;
502   }
503 
504   if (hspdif->State == HAL_SPDIFRX_STATE_READY)
505   {
506     /* Process Locked */
507     __HAL_LOCK(hspdif);
508 
509     hspdif->State = HAL_SPDIFRX_STATE_BUSY;
510 
511     /* Start synchronization */
512     __HAL_SPDIFRX_SYNC(hspdif);
513 
514     /* Get tick */
515     tickstart = HAL_GetTick();
516 
517     /* Wait until SYNCD flag is set */
518     if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
519     {
520       return HAL_TIMEOUT;
521     }
522 
523     /* Start reception */
524     __HAL_SPDIFRX_RCV(hspdif);
525 
526     /* Receive control flow */
527     while (Size > 0U)
528     {
529       /* Get tick */
530       tickstart = HAL_GetTick();
531 
532       /* Wait until CSRNE flag is set */
533       if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_CSRNE, RESET, Timeout, tickstart) != HAL_OK)
534       {
535         return HAL_TIMEOUT;
536       }
537 
538       (*pData++) = hspdif->Instance->CSR;
539       Size--;
540     }
541 
542     /* SPDIFRX ready */
543     hspdif->State = HAL_SPDIFRX_STATE_READY;
544 
545     /* Process Unlocked */
546     __HAL_UNLOCK(hspdif);
547 
548     return HAL_OK;
549   }
550   else
551   {
552     return HAL_BUSY;
553   }
554 }
555 
556 /**
557   * @brief Receive an amount of data (Data Flow) in non-blocking mode with Interrupt
558   * @param hspdif: SPDIFRX handle
559   * @param pData: a 32-bit pointer to the Receive data buffer.
560   * @param Size: number of data sample to be received .
561   * @retval HAL status
562   */
HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)563 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
564 {
565   uint32_t tickstart = 0U;
566 
567   if ((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_CX))
568   {
569     if ((pData == NULL) || (Size == 0U))
570     {
571       return HAL_ERROR;
572     }
573 
574     /* Process Locked */
575     __HAL_LOCK(hspdif);
576 
577     hspdif->pRxBuffPtr = pData;
578     hspdif->RxXferSize = Size;
579     hspdif->RxXferCount = Size;
580 
581     hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
582 
583     /* Check if a receive process is ongoing or not */
584     hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
585 
586 
587     /* Enable the SPDIFRX  PE Error Interrupt */
588     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
589 
590     /* Enable the SPDIFRX  OVR Error Interrupt */
591     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
592 
593     /* Process Unlocked */
594     __HAL_UNLOCK(hspdif);
595 
596     /* Enable the SPDIFRX RXNE interrupt */
597     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_RXNE);
598 
599     if (((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC) || ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00U))
600     {
601       /* Start synchronization */
602       __HAL_SPDIFRX_SYNC(hspdif);
603 
604       /* Get tick */
605       tickstart = HAL_GetTick();
606 
607       /* Wait until SYNCD flag is set */
608       if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE, tickstart) != HAL_OK)
609       {
610         return HAL_TIMEOUT;
611       }
612 
613       /* Start reception */
614       __HAL_SPDIFRX_RCV(hspdif);
615     }
616 
617     return HAL_OK;
618   }
619   else
620   {
621     return HAL_BUSY;
622   }
623 }
624 
625 /**
626   * @brief Receive an amount of data (Control Flow) with Interrupt
627   * @param hspdif: SPDIFRX handle
628   * @param pData: a 32-bit pointer to the Receive data buffer.
629   * @param Size: number of data sample (Control Flow) to be received :
630   * @retval HAL status
631   */
HAL_SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)632 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
633 {
634   uint32_t tickstart = 0U;
635 
636   if ((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_RX))
637   {
638     if ((pData == NULL) || (Size == 0U))
639     {
640       return HAL_ERROR;
641     }
642 
643     /* Process Locked */
644     __HAL_LOCK(hspdif);
645 
646     hspdif->pCsBuffPtr = pData;
647     hspdif->CsXferSize = Size;
648     hspdif->CsXferCount = Size;
649 
650     hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
651 
652     /* Check if a receive process is ongoing or not */
653     hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
654 
655 
656     /* Enable the SPDIFRX PE Error Interrupt */
657     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
658 
659     /* Enable the SPDIFRX OVR Error Interrupt */
660     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
661 
662     /* Process Unlocked */
663     __HAL_UNLOCK(hspdif);
664 
665     /* Enable the SPDIFRX CSRNE interrupt */
666     __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
667 
668     if (((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC) || ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00U))
669     {
670       /* Start synchronization */
671       __HAL_SPDIFRX_SYNC(hspdif);
672 
673       /* Get tick */
674       tickstart = HAL_GetTick();
675 
676       /* Wait until SYNCD flag is set */
677       if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE, tickstart) != HAL_OK)
678       {
679         return HAL_TIMEOUT;
680       }
681 
682       /* Start reception */
683       __HAL_SPDIFRX_RCV(hspdif);
684     }
685 
686     return HAL_OK;
687   }
688   else
689   {
690     return HAL_BUSY;
691   }
692 }
693 
694 /**
695   * @brief Receive an amount of data (Data Flow) mode with DMA
696   * @param hspdif: SPDIFRX handle
697   * @param pData: a 32-bit pointer to the Receive data buffer.
698   * @param Size: number of data sample to be received :
699   * @retval HAL status
700   */
HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)701 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
702 {
703   uint32_t tickstart = 0U;
704 
705   if ((pData == NULL) || (Size == 0U))
706   {
707     return  HAL_ERROR;
708   }
709 
710   if ((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_CX))
711   {
712     hspdif->pRxBuffPtr = pData;
713     hspdif->RxXferSize = Size;
714     hspdif->RxXferCount = Size;
715 
716     /* Process Locked */
717     __HAL_LOCK(hspdif);
718 
719     hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
720     hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
721 
722     /* Set the SPDIFRX Rx DMA Half transfer complete callback */
723     hspdif->hdmaDrRx->XferHalfCpltCallback = SPDIFRX_DMARxHalfCplt;
724 
725     /* Set the SPDIFRX Rx DMA transfer complete callback */
726     hspdif->hdmaDrRx->XferCpltCallback = SPDIFRX_DMARxCplt;
727 
728     /* Set the DMA error callback */
729     hspdif->hdmaDrRx->XferErrorCallback = SPDIFRX_DMAError;
730 
731     /* Enable the DMA request */
732     HAL_DMA_Start_IT(hspdif->hdmaDrRx, (uint32_t)&hspdif->Instance->DR, (uint32_t)hspdif->pRxBuffPtr, Size);
733 
734     /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/
735     hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN;
736 
737     if (((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC) || ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00U))
738     {
739       /* Start synchronization */
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, SPDIFRX_TIMEOUT_VALUE, tickstart) != HAL_OK)
747       {
748         return HAL_TIMEOUT;
749       }
750 
751       /* Start reception */
752       __HAL_SPDIFRX_RCV(hspdif);
753     }
754 
755     /* Process Unlocked */
756     __HAL_UNLOCK(hspdif);
757 
758     return HAL_OK;
759   }
760   else
761   {
762     return HAL_BUSY;
763   }
764 }
765 
766 /**
767   * @brief Receive an amount of data (Control Flow) with DMA
768   * @param hspdif: SPDIFRX handle
769   * @param pData: a 32-bit pointer to the Receive data buffer.
770   * @param Size: number of data (Control Flow) sample to be received :
771   * @retval HAL status
772   */
HAL_SPDIFRX_ReceiveControlFlow_DMA(SPDIFRX_HandleTypeDef * hspdif,uint32_t * pData,uint16_t Size)773 HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
774 {
775   uint32_t tickstart = 0U;
776 
777   if ((pData == NULL) || (Size == 0U))
778   {
779     return  HAL_ERROR;
780   }
781 
782   if ((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_RX))
783   {
784     hspdif->pCsBuffPtr = pData;
785     hspdif->CsXferSize = Size;
786     hspdif->CsXferCount = Size;
787 
788     /* Process Locked */
789     __HAL_LOCK(hspdif);
790 
791     hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
792     hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
793 
794     /* Set the SPDIFRX Rx DMA Half transfer complete callback */
795     hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt;
796 
797     /* Set the SPDIFRX Rx DMA transfer complete callback */
798     hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt;
799 
800     /* Set the DMA error callback */
801     hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError;
802 
803     /* Enable the DMA request */
804     HAL_DMA_Start_IT(hspdif->hdmaCsRx, (uint32_t)&hspdif->Instance->CSR, (uint32_t)hspdif->pCsBuffPtr, Size);
805 
806     /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/
807     hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN;
808 
809     if (((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC) || ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00U))
810     {
811       /* Start synchronization */
812       __HAL_SPDIFRX_SYNC(hspdif);
813 
814       /* Get tick */
815       tickstart = HAL_GetTick();
816 
817       /* Wait until SYNCD flag is set */
818       if (SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE, tickstart) != HAL_OK)
819       {
820         return HAL_TIMEOUT;
821       }
822 
823       /* Start reception */
824       __HAL_SPDIFRX_RCV(hspdif);
825     }
826 
827     /* Process Unlocked */
828     __HAL_UNLOCK(hspdif);
829 
830     return HAL_OK;
831   }
832   else
833   {
834     return HAL_BUSY;
835   }
836 }
837 
838 /**
839   * @brief stop the audio stream receive from the Media.
840   * @param hspdif: SPDIFRX handle
841   * @retval None
842   */
HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef * hspdif)843 HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif)
844 {
845   /* Process Locked */
846   __HAL_LOCK(hspdif);
847 
848   /* Disable the SPDIFRX DMA requests */
849   hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
850   hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
851 
852   /* Disable the SPDIFRX DMA channel */
853   __HAL_DMA_DISABLE(hspdif->hdmaDrRx);
854   __HAL_DMA_DISABLE(hspdif->hdmaCsRx);
855 
856   /* Disable SPDIFRX peripheral */
857   __HAL_SPDIFRX_IDLE(hspdif);
858 
859   hspdif->State = HAL_SPDIFRX_STATE_READY;
860 
861   /* Process Unlocked */
862   __HAL_UNLOCK(hspdif);
863 
864   return HAL_OK;
865 }
866 
867 /**
868   * @brief  This function handles SPDIFRX interrupt request.
869   * @param  hspdif: SPDIFRX handle
870   * @retval HAL status
871   */
HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef * hspdif)872 void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif)
873 {
874   /* SPDIFRX in mode Data Flow Reception ------------------------------------------------*/
875   if ((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_RXNE) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_RXNE) != RESET))
876   {
877     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE);
878     SPDIFRX_ReceiveDataFlow_IT(hspdif);
879   }
880 
881   /* SPDIFRX Synchronization done  -------------------------------------------------------*/
882   if ((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_IT_SYNCDIE) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_SYNCDIE) != RESET))
883   {
884     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_SYNCDIE);
885   }
886 
887   /* SPDIFRX Synchronization Block detected  ---------------------------------------------*/
888   if ((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_IT_SBLKIE) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_SBLKIE) != RESET))
889   {
890     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_SBLKIE);
891   }
892 
893   /* SPDIFRX in mode Control Flow Reception ------------------------------------------------*/
894   if ((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_CSRNE) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_CSRNE) != RESET))
895   {
896     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE);
897     SPDIFRX_ReceiveControlFlow_IT(hspdif);
898   }
899 
900   /* SPDIFRX Overrun error interrupt occurred ---------------------------------*/
901   if ((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_OVR) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_OVRIE) != RESET))
902   {
903     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_FLAG_OVR);
904 
905     /* Change the SPDIFRX error code */
906     hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR;
907 
908     /* the transfer is not stopped */
909     HAL_SPDIFRX_ErrorCallback(hspdif);
910   }
911 
912   /* SPDIFRX Parity error interrupt occurred ---------------------------------*/
913   if ((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_PERR) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_PERRIE) != RESET))
914   {
915     __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_FLAG_PERR);
916 
917     /* Change the SPDIFRX error code */
918     hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE;
919 
920     /* the transfer is not stopped */
921     HAL_SPDIFRX_ErrorCallback(hspdif);
922   }
923 }
924 
925 /**
926   * @brief Rx Transfer (Data flow) half completed callbacks
927   * @param hspdif: SPDIFRX handle
928   * @retval None
929   */
HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef * hspdif)930 __weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
931 {
932   /* Prevent unused argument(s) compilation warning */
933   UNUSED(hspdif);
934 
935   /* NOTE : This function Should not be modified, when the callback is needed,
936   the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
937   */
938 }
939 
940 /**
941   * @brief Rx Transfer (Data flow) completed callbacks
942   * @param hspdif: SPDIFRX handle
943   * @retval None
944   */
HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef * hspdif)945 __weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
946 {
947   /* Prevent unused argument(s) compilation warning */
948   UNUSED(hspdif);
949 
950   /* NOTE : This function Should not be modified, when the callback is needed,
951   the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
952   */
953 }
954 
955 /**
956   * @brief Rx (Control flow) Transfer half completed callbacks
957   * @param hspdif: SPDIFRX handle
958   * @retval None
959   */
HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef * hspdif)960 __weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
961 {
962   /* Prevent unused argument(s) compilation warning */
963   UNUSED(hspdif);
964 
965   /* NOTE : This function Should not be modified, when the callback is needed,
966   the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
967   */
968 }
969 
970 /**
971   * @brief Rx Transfer (Control flow) completed callbacks
972   * @param hspdif: SPDIFRX handle
973   * @retval None
974   */
HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef * hspdif)975 __weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
976 {
977   /* Prevent unused argument(s) compilation warning */
978   UNUSED(hspdif);
979 
980   /* NOTE : This function Should not be modified, when the callback is needed,
981   the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
982   */
983 }
984 
985 /**
986   * @brief SPDIFRX error callbacks
987   * @param hspdif: SPDIFRX handle
988   * @retval None
989   */
HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef * hspdif)990 __weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif)
991 {
992   /* Prevent unused argument(s) compilation warning */
993   UNUSED(hspdif);
994 
995   /* NOTE : This function Should not be modified, when the callback is needed,
996   the HAL_SPDIFRX_ErrorCallback could be implemented in the user file
997   */
998 }
999 
1000 /**
1001   * @}
1002   */
1003 
1004 /** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions
1005   *  @brief   Peripheral State functions
1006   *
1007 @verbatim
1008 ===============================================================================
1009 ##### Peripheral State and Errors functions #####
1010 ===============================================================================
1011 [..]
1012 This subsection permit to get in run-time the status of the peripheral
1013 and the data flow.
1014 
1015 @endverbatim
1016   * @{
1017   */
1018 
1019 /**
1020   * @brief  Return the SPDIFRX state
1021   * @param  hspdif : SPDIFRX handle
1022   * @retval HAL state
1023   */
HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef * hspdif)1024 HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef *hspdif)
1025 {
1026   return hspdif->State;
1027 }
1028 
1029 /**
1030   * @brief  Return the SPDIFRX error code
1031   * @param  hspdif : SPDIFRX handle
1032   * @retval SPDIFRX Error Code
1033   */
HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef * hspdif)1034 uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef *hspdif)
1035 {
1036   return hspdif->ErrorCode;
1037 }
1038 
1039 /**
1040   * @}
1041   */
1042 
1043 /**
1044   * @brief DMA SPDIFRX receive process (Data flow) complete callback
1045   * @param hdma : DMA handle
1046   * @retval None
1047   */
SPDIFRX_DMARxCplt(DMA_HandleTypeDef * hdma)1048 static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma)
1049 {
1050   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1051 
1052   /* Disable Rx DMA Request */
1053   if (hdma->Init.Mode != DMA_CIRCULAR)
1054   {
1055     hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
1056     hspdif->RxXferCount = 0;
1057     hspdif->State = HAL_SPDIFRX_STATE_READY;
1058   }
1059   HAL_SPDIFRX_RxCpltCallback(hspdif);
1060 }
1061 
1062 /**
1063   * @brief DMA SPDIFRX receive process (Data flow) half complete callback
1064   * @param hdma : DMA handle
1065   * @retval None
1066   */
SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1067 static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1068 {
1069   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1070 
1071   HAL_SPDIFRX_RxHalfCpltCallback(hspdif);
1072 }
1073 
1074 
1075 /**
1076   * @brief DMA SPDIFRX receive process (Control flow) complete callback
1077   * @param hdma : DMA handle
1078   * @retval None
1079   */
SPDIFRX_DMACxCplt(DMA_HandleTypeDef * hdma)1080 static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma)
1081 {
1082   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1083 
1084   /* Disable Cb DMA Request */
1085   hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
1086   hspdif->CsXferCount = 0;
1087 
1088   hspdif->State = HAL_SPDIFRX_STATE_READY;
1089   HAL_SPDIFRX_CxCpltCallback(hspdif);
1090 }
1091 
1092 /**
1093   * @brief DMA SPDIFRX receive process (Control flow) half complete callback
1094   * @param hdma : DMA handle
1095   * @retval None
1096   */
SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef * hdma)1097 static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma)
1098 {
1099   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1100 
1101   HAL_SPDIFRX_CxHalfCpltCallback(hspdif);
1102 }
1103 
1104 /**
1105   * @brief DMA SPDIFRX communication error callback
1106   * @param hdma : DMA handle
1107   * @retval None
1108   */
SPDIFRX_DMAError(DMA_HandleTypeDef * hdma)1109 static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma)
1110 {
1111   SPDIFRX_HandleTypeDef *hspdif = (SPDIFRX_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1112 
1113   /* Disable Rx and Cb DMA Request */
1114   hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN));
1115   hspdif->RxXferCount = 0;
1116 
1117   hspdif->State = HAL_SPDIFRX_STATE_READY;
1118 
1119   /* Set the error code and execute error callback*/
1120   hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA;
1121   HAL_SPDIFRX_ErrorCallback(hspdif);
1122 }
1123 
1124 /**
1125   * @brief Receive an amount of data (Data Flow) with Interrupt
1126   * @param hspdif: SPDIFRX handle
1127   * @retval None
1128   */
SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef * hspdif)1129 static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1130 {
1131   /* Receive data */
1132   (*hspdif->pRxBuffPtr++) = hspdif->Instance->DR;
1133   hspdif->RxXferCount--;
1134 
1135   if (hspdif->RxXferCount == 0)
1136   {
1137     /* Disable RXNE/PE and OVR interrupts */
1138     __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE);
1139 
1140     hspdif->State = HAL_SPDIFRX_STATE_READY;
1141 
1142     /* Process Unlocked */
1143     __HAL_UNLOCK(hspdif);
1144 
1145     HAL_SPDIFRX_RxCpltCallback(hspdif);
1146   }
1147 }
1148 
1149 /**
1150   * @brief Receive an amount of data (Control Flow) with Interrupt
1151   * @param hspdif: SPDIFRX handle
1152   * @retval None
1153   */
SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef * hspdif)1154 static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
1155 {
1156   /* Receive data */
1157   (*hspdif->pCsBuffPtr++) = hspdif->Instance->CSR;
1158   hspdif->CsXferCount--;
1159 
1160   if (hspdif->CsXferCount == 0)
1161   {
1162     /* Disable CSRNE interrupt */
1163     __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1164 
1165     hspdif->State = HAL_SPDIFRX_STATE_READY;
1166 
1167     /* Process Unlocked */
1168     __HAL_UNLOCK(hspdif);
1169 
1170     HAL_SPDIFRX_CxCpltCallback(hspdif);
1171   }
1172 }
1173 
1174 /**
1175   * @brief This function handles SPDIFRX Communication Timeout.
1176   * @param hspdif: SPDIFRX handle
1177   * @param Flag: Flag checked
1178   * @param Status: Value of the flag expected
1179   * @param Timeout: Duration of the timeout
1180   * @param tickstart: Tick start value
1181   * @retval HAL status
1182   */
SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef * hspdif,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t tickstart)1183 static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t tickstart)
1184 {
1185   /* Wait until flag is set */
1186   if (Status == RESET)
1187   {
1188     while (__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == RESET)
1189     {
1190       /* Check for the Timeout */
1191       if (Timeout != HAL_MAX_DELAY)
1192       {
1193         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1194         {
1195           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1196           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1197           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1198           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1199           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1200           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1201           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1202           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1203 
1204           hspdif->State = HAL_SPDIFRX_STATE_READY;
1205 
1206           /* Process Unlocked */
1207           __HAL_UNLOCK(hspdif);
1208 
1209           return HAL_TIMEOUT;
1210         }
1211       }
1212     }
1213   }
1214   else
1215   {
1216     while (__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) != RESET)
1217     {
1218       /* Check for the Timeout */
1219       if (Timeout != HAL_MAX_DELAY)
1220       {
1221         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1222         {
1223           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1224           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
1225           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
1226           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
1227           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
1228           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
1229           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
1230           __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
1231 
1232           hspdif->State = HAL_SPDIFRX_STATE_READY;
1233 
1234           /* Process Unlocked */
1235           __HAL_UNLOCK(hspdif);
1236 
1237           return HAL_TIMEOUT;
1238         }
1239       }
1240     }
1241   }
1242   return HAL_OK;
1243 }
1244 
1245 /**
1246 * @}
1247 */
1248 #endif /* SPDIFRX */
1249 #endif /* HAL_SPDIFRX_MODULE_ENABLED */
1250 /**
1251   * @}
1252   */
1253 
1254 /**
1255   * @}
1256   */
1257