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