Merge pull request #11189 from klutvott123/move-telemetry-displayport-init
[betaflight.git] / lib / main / STM32G4 / Drivers / STM32G4xx_HAL_Driver / Src / stm32g4xx_hal_i2s.c
blobe6c1340a3d4344b119bad50724c30c459206eb3e
1 /**
2 ******************************************************************************
3 * @file stm32g4xx_hal_i2s.c
4 * @author MCD Application Team
5 * @brief I2S HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Integrated Interchip Sound (I2S) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral State and Errors functions
11 @verbatim
12 ===============================================================================
13 ##### How to use this driver #####
14 ===============================================================================
15 [..]
16 The I2S HAL driver can be used as follow:
18 (#) Declare a I2S_HandleTypeDef handle structure.
19 (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
20 (##) Enable the SPIx interface clock.
21 (##) I2S pins configuration:
22 (+++) Enable the clock for the I2S GPIOs.
23 (+++) Configure these I2S pins as alternate function pull-up.
24 (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
25 and HAL_I2S_Receive_IT() APIs).
26 (+++) Configure the I2Sx interrupt priority.
27 (+++) Enable the NVIC I2S IRQ handle.
28 (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
29 and HAL_I2S_Receive_DMA() APIs:
30 (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel.
31 (+++) Enable the DMAx interface clock.
32 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
33 (+++) Configure the DMA Tx/Rx Stream/Channel.
34 (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
35 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
36 DMA Tx/Rx Stream/Channel.
38 (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
39 using HAL_I2S_Init() function.
41 -@- The specific I2S interrupts (Transmission complete interrupt,
42 RXNE interrupt and Error Interrupts) will be managed using the macros
43 __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
44 -@- Make sure that either:
45 (+@) SYSCLK is configured or
46 (+@) PLLADCCLK output is configured or
47 (+@) HSI is enabled or
48 (+@) External clock source is configured after setting correctly
49 the define constant EXTERNAL_CLOCK_VALUE in the stm32g4xx_hal_conf.h file.
51 (#) Three mode of operations are available within this driver :
53 *** Polling mode IO operation ***
54 =================================
55 [..]
56 (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
57 (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
59 *** Interrupt mode IO operation ***
60 ===================================
61 [..]
62 (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
63 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
64 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
65 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
66 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
67 (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
68 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
69 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
70 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
71 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
72 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
73 add his own code by customization of function pointer HAL_I2S_ErrorCallback
75 *** DMA mode IO operation ***
76 ==============================
77 [..]
78 (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
79 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
80 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
81 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
82 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
83 (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
84 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
85 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
86 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
87 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
88 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
89 add his own code by customization of function pointer HAL_I2S_ErrorCallback
90 (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
91 (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
92 (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
94 *** I2S HAL driver macros list ***
95 ===================================
96 [..]
97 Below the list of most used macros in I2S HAL driver.
99 (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
100 (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
101 (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
102 (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
103 (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
105 [..]
106 (@) You can refer to the I2S HAL driver header file for more useful macros
108 *** I2S HAL driver macros list ***
109 ===================================
110 [..]
111 Callback registration:
113 (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1U
114 allows the user to configure dynamically the driver callbacks.
115 Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
117 Function HAL_I2S_RegisterCallback() allows to register following callbacks:
118 (+) TxCpltCallback : I2S Tx Completed callback
119 (+) RxCpltCallback : I2S Rx Completed callback
120 (+) TxHalfCpltCallback : I2S Tx Half Completed callback
121 (+) RxHalfCpltCallback : I2S Rx Half Completed callback
122 (+) ErrorCallback : I2S Error callback
123 (+) MspInitCallback : I2S Msp Init callback
124 (+) MspDeInitCallback : I2S Msp DeInit callback
125 This function takes as parameters the HAL peripheral handle, the Callback ID
126 and a pointer to the user callback function.
129 (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default
130 weak function.
131 HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
132 and the Callback ID.
133 This function allows to reset following callbacks:
134 (+) TxCpltCallback : I2S Tx Completed callback
135 (+) RxCpltCallback : I2S Rx Completed callback
136 (+) TxHalfCpltCallback : I2S Tx Half Completed callback
137 (+) RxHalfCpltCallback : I2S Rx Half Completed callback
138 (+) ErrorCallback : I2S Error callback
139 (+) MspInitCallback : I2S Msp Init callback
140 (+) MspDeInitCallback : I2S Msp DeInit callback
142 By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
143 all callbacks are set to the corresponding weak functions:
144 examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
145 Exception done for MspInit and MspDeInit functions that are
146 reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
147 these callbacks are null (not registered beforehand).
148 If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
149 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
151 Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
152 Exception done MspInit/MspDeInit functions that can be registered/unregistered
153 in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state,
154 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
155 Then, the user first registers the MspInit/MspDeInit user callbacks
156 using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
157 or HAL_I2S_Init() function.
159 When The compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
160 not defined, the callback registering feature is not available
161 and weak (surcharged) callbacks are used.
163 @endverbatim
164 ******************************************************************************
165 * @attention
167 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
168 * All rights reserved.</center></h2>
170 * This software component is licensed by ST under BSD 3-Clause license,
171 * the "License"; You may not use this file except in compliance with the
172 * License. You may obtain a copy of the License at:
173 * opensource.org/licenses/BSD-3-Clause
175 ******************************************************************************
178 /* Includes ------------------------------------------------------------------*/
179 #include "stm32g4xx_hal.h"
181 #ifdef HAL_I2S_MODULE_ENABLED
183 #if defined(SPI_I2S_SUPPORT)
184 /** @addtogroup STM32G4xx_HAL_Driver
185 * @{
188 /** @defgroup I2S I2S
189 * @brief I2S HAL module driver
190 * @{
193 /* Private typedef -----------------------------------------------------------*/
194 /* Private define ------------------------------------------------------------*/
195 /* Private macro -------------------------------------------------------------*/
196 /* Private variables ---------------------------------------------------------*/
197 /* Private function prototypes -----------------------------------------------*/
198 /** @defgroup I2S_Private_Functions I2S Private Functions
199 * @{
201 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
202 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
203 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
204 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
205 static void I2S_DMAError(DMA_HandleTypeDef *hdma);
206 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
207 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
208 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
209 uint32_t Timeout);
211 * @}
214 /* Exported functions ---------------------------------------------------------*/
216 /** @defgroup I2S_Exported_Functions I2S Exported Functions
217 * @{
220 /** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions
221 * @brief Initialization and Configuration functions
223 @verbatim
224 ===============================================================================
225 ##### Initialization and de-initialization functions #####
226 ===============================================================================
227 [..] This subsection provides a set of functions allowing to initialize and
228 de-initialize the I2Sx peripheral in simplex mode:
230 (+) User must Implement HAL_I2S_MspInit() function in which he configures
231 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
233 (+) Call the function HAL_I2S_Init() to configure the selected device with
234 the selected configuration:
235 (++) Mode
236 (++) Standard
237 (++) Data Format
238 (++) MCLK Output
239 (++) Audio frequency
240 (++) Polarity
242 (+) Call the function HAL_I2S_DeInit() to restore the default configuration
243 of the selected I2Sx peripheral.
244 @endverbatim
245 * @{
249 * @brief Initializes the I2S according to the specified parameters
250 * in the I2S_InitTypeDef and create the associated handle.
251 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
252 * the configuration information for I2S module
253 * @retval HAL status
255 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
257 uint32_t i2sdiv;
258 uint32_t i2sodd;
259 uint32_t packetlength;
260 uint32_t tmp;
261 uint32_t i2sclk;
263 /* Check the I2S handle allocation */
264 if (hi2s == NULL)
266 return HAL_ERROR;
269 /* Check the I2S parameters */
270 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
271 assert_param(IS_I2S_MODE(hi2s->Init.Mode));
272 assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
273 assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
274 assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
275 assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
276 assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
278 if (hi2s->State == HAL_I2S_STATE_RESET)
280 /* Allocate lock resource and initialize it */
281 hi2s->Lock = HAL_UNLOCKED;
283 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
284 /* Init the I2S Callback settings */
285 hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */
286 hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */
287 hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
288 hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
289 hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */
291 if (hi2s->MspInitCallback == NULL)
293 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
296 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
297 hi2s->MspInitCallback(hi2s);
298 #else
299 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
300 HAL_I2S_MspInit(hi2s);
301 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
304 hi2s->State = HAL_I2S_STATE_BUSY;
306 /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
307 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
308 CLEAR_BIT(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
309 SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
310 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD));
311 hi2s->Instance->I2SPR = 0x0002U;
313 /*----------------------- I2SPR: I2SDIV and ODD Calculation -----------------*/
314 /* If the requested audio frequency is not the default, compute the prescaler */
315 if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
317 /* Check the frame length (For the Prescaler computing) ********************/
318 if (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B)
320 /* Packet length is 16 bits */
321 packetlength = 16U;
323 else
325 /* Packet length is 32 bits */
326 packetlength = 32U;
329 /* I2S standard */
330 if (hi2s->Init.Standard <= I2S_STANDARD_LSB)
332 /* In I2S standard packet lenght is multiplied by 2 */
333 packetlength = packetlength * 2U;
336 /* Get the source clock value: based on System Clock value */
337 i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S);
339 /* Compute the Real divider depending on the MCLK output state, with a floating point */
340 if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
342 /* MCLK output is enabled */
343 if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
345 tmp = (uint32_t)(((((i2sclk / (packetlength * 4U)) * 10U) / hi2s->Init.AudioFreq)) + 5U);
347 else
349 tmp = (uint32_t)(((((i2sclk / (packetlength * 8U)) * 10U) / hi2s->Init.AudioFreq)) + 5U);
352 else
354 /* MCLK output is disabled */
355 tmp = (uint32_t)(((((i2sclk / packetlength) * 10U) / hi2s->Init.AudioFreq)) + 5U);
358 /* Remove the flatting point */
359 tmp = tmp / 10U;
361 /* Check the parity of the divider */
362 i2sodd = (uint32_t)(tmp & (uint32_t)1U);
364 /* Compute the i2sdiv prescaler */
365 i2sdiv = (uint32_t)((tmp - i2sodd) / 2U);
367 /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
368 i2sodd = (uint32_t)(i2sodd << 8U);
370 else
372 /* Set the default values */
373 i2sdiv = 2U;
374 i2sodd = 0U;
377 /* Test if the divider is 1 or 0 or greater than 0xFF */
378 if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
380 /* Set the error code and execute error callback*/
381 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
382 return HAL_ERROR;
385 /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
387 /* Write to SPIx I2SPR register the computed value */
388 hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput));
390 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
391 /* And configure the I2S with the I2S_InitStruct values */
392 MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
393 SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
394 SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
395 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD), \
396 (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | \
397 hi2s->Init.Standard | hi2s->Init.DataFormat | \
398 hi2s->Init.CPOL));
400 #if defined(SPI_I2SCFGR_ASTRTEN)
401 if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) || ((hi2s->Init.Standard == I2S_STANDARD_PCM_LONG)))
403 /* Write to SPIx I2SCFGR */
404 SET_BIT(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_ASTRTEN);
406 #endif /* SPI_I2SCFGR_ASTRTEN */
408 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
409 hi2s->State = HAL_I2S_STATE_READY;
411 return HAL_OK;
415 * @brief DeInitializes the I2S peripheral
416 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
417 * the configuration information for I2S module
418 * @retval HAL status
420 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
422 /* Check the I2S handle allocation */
423 if (hi2s == NULL)
425 return HAL_ERROR;
428 /* Check the parameters */
429 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
431 hi2s->State = HAL_I2S_STATE_BUSY;
433 /* Disable the I2S Peripheral Clock */
434 __HAL_I2S_DISABLE(hi2s);
436 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
437 if (hi2s->MspDeInitCallback == NULL)
439 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
442 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
443 hi2s->MspDeInitCallback(hi2s);
444 #else
445 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
446 HAL_I2S_MspDeInit(hi2s);
447 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
449 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
450 hi2s->State = HAL_I2S_STATE_RESET;
452 /* Release Lock */
453 __HAL_UNLOCK(hi2s);
455 return HAL_OK;
459 * @brief I2S MSP Init
460 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
461 * the configuration information for I2S module
462 * @retval None
464 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
466 /* Prevent unused argument(s) compilation warning */
467 UNUSED(hi2s);
469 /* NOTE : This function Should not be modified, when the callback is needed,
470 the HAL_I2S_MspInit could be implemented in the user file
475 * @brief I2S MSP DeInit
476 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
477 * the configuration information for I2S module
478 * @retval None
480 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
482 /* Prevent unused argument(s) compilation warning */
483 UNUSED(hi2s);
485 /* NOTE : This function Should not be modified, when the callback is needed,
486 the HAL_I2S_MspDeInit could be implemented in the user file
490 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
492 * @brief Register a User I2S Callback
493 * To be used instead of the weak predefined callback
494 * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains
495 * the configuration information for the specified I2S.
496 * @param CallbackID ID of the callback to be registered
497 * @param pCallback pointer to the Callback function
498 * @retval HAL status
500 HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID,
501 pI2S_CallbackTypeDef pCallback)
503 HAL_StatusTypeDef status = HAL_OK;
505 if (pCallback == NULL)
507 /* Update the error code */
508 hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
510 return HAL_ERROR;
512 /* Process locked */
513 __HAL_LOCK(hi2s);
515 if (HAL_I2S_STATE_READY == hi2s->State)
517 switch (CallbackID)
519 case HAL_I2S_TX_COMPLETE_CB_ID :
520 hi2s->TxCpltCallback = pCallback;
521 break;
523 case HAL_I2S_RX_COMPLETE_CB_ID :
524 hi2s->RxCpltCallback = pCallback;
525 break;
527 case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
528 hi2s->TxHalfCpltCallback = pCallback;
529 break;
531 case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
532 hi2s->RxHalfCpltCallback = pCallback;
533 break;
535 case HAL_I2S_ERROR_CB_ID :
536 hi2s->ErrorCallback = pCallback;
537 break;
539 case HAL_I2S_MSPINIT_CB_ID :
540 hi2s->MspInitCallback = pCallback;
541 break;
543 case HAL_I2S_MSPDEINIT_CB_ID :
544 hi2s->MspDeInitCallback = pCallback;
545 break;
547 default :
548 /* Update the error code */
549 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
551 /* Return error status */
552 status = HAL_ERROR;
553 break;
556 else if (HAL_I2S_STATE_RESET == hi2s->State)
558 switch (CallbackID)
560 case HAL_I2S_MSPINIT_CB_ID :
561 hi2s->MspInitCallback = pCallback;
562 break;
564 case HAL_I2S_MSPDEINIT_CB_ID :
565 hi2s->MspDeInitCallback = pCallback;
566 break;
568 default :
569 /* Update the error code */
570 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
572 /* Return error status */
573 status = HAL_ERROR;
574 break;
577 else
579 /* Update the error code */
580 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
582 /* Return error status */
583 status = HAL_ERROR;
586 /* Release Lock */
587 __HAL_UNLOCK(hi2s);
588 return status;
592 * @brief Unregister an I2S Callback
593 * I2S callback is redirected to the weak predefined callback
594 * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains
595 * the configuration information for the specified I2S.
596 * @param CallbackID ID of the callback to be unregistered
597 * @retval HAL status
599 HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
601 HAL_StatusTypeDef status = HAL_OK;
603 /* Process locked */
604 __HAL_LOCK(hi2s);
606 if (HAL_I2S_STATE_READY == hi2s->State)
608 switch (CallbackID)
610 case HAL_I2S_TX_COMPLETE_CB_ID :
611 hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */
612 break;
614 case HAL_I2S_RX_COMPLETE_CB_ID :
615 hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */
616 break;
618 case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
619 hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
620 break;
622 case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
623 hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
624 break;
626 case HAL_I2S_ERROR_CB_ID :
627 hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */
628 break;
630 case HAL_I2S_MSPINIT_CB_ID :
631 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
632 break;
634 case HAL_I2S_MSPDEINIT_CB_ID :
635 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
636 break;
638 default :
639 /* Update the error code */
640 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
642 /* Return error status */
643 status = HAL_ERROR;
644 break;
647 else if (HAL_I2S_STATE_RESET == hi2s->State)
649 switch (CallbackID)
651 case HAL_I2S_MSPINIT_CB_ID :
652 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
653 break;
655 case HAL_I2S_MSPDEINIT_CB_ID :
656 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
657 break;
659 default :
660 /* Update the error code */
661 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
663 /* Return error status */
664 status = HAL_ERROR;
665 break;
668 else
670 /* Update the error code */
671 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
673 /* Return error status */
674 status = HAL_ERROR;
677 /* Release Lock */
678 __HAL_UNLOCK(hi2s);
679 return status;
681 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
683 * @}
686 /** @defgroup I2S_Exported_Functions_Group2 IO operation functions
687 * @brief Data transfers functions
689 @verbatim
690 ===============================================================================
691 ##### IO operation functions #####
692 ===============================================================================
693 [..]
694 This subsection provides a set of functions allowing to manage the I2S data
695 transfers.
697 (#) There are two modes of transfer:
698 (++) Blocking mode : The communication is performed in the polling mode.
699 The status of all data processing is returned by the same function
700 after finishing transfer.
701 (++) No-Blocking mode : The communication is performed using Interrupts
702 or DMA. These functions return the status of the transfer startup.
703 The end of the data processing will be indicated through the
704 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
705 using DMA mode.
707 (#) Blocking mode functions are :
708 (++) HAL_I2S_Transmit()
709 (++) HAL_I2S_Receive()
711 (#) No-Blocking mode functions with Interrupt are :
712 (++) HAL_I2S_Transmit_IT()
713 (++) HAL_I2S_Receive_IT()
715 (#) No-Blocking mode functions with DMA are :
716 (++) HAL_I2S_Transmit_DMA()
717 (++) HAL_I2S_Receive_DMA()
719 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
720 (++) HAL_I2S_TxCpltCallback()
721 (++) HAL_I2S_RxCpltCallback()
722 (++) HAL_I2S_ErrorCallback()
724 @endverbatim
725 * @{
729 * @brief Transmit an amount of data in blocking mode
730 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
731 * the configuration information for I2S module
732 * @param pData a 16-bit pointer to data buffer.
733 * @param Size number of data sample to be sent:
734 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
735 * configuration phase, the Size parameter means the number of 16-bit data length
736 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
737 * the Size parameter means the number of 16-bit data length.
738 * @param Timeout Timeout duration
739 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
740 * between Master and Slave(example: audio streaming).
741 * @retval HAL status
743 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
745 uint32_t tmpreg_cfgr;
747 if ((pData == NULL) || (Size == 0U))
749 return HAL_ERROR;
752 /* Process Locked */
753 __HAL_LOCK(hi2s);
755 if (hi2s->State != HAL_I2S_STATE_READY)
757 __HAL_UNLOCK(hi2s);
758 return HAL_BUSY;
761 /* Set state and reset error code */
762 hi2s->State = HAL_I2S_STATE_BUSY_TX;
763 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
764 hi2s->pTxBuffPtr = pData;
766 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
768 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
770 hi2s->TxXferSize = (Size << 1U);
771 hi2s->TxXferCount = (Size << 1U);
773 else
775 hi2s->TxXferSize = Size;
776 hi2s->TxXferCount = Size;
779 tmpreg_cfgr = hi2s->Instance->I2SCFGR;
781 /* Check if the I2S is already enabled */
782 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
784 /* Enable I2S peripheral */
785 __HAL_I2S_ENABLE(hi2s);
788 /* Wait until TXE flag is set */
789 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
791 /* Set the error code */
792 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
793 hi2s->State = HAL_I2S_STATE_READY;
794 __HAL_UNLOCK(hi2s);
795 return HAL_ERROR;
798 while (hi2s->TxXferCount > 0U)
800 hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
801 hi2s->pTxBuffPtr++;
802 hi2s->TxXferCount--;
804 /* Wait until TXE flag is set */
805 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
807 /* Set the error code */
808 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
809 hi2s->State = HAL_I2S_STATE_READY;
810 __HAL_UNLOCK(hi2s);
811 return HAL_ERROR;
814 /* Check if an underrun occurs */
815 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
817 /* Clear underrun flag */
818 __HAL_I2S_CLEAR_UDRFLAG(hi2s);
820 /* Set the error code */
821 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
825 /* Check if Slave mode is selected */
826 if (((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)
827 || ((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX))
829 /* Wait until Busy flag is reset */
830 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK)
832 /* Set the error code */
833 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
834 hi2s->State = HAL_I2S_STATE_READY;
835 __HAL_UNLOCK(hi2s);
836 return HAL_ERROR;
840 hi2s->State = HAL_I2S_STATE_READY;
841 __HAL_UNLOCK(hi2s);
842 return HAL_OK;
846 * @brief Receive an amount of data in blocking mode
847 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
848 * the configuration information for I2S module
849 * @param pData a 16-bit pointer to data buffer.
850 * @param Size number of data sample to be sent:
851 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
852 * configuration phase, the Size parameter means the number of 16-bit data length
853 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
854 * the Size parameter means the number of 16-bit data length.
855 * @param Timeout Timeout duration
856 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
857 * between Master and Slave(example: audio streaming).
858 * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
859 * in continuous way and as the I2S is not disabled at the end of the I2S transaction.
860 * @retval HAL status
862 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
864 uint32_t tmpreg_cfgr;
866 if ((pData == NULL) || (Size == 0U))
868 return HAL_ERROR;
871 /* Process Locked */
872 __HAL_LOCK(hi2s);
874 if (hi2s->State != HAL_I2S_STATE_READY)
876 __HAL_UNLOCK(hi2s);
877 return HAL_BUSY;
880 /* Set state and reset error code */
881 hi2s->State = HAL_I2S_STATE_BUSY_RX;
882 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
883 hi2s->pRxBuffPtr = pData;
885 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
887 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
889 hi2s->RxXferSize = (Size << 1U);
890 hi2s->RxXferCount = (Size << 1U);
892 else
894 hi2s->RxXferSize = Size;
895 hi2s->RxXferCount = Size;
898 /* Check if the I2S is already enabled */
899 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
901 /* Enable I2S peripheral */
902 __HAL_I2S_ENABLE(hi2s);
905 /* Check if Master Receiver mode is selected */
906 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
908 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
909 access to the SPI_SR register. */
910 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
913 /* Receive data */
914 while (hi2s->RxXferCount > 0U)
916 /* Wait until RXNE flag is set */
917 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
919 /* Set the error code */
920 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
921 hi2s->State = HAL_I2S_STATE_READY;
922 __HAL_UNLOCK(hi2s);
923 return HAL_ERROR;
926 (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
927 hi2s->pRxBuffPtr++;
928 hi2s->RxXferCount--;
930 /* Check if an overrun occurs */
931 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
933 /* Clear overrun flag */
934 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
936 /* Set the error code */
937 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
941 hi2s->State = HAL_I2S_STATE_READY;
942 __HAL_UNLOCK(hi2s);
943 return HAL_OK;
947 * @brief Transmit an amount of data in non-blocking mode with Interrupt
948 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
949 * the configuration information for I2S module
950 * @param pData a 16-bit pointer to data buffer.
951 * @param Size number of data sample to be sent:
952 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
953 * configuration phase, the Size parameter means the number of 16-bit data length
954 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
955 * the Size parameter means the number of 16-bit data length.
956 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
957 * between Master and Slave(example: audio streaming).
958 * @retval HAL status
960 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
962 uint32_t tmpreg_cfgr;
964 if ((pData == NULL) || (Size == 0U))
966 return HAL_ERROR;
969 /* Process Locked */
970 __HAL_LOCK(hi2s);
972 if (hi2s->State != HAL_I2S_STATE_READY)
974 __HAL_UNLOCK(hi2s);
975 return HAL_BUSY;
978 /* Set state and reset error code */
979 hi2s->State = HAL_I2S_STATE_BUSY_TX;
980 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
981 hi2s->pTxBuffPtr = pData;
983 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
985 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
987 hi2s->TxXferSize = (Size << 1U);
988 hi2s->TxXferCount = (Size << 1U);
990 else
992 hi2s->TxXferSize = Size;
993 hi2s->TxXferCount = Size;
996 /* Enable TXE and ERR interrupt */
997 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
999 /* Check if the I2S is already enabled */
1000 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1002 /* Enable I2S peripheral */
1003 __HAL_I2S_ENABLE(hi2s);
1006 __HAL_UNLOCK(hi2s);
1007 return HAL_OK;
1011 * @brief Receive an amount of data in non-blocking mode with Interrupt
1012 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1013 * the configuration information for I2S module
1014 * @param pData a 16-bit pointer to the Receive data buffer.
1015 * @param Size number of data sample to be sent:
1016 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1017 * configuration phase, the Size parameter means the number of 16-bit data length
1018 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1019 * the Size parameter means the number of 16-bit data length.
1020 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1021 * between Master and Slave(example: audio streaming).
1022 * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronization
1023 * between Master and Slave otherwise the I2S interrupt should be optimized.
1024 * @retval HAL status
1026 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1028 uint32_t tmpreg_cfgr;
1030 if ((pData == NULL) || (Size == 0U))
1032 return HAL_ERROR;
1035 /* Process Locked */
1036 __HAL_LOCK(hi2s);
1038 if (hi2s->State != HAL_I2S_STATE_READY)
1040 __HAL_UNLOCK(hi2s);
1041 return HAL_BUSY;
1044 /* Set state and reset error code */
1045 hi2s->State = HAL_I2S_STATE_BUSY_RX;
1046 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1047 hi2s->pRxBuffPtr = pData;
1049 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1051 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1053 hi2s->RxXferSize = (Size << 1U);
1054 hi2s->RxXferCount = (Size << 1U);
1056 else
1058 hi2s->RxXferSize = Size;
1059 hi2s->RxXferCount = Size;
1062 /* Enable RXNE and ERR interrupt */
1063 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1065 /* Check if the I2S is already enabled */
1066 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1068 /* Enable I2S peripheral */
1069 __HAL_I2S_ENABLE(hi2s);
1072 __HAL_UNLOCK(hi2s);
1073 return HAL_OK;
1077 * @brief Transmit an amount of data in non-blocking mode with DMA
1078 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1079 * the configuration information for I2S module
1080 * @param pData a 16-bit pointer to the Transmit data buffer.
1081 * @param Size number of data sample to be sent:
1082 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1083 * configuration phase, the Size parameter means the number of 16-bit data length
1084 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1085 * the Size parameter means the number of 16-bit data length.
1086 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1087 * between Master and Slave(example: audio streaming).
1088 * @retval HAL status
1090 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1092 uint32_t tmpreg_cfgr;
1094 if ((pData == NULL) || (Size == 0U))
1096 return HAL_ERROR;
1099 /* Process Locked */
1100 __HAL_LOCK(hi2s);
1102 if (hi2s->State != HAL_I2S_STATE_READY)
1104 __HAL_UNLOCK(hi2s);
1105 return HAL_BUSY;
1108 /* Set state and reset error code */
1109 hi2s->State = HAL_I2S_STATE_BUSY_TX;
1110 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1111 hi2s->pTxBuffPtr = pData;
1113 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1115 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1117 hi2s->TxXferSize = (Size << 1U);
1118 hi2s->TxXferCount = (Size << 1U);
1120 else
1122 hi2s->TxXferSize = Size;
1123 hi2s->TxXferCount = Size;
1126 /* Set the I2S Tx DMA Half transfer complete callback */
1127 hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
1129 /* Set the I2S Tx DMA transfer complete callback */
1130 hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
1132 /* Set the DMA error callback */
1133 hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
1135 /* Enable the Tx DMA Stream/Channel */
1136 if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx,
1137 (uint32_t)hi2s->pTxBuffPtr,
1138 (uint32_t)&hi2s->Instance->DR,
1139 hi2s->TxXferSize))
1141 /* Update SPI error code */
1142 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1143 hi2s->State = HAL_I2S_STATE_READY;
1145 __HAL_UNLOCK(hi2s);
1146 return HAL_ERROR;
1149 /* Check if the I2S is already enabled */
1150 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1152 /* Enable I2S peripheral */
1153 __HAL_I2S_ENABLE(hi2s);
1156 /* Check if the I2S Tx request is already enabled */
1157 if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN))
1159 /* Enable Tx DMA Request */
1160 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1163 __HAL_UNLOCK(hi2s);
1164 return HAL_OK;
1168 * @brief Receive an amount of data in non-blocking mode with DMA
1169 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1170 * the configuration information for I2S module
1171 * @param pData a 16-bit pointer to the Receive data buffer.
1172 * @param Size number of data sample to be sent:
1173 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1174 * configuration phase, the Size parameter means the number of 16-bit data length
1175 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1176 * the Size parameter means the number of 16-bit data length.
1177 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1178 * between Master and Slave(example: audio streaming).
1179 * @retval HAL status
1181 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1183 uint32_t tmpreg_cfgr;
1185 if ((pData == NULL) || (Size == 0U))
1187 return HAL_ERROR;
1190 /* Process Locked */
1191 __HAL_LOCK(hi2s);
1193 if (hi2s->State != HAL_I2S_STATE_READY)
1195 __HAL_UNLOCK(hi2s);
1196 return HAL_BUSY;
1199 /* Set state and reset error code */
1200 hi2s->State = HAL_I2S_STATE_BUSY_RX;
1201 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1202 hi2s->pRxBuffPtr = pData;
1204 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1206 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1208 hi2s->RxXferSize = (Size << 1U);
1209 hi2s->RxXferCount = (Size << 1U);
1211 else
1213 hi2s->RxXferSize = Size;
1214 hi2s->RxXferCount = Size;
1217 /* Set the I2S Rx DMA Half transfer complete callback */
1218 hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
1220 /* Set the I2S Rx DMA transfer complete callback */
1221 hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
1223 /* Set the DMA error callback */
1224 hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1226 /* Check if Master Receiver mode is selected */
1227 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
1229 /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
1230 access to the SPI_SR register. */
1231 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1234 /* Enable the Rx DMA Stream/Channel */
1235 if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr,
1236 hi2s->RxXferSize))
1238 /* Update SPI error code */
1239 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1240 hi2s->State = HAL_I2S_STATE_READY;
1242 __HAL_UNLOCK(hi2s);
1243 return HAL_ERROR;
1246 /* Check if the I2S is already enabled */
1247 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1249 /* Enable I2S peripheral */
1250 __HAL_I2S_ENABLE(hi2s);
1253 /* Check if the I2S Rx request is already enabled */
1254 if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN))
1256 /* Enable Rx DMA Request */
1257 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1260 __HAL_UNLOCK(hi2s);
1261 return HAL_OK;
1265 * @brief Pauses the audio DMA Stream/Channel playing from the Media.
1266 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1267 * the configuration information for I2S module
1268 * @retval HAL status
1270 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1272 /* Process Locked */
1273 __HAL_LOCK(hi2s);
1275 if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1277 /* Disable the I2S DMA Tx request */
1278 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1280 else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1282 /* Disable the I2S DMA Rx request */
1283 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1285 else
1287 /* nothing to do */
1290 /* Process Unlocked */
1291 __HAL_UNLOCK(hi2s);
1293 return HAL_OK;
1297 * @brief Resumes the audio DMA Stream/Channel playing from the Media.
1298 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1299 * the configuration information for I2S module
1300 * @retval HAL status
1302 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1304 /* Process Locked */
1305 __HAL_LOCK(hi2s);
1307 if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1309 /* Enable the I2S DMA Tx request */
1310 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1312 else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1314 /* Enable the I2S DMA Rx request */
1315 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1317 else
1319 /* nothing to do */
1322 /* If the I2S peripheral is still not enabled, enable it */
1323 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1325 /* Enable I2S peripheral */
1326 __HAL_I2S_ENABLE(hi2s);
1329 /* Process Unlocked */
1330 __HAL_UNLOCK(hi2s);
1332 return HAL_OK;
1336 * @brief Stops the audio DMA Stream/Channel playing from the Media.
1337 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1338 * the configuration information for I2S module
1339 * @retval HAL status
1341 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1343 HAL_StatusTypeDef errorcode = HAL_OK;
1344 /* The Lock is not implemented on this API to allow the user application
1345 to call the HAL SPI API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1346 when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1347 and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1350 /* Disable the I2S Tx/Rx DMA requests */
1351 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1352 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1354 /* Abort the I2S DMA tx Stream/Channel */
1355 if (hi2s->hdmatx != NULL)
1357 /* Disable the I2S DMA tx Stream/Channel */
1358 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1360 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1361 errorcode = HAL_ERROR;
1365 /* Abort the I2S DMA rx Stream/Channel */
1366 if (hi2s->hdmarx != NULL)
1368 /* Disable the I2S DMA rx Stream/Channel */
1369 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1371 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1372 errorcode = HAL_ERROR;
1376 /* Disable I2S peripheral */
1377 __HAL_I2S_DISABLE(hi2s);
1379 hi2s->State = HAL_I2S_STATE_READY;
1381 return errorcode;
1385 * @brief This function handles I2S interrupt request.
1386 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1387 * the configuration information for I2S module
1388 * @retval None
1390 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1392 uint32_t itsource = hi2s->Instance->CR2;
1393 uint32_t itflag = hi2s->Instance->SR;
1395 /* I2S in mode Receiver ------------------------------------------------*/
1396 if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) == RESET) &&
1397 (I2S_CHECK_FLAG(itflag, I2S_FLAG_RXNE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_RXNE) != RESET))
1399 I2S_Receive_IT(hi2s);
1400 return;
1403 /* I2S in mode Tramitter -----------------------------------------------*/
1404 if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_TXE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_TXE) != RESET))
1406 I2S_Transmit_IT(hi2s);
1407 return;
1410 /* I2S interrupt error -------------------------------------------------*/
1411 if (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_ERR) != RESET)
1413 /* I2S Overrun error interrupt occurred ---------------------------------*/
1414 if (I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) != RESET)
1416 /* Disable RXNE and ERR interrupt */
1417 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1419 /* Set the error code and execute error callback*/
1420 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1423 /* I2S Underrun error interrupt occurred --------------------------------*/
1424 if (I2S_CHECK_FLAG(itflag, I2S_FLAG_UDR) != RESET)
1426 /* Disable TXE and ERR interrupt */
1427 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1429 /* Set the error code and execute error callback*/
1430 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1433 /* Set the I2S State ready */
1434 hi2s->State = HAL_I2S_STATE_READY;
1436 /* Call user error callback */
1437 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1438 hi2s->ErrorCallback(hi2s);
1439 #else
1440 HAL_I2S_ErrorCallback(hi2s);
1441 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1446 * @brief Tx Transfer Half completed callbacks
1447 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1448 * the configuration information for I2S module
1449 * @retval None
1451 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1453 /* Prevent unused argument(s) compilation warning */
1454 UNUSED(hi2s);
1456 /* NOTE : This function Should not be modified, when the callback is needed,
1457 the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1462 * @brief Tx Transfer completed callbacks
1463 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1464 * the configuration information for I2S module
1465 * @retval None
1467 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
1469 /* Prevent unused argument(s) compilation warning */
1470 UNUSED(hi2s);
1472 /* NOTE : This function Should not be modified, when the callback is needed,
1473 the HAL_I2S_TxCpltCallback could be implemented in the user file
1478 * @brief Rx Transfer half completed callbacks
1479 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1480 * the configuration information for I2S module
1481 * @retval None
1483 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1485 /* Prevent unused argument(s) compilation warning */
1486 UNUSED(hi2s);
1488 /* NOTE : This function Should not be modified, when the callback is needed,
1489 the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
1494 * @brief Rx Transfer completed callbacks
1495 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1496 * the configuration information for I2S module
1497 * @retval None
1499 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1501 /* Prevent unused argument(s) compilation warning */
1502 UNUSED(hi2s);
1504 /* NOTE : This function Should not be modified, when the callback is needed,
1505 the HAL_I2S_RxCpltCallback could be implemented in the user file
1510 * @brief I2S error callbacks
1511 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1512 * the configuration information for I2S module
1513 * @retval None
1515 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
1517 /* Prevent unused argument(s) compilation warning */
1518 UNUSED(hi2s);
1520 /* NOTE : This function Should not be modified, when the callback is needed,
1521 the HAL_I2S_ErrorCallback could be implemented in the user file
1526 * @}
1529 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1530 * @brief Peripheral State functions
1532 @verbatim
1533 ===============================================================================
1534 ##### Peripheral State and Errors functions #####
1535 ===============================================================================
1536 [..]
1537 This subsection permits to get in run-time the status of the peripheral
1538 and the data flow.
1540 @endverbatim
1541 * @{
1545 * @brief Return the I2S state
1546 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1547 * the configuration information for I2S module
1548 * @retval HAL state
1550 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1552 return hi2s->State;
1556 * @brief Return the I2S error code
1557 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1558 * the configuration information for I2S module
1559 * @retval I2S Error Code
1561 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1563 return hi2s->ErrorCode;
1566 * @}
1570 * @}
1573 /** @addtogroup I2S_Private_Functions I2S Private Functions
1574 * @{
1577 * @brief DMA I2S transmit process complete callback
1578 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1579 * the configuration information for the specified DMA module.
1580 * @retval None
1582 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1584 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1586 /* if DMA is configured in DMA_NORMAL Mode */
1587 if (hdma->Init.Mode == DMA_NORMAL)
1589 /* Disable Tx DMA Request */
1590 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1592 hi2s->TxXferCount = 0U;
1593 hi2s->State = HAL_I2S_STATE_READY;
1595 /* Call user Tx complete callback */
1596 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1597 hi2s->TxCpltCallback(hi2s);
1598 #else
1599 HAL_I2S_TxCpltCallback(hi2s);
1600 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1604 * @brief DMA I2S transmit process half complete callback
1605 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1606 * the configuration information for the specified DMA module.
1607 * @retval None
1609 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1611 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1613 /* Call user Tx half complete callback */
1614 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1615 hi2s->TxHalfCpltCallback(hi2s);
1616 #else
1617 HAL_I2S_TxHalfCpltCallback(hi2s);
1618 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1622 * @brief DMA I2S receive process complete callback
1623 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1624 * the configuration information for the specified DMA module.
1625 * @retval None
1627 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1629 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1631 /* if DMA is configured in DMA_NORMAL Mode */
1632 if (hdma->Init.Mode == DMA_NORMAL)
1634 /* Disable Rx DMA Request */
1635 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1636 hi2s->RxXferCount = 0U;
1637 hi2s->State = HAL_I2S_STATE_READY;
1639 /* Call user Rx complete callback */
1640 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1641 hi2s->RxCpltCallback(hi2s);
1642 #else
1643 HAL_I2S_RxCpltCallback(hi2s);
1644 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1648 * @brief DMA I2S receive process half complete callback
1649 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1650 * the configuration information for the specified DMA module.
1651 * @retval None
1653 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1655 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1657 /* Call user Rx half complete callback */
1658 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1659 hi2s->RxHalfCpltCallback(hi2s);
1660 #else
1661 HAL_I2S_RxHalfCpltCallback(hi2s);
1662 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1666 * @brief DMA I2S communication error callback
1667 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1668 * the configuration information for the specified DMA module.
1669 * @retval None
1671 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1673 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1675 /* Disable Rx and Tx DMA Request */
1676 CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1677 hi2s->TxXferCount = 0U;
1678 hi2s->RxXferCount = 0U;
1680 hi2s->State = HAL_I2S_STATE_READY;
1682 /* Set the error code and execute error callback*/
1683 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1684 /* Call user error callback */
1685 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1686 hi2s->ErrorCallback(hi2s);
1687 #else
1688 HAL_I2S_ErrorCallback(hi2s);
1689 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1693 * @brief Transmit an amount of data in non-blocking mode with Interrupt
1694 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1695 * the configuration information for I2S module
1696 * @retval None
1698 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
1700 /* Transmit data */
1701 hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
1702 hi2s->pTxBuffPtr++;
1703 hi2s->TxXferCount--;
1705 if (hi2s->TxXferCount == 0U)
1707 /* Disable TXE and ERR interrupt */
1708 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1710 hi2s->State = HAL_I2S_STATE_READY;
1711 /* Call user Tx complete callback */
1712 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1713 hi2s->TxCpltCallback(hi2s);
1714 #else
1715 HAL_I2S_TxCpltCallback(hi2s);
1716 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1721 * @brief Receive an amount of data in non-blocking mode with Interrupt
1722 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1723 * the configuration information for I2S module
1724 * @retval None
1726 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
1728 /* Receive data */
1729 (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
1730 hi2s->pRxBuffPtr++;
1731 hi2s->RxXferCount--;
1733 if (hi2s->RxXferCount == 0U)
1735 /* Disable RXNE and ERR interrupt */
1736 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1738 hi2s->State = HAL_I2S_STATE_READY;
1739 /* Call user Rx complete callback */
1740 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1741 hi2s->RxCpltCallback(hi2s);
1742 #else
1743 HAL_I2S_RxCpltCallback(hi2s);
1744 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1749 * @brief This function handles I2S Communication Timeout.
1750 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1751 * the configuration information for I2S module
1752 * @param Flag Flag checked
1753 * @param State Value of the flag expected
1754 * @param Timeout Duration of the timeout
1755 * @retval HAL status
1757 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
1758 uint32_t Timeout)
1760 uint32_t tickstart;
1762 /* Get tick */
1763 tickstart = HAL_GetTick();
1765 /* Wait until flag is set to status*/
1766 while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1768 if (Timeout != HAL_MAX_DELAY)
1770 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
1772 /* Set the I2S State ready */
1773 hi2s->State = HAL_I2S_STATE_READY;
1775 /* Process Unlocked */
1776 __HAL_UNLOCK(hi2s);
1778 return HAL_TIMEOUT;
1782 return HAL_OK;
1786 * @}
1790 * @}
1794 * @}
1796 #endif /* SPI_I2S_SUPPORT */
1798 #endif /* HAL_I2S_MODULE_ENABLED */
1800 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/