source: S-port/trunk/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spdifrx.c

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