2 ******************************************************************************
3 * @file stm32f3xx_hal_i2s_ex.c
4 * @author MCD Application Team
7 * @brief I2S Extended HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of I2S Extended peripheral:
10 * + Extended features Functions
13 ==============================================================================
14 ##### I2S Extended features #####
15 ==============================================================================
17 (#) In I2S full duplex mode, each SPI peripheral is able to manage sending and receiving
18 data simultaneously using two data lines. Each SPI peripheral has an extended block
19 called I2Sxext ie. I2S2ext for SPI2 and I2S3ext for SPI3).
20 (#) The Extended block is not a full SPI IP, it is used only as I2S slave to
21 implement full duplex mode. The Extended block uses the same clock sources
22 as its master (refer to the following Figure).
24 +-----------------------+
26 ----------+-->| I2Sx |------------------->I2Sx_SD(in/out)
28 | | +-----------------------+
32 | | +-----------------------+
34 | | I2Sx_ext |------------------->I2Sx_extSD(in/out)
36 +-----------------------+
38 (#) Both I2Sx and I2Sx_ext can be configured as transmitters or receivers.
40 -@- Only I2Sx can deliver SCK and WS to I2Sx_ext in full duplex mode, where
41 I2Sx can be I2S2 or I2S3.
43 ===============================================================================
44 ##### How to use this driver #####
45 ===============================================================================
47 Three mode of operations are available within this driver :
49 *** Polling mode IO operation ***
50 =================================
52 (+) Send and receive in the same time an amount of data in blocking mode using HAL_I2S_TransmitReceive()
54 *** Interrupt mode IO operation ***
55 ===================================
57 (+) Send and receive in the same time an amount of data in non blocking mode using HAL_I2S_TransmitReceive_IT()
58 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
59 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
60 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
61 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
62 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
63 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
64 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
65 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
66 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
67 add his own code by customization of function pointer HAL_I2S_ErrorCallback
69 *** DMA mode IO operation ***
70 ==============================
72 (+) Send and receive an amount of data in non blocking mode (DMA) using HAL_I2S_TransmitReceive_DMA()
73 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
74 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
75 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
76 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
77 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
78 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
79 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
80 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
81 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
82 add his own code by customization of function pointer HAL_I2S_ErrorCallback
83 (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
84 (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
85 (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
88 ******************************************************************************
91 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
93 * Redistribution and use in source and binary forms, with or without modification,
94 * are permitted provided that the following conditions are met:
95 * 1. Redistributions of source code must retain the above copyright notice,
96 * this list of conditions and the following disclaimer.
97 * 2. Redistributions in binary form must reproduce the above copyright notice,
98 * this list of conditions and the following disclaimer in the documentation
99 * and/or other materials provided with the distribution.
100 * 3. Neither the name of STMicroelectronics nor the names of its contributors
101 * may be used to endorse or promote products derived from this software
102 * without specific prior written permission.
104 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
105 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
106 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
107 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
108 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
109 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
110 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
111 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
112 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
113 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
115 ******************************************************************************
118 /* Includes ------------------------------------------------------------------*/
119 #include "stm32f3xx_hal.h"
121 /** @addtogroup STM32F3xx_HAL_Driver
125 #ifdef HAL_I2S_MODULE_ENABLED
127 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx) || \
128 defined(STM32F302xC) || defined(STM32F303xC) || defined(STM32F358xx) || \
129 defined(STM32F301x8) || defined(STM32F302x8) || defined(STM32F318xx) || \
130 defined(STM32F373xC) || defined(STM32F378xx)
132 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx) || \
133 defined(STM32F302xC) || defined(STM32F303xC) || defined(STM32F358xx)
135 /** @defgroup I2SEx I2S Extended HAL module driver
136 * @brief I2S Extended HAL module driver
140 /* Private typedef -----------------------------------------------------------*/
141 /** @defgroup I2SEx_Private_Typedef I2S Extended Private Typedef
146 I2S_USE_I2S = 0x00, /*!< I2Sx should be used */
147 I2S_USE_I2SEXT = 0x01 /*!< I2Sx_ext should be used */
153 /* Private define ------------------------------------------------------------*/
154 /* Private macro -------------------------------------------------------------*/
155 /* Private variables ---------------------------------------------------------*/
156 /* Private function prototypes -----------------------------------------------*/
157 /** @defgroup I2SEx_Private_Functions I2S Extended Private Functions
160 static void I2S_TxRxDMACplt(DMA_HandleTypeDef *hdma);
161 static void I2S_TxRxDMAError(DMA_HandleTypeDef *hdma);
162 static void I2S_FullDuplexTx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed);
163 static void I2S_FullDuplexRx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed);
164 static HAL_StatusTypeDef I2S_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag,
165 uint32_t State, uint32_t Timeout, I2S_UseTypeDef i2sUsed);
173 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
174 /* STM32F302xC || STM32F303xC || STM32F358xx */
176 /* Exported functions ---------------------------------------------------------*/
178 /** @addtogroup I2S I2S HAL module driver
182 /** @addtogroup I2S_Exported_Functions I2S Exported Functions
186 /** @addtogroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions
187 * @brief Initialization and Configuration functions
190 ===============================================================================
191 ##### Initialization/de-initialization functions #####
192 ===============================================================================
193 [..] This subsection provides a set of functions allowing to initialize and
194 de-initialiaze the I2Sx peripheral in simplex mode:
196 (+) User must Implement HAL_I2S_MspInit() function in which he configures
197 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
199 (+) Call the function HAL_I2S_Init() to configure the selected device with
200 the selected configuration:
208 (+) Call the function HAL_I2S_DeInit() to restore the default configuration
209 of the selected I2Sx periperal.
215 * @brief Initializes the I2S according to the specified parameters
216 * in the I2S_InitTypeDef and create the associated handle.
217 * @param hi2s: I2S handle
220 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
222 uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
223 uint32_t tmp = 0, i2sclk = 0;
224 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx) || \
225 defined(STM32F302xC) || defined(STM32F303xC) || defined(STM32F358xx)
226 RCC_PeriphCLKInitTypeDef rccperiphclkinit;
227 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
228 /* STM32F302xC || STM32F303xC || STM32F358xx */
230 /* Check the I2S handle allocation */
236 /* Check the parameters */
237 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
238 assert_param(IS_I2S_MODE(hi2s->Init.Mode));
239 assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
240 assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
241 assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
242 assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
243 assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
244 assert_param(IS_I2S_CLOCKSOURCE(hi2s->Init.ClockSource));
245 assert_param(IS_I2S_FULLDUPLEX_MODE(hi2s->Init.FullDuplexMode));
247 hi2s->State = HAL_I2S_STATE_BUSY;
249 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
250 HAL_I2S_MspInit(hi2s);
252 /*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
253 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
254 hi2s->Instance->I2SCFGR &= ~(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
255 SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
256 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD);
257 hi2s->Instance->I2SPR = 0x0002;
259 /* Get the I2SCFGR register value */
260 tmpreg = hi2s->Instance->I2SCFGR;
262 /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
263 if(hi2s->Init.AudioFreq == I2S_AUDIOFREQ_DEFAULT)
265 i2sodd = (uint16_t)0;
266 i2sdiv = (uint16_t)2;
268 /* If the requested audio frequency is not the default, compute the prescaler */
271 /* Check the frame length (For the Prescaler computing) *******************/
272 if(hi2s->Init.DataFormat == I2S_DATAFORMAT_16B)
274 /* Packet length is 16 bits */
279 /* Packet length is 32 bits */
283 /* Get I2S source Clock frequency ****************************************/
284 #if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx) || \
285 defined (STM32F302xC) || defined (STM32F303xC) || defined (STM32F358xx)
286 rccperiphclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S;
288 /* If an external I2S clock has to be used, the specific define should be set
289 in the project configuration or in the stm32f3xx_conf.h file */
290 if(hi2s->Init.ClockSource == I2S_CLOCK_EXTERNAL)
292 /* Set external clock as I2S clock source */
293 rccperiphclkinit.I2sClockSelection = RCC_I2SCLKSOURCE_EXT;
294 HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit);
296 /* Set the I2S clock to the external clock value */
297 i2sclk = EXTERNAL_CLOCK_VALUE;
301 /* Set SYSCLK as I2S clock source */
302 rccperiphclkinit.I2sClockSelection = RCC_I2SCLKSOURCE_SYSCLK;
303 HAL_RCCEx_PeriphCLKConfig(&rccperiphclkinit);
305 /* Get the I2S source clock value */
306 i2sclk = HAL_RCC_GetSysClockFreq();
308 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
309 /* STM32F302xC || STM32F303xC || STM32F358xx */
311 #if defined (STM32F373xC) || defined (STM32F378xx)
312 if(hi2s->Instance == SPI1)
314 i2sclk = HAL_RCC_GetPCLK2Freq();
316 else if((hi2s->Instance == SPI2) || (hi2s->Instance == SPI3))
318 i2sclk = HAL_RCC_GetPCLK1Freq();
320 #endif /* STM32F373xC || STM32F378xx */
322 /* Compute the Real divider depending on the MCLK output state, with a floating point */
323 if(hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
325 /* MCLK output is enabled */
326 tmp = (uint16_t)(((((i2sclk / 256) * 10) / hi2s->Init.AudioFreq)) + 5);
330 /* MCLK output is disabled */
331 tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / hi2s->Init.AudioFreq)) + 5);
334 /* Remove the flatting point */
337 /* Check the parity of the divider */
338 i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
340 /* Compute the i2sdiv prescaler */
341 i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
343 /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
344 i2sodd = (uint16_t) (i2sodd << 8);
347 /* Test if the divider is 1 or 0 or greater than 0xFF */
348 if((i2sdiv < 2) || (i2sdiv > 0xFF))
350 /* Set the default values */
355 /* Write to SPIx I2SPR register the computed value */
356 hi2s->Instance->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)hi2s->Init.MCLKOutput));
358 /* Configure the I2S with the I2S_InitStruct values */
359 tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(hi2s->Init.Mode | \
360 (uint16_t)(hi2s->Init.Standard | (uint16_t)(hi2s->Init.DataFormat | \
361 (uint16_t)hi2s->Init.CPOL))));
363 /* Write to SPIx I2SCFGR */
364 hi2s->Instance->I2SCFGR = tmpreg;
366 #if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx) || \
367 defined (STM32F302xC) || defined (STM32F303xC) || defined (STM32F358xx)
368 if (hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE)
370 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
371 I2SxEXT(hi2s->Instance)->I2SCFGR &= ~(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
372 SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
373 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD);
374 I2SxEXT(hi2s->Instance)->I2SPR = 0x0002;
376 /* Get the I2SCFGR register value */
377 tmpreg = I2SxEXT(hi2s->Instance)->I2SCFGR;
379 /* Get the mode to be configured for the extended I2S */
380 if((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
382 tmp = I2S_MODE_SLAVE_RX;
386 if((hi2s->Init.Mode == I2S_MODE_MASTER_RX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_RX))
388 tmp = I2S_MODE_SLAVE_TX;
392 /* Configure the I2S Slave with the I2S Master parameter values */
393 tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(tmp | \
394 (uint16_t)(hi2s->Init.Standard | (uint16_t)(hi2s->Init.DataFormat | \
395 (uint16_t)hi2s->Init.CPOL))));
397 /* Write to SPIx I2SCFGR */
398 I2SxEXT(hi2s->Instance)->I2SCFGR = tmpreg;
400 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
401 /* STM32F302xC || STM32F303xC || STM32F358xx */
403 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
404 hi2s->State= HAL_I2S_STATE_READY;
412 #if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx) || \
413 defined (STM32F302xC) || defined (STM32F303xC) || defined (STM32F358xx)
414 /** @addtogroup I2S_Exported_Functions_Group2 Input and Output operation functions
419 * @brief This function handles I2S/I2Sext interrupt requests in full-duplex mode.
420 * @param hi2s: I2S handle
423 void HAL_I2S_FullDuplex_IRQHandler(I2S_HandleTypeDef *hi2s)
425 __IO uint32_t i2ssr = hi2s->Instance->SR ;
426 __IO uint32_t i2sextsr = I2SxEXT(hi2s->Instance)->SR;
428 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
429 if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
431 /* I2S in mode Transmitter -------------------------------------------------*/
432 if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET))
434 /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX,
435 the I2S TXE interrupt will be generated to manage the full-duplex transmit phase. */
436 I2S_FullDuplexTx_IT(hi2s, I2S_USE_I2S);
439 /* I2Sext in mode Receiver -----------------------------------------------*/
440 if(((i2sextsr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET))
442 /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX,
443 the I2Sext RXNE interrupt will be generated to manage the full-duplex receive phase. */
444 I2S_FullDuplexRx_IT(hi2s, I2S_USE_I2SEXT);
447 /* I2Sext Overrun error interrupt occured --------------------------------*/
448 if(((i2sextsr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
450 /* Disable RXNE and ERR interrupt */
451 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
453 /* Disable TXE and ERR interrupt */
454 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
456 /* Set the I2S State ready */
457 hi2s->State = HAL_I2S_STATE_READY;
459 /* Set the error code and execute error callback*/
460 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
461 HAL_I2S_ErrorCallback(hi2s);
464 /* I2S Underrun error interrupt occured ----------------------------------*/
465 if(((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
467 /* Disable TXE and ERR interrupt */
468 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
470 /* Disable RXNE and ERR interrupt */
471 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
473 /* Set the I2S State ready */
474 hi2s->State = HAL_I2S_STATE_READY;
476 /* Set the error code and execute error callback*/
477 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
478 HAL_I2S_ErrorCallback(hi2s);
481 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
484 /* I2Sext in mode Transmitter ----------------------------------------------*/
485 if(((i2sextsr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET))
487 /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX,
488 the I2Sext TXE interrupt will be generated to manage the full-duplex transmit phase. */
489 I2S_FullDuplexTx_IT(hi2s, I2S_USE_I2SEXT);
492 /* I2S in mode Receiver --------------------------------------------------*/
493 if(((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET))
495 /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX,
496 the I2S RXNE interrupt will be generated to manage the full-duplex receive phase. */
497 I2S_FullDuplexRx_IT(hi2s, I2S_USE_I2S);
500 /* I2S Overrun error interrupt occured -------------------------------------*/
501 if(((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
503 /* Disable RXNE and ERR interrupt */
504 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
506 /* Disable TXE and ERR interrupt */
507 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
509 /* Set the I2S State ready */
510 hi2s->State = HAL_I2S_STATE_READY;
512 /* Set the error code and execute error callback*/
513 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
514 HAL_I2S_ErrorCallback(hi2s);
517 /* I2Sext Underrun error interrupt occured -------------------------------*/
518 if(((i2sextsr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
520 /* Disable TXE and ERR interrupt */
521 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
523 /* Disable RXNE and ERR interrupt */
524 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
526 /* Set the I2S State ready */
527 hi2s->State = HAL_I2S_STATE_READY;
529 /* Set the error code and execute error callback*/
530 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
531 HAL_I2S_ErrorCallback(hi2s);
537 * @brief Tx and Rx Transfer completed callbacks
538 * @param hi2s: I2S handle
541 __weak void HAL_I2S_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
543 /* NOTE : This function Should not be modified, when the callback is needed,
544 the HAL_I2S_TxRxCpltCallback could be implenetd in the user file
552 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
553 /* STM32F302xC || STM32F303xC || STM32F358xx */
555 /** @addtogroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
556 * @brief Peripheral State functions
560 ===============================================================================
561 ##### Peripheral State functions #####
562 ===============================================================================
564 This subsection permit to get in run-time the status of the peripheral
571 * @brief Pauses the audio stream playing from the Media.
572 * @param hi2s : I2S handle
575 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
580 if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
582 /* Pause the audio file playing by disabling the I2S DMA request */
583 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
585 else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
587 /* Pause the audio file playing by disabling the I2S DMA request */
588 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
590 #if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx) || \
591 defined (STM32F302xC) || defined (STM32F303xC) || defined (STM32F358xx)
592 else if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
594 /* Pause the audio file playing by disabling the I2S DMA request */
595 hi2s->Instance->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
596 I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
598 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
599 /* STM32F302xC || STM32F303xC || STM32F358xx */
601 /* Process Unlocked */
608 * @brief Resumes the audio stream playing from the Media.
609 * @param hi2s : I2S handle
612 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
617 if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
619 /* Enable the I2S DMA request */
620 hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN;
622 else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
624 /* Enable the I2S DMA request */
625 hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;
627 #if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx) || \
628 defined (STM32F302xC) || defined (STM32F303xC) || defined (STM32F358xx)
629 else if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
631 /* Pause the audio file playing by disabling the I2S DMA request */
632 hi2s->Instance->CR2 |= (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
633 I2SxEXT(hi2s->Instance)->CR2 |= (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
635 /* If the I2Sext peripheral is still not enabled, enable it */
636 if ((I2SxEXT(hi2s->Instance)->I2SCFGR & SPI_I2SCFGR_I2SE) == 0)
638 /* Enable I2Sext peripheral */
639 __HAL_I2SEXT_ENABLE(hi2s);
642 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
643 /* STM32F302xC || STM32F303xC || STM32F358xx */
645 /* If the I2S peripheral is still not enabled, enable it */
646 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) == 0)
648 /* Enable I2S peripheral */
649 __HAL_I2S_ENABLE(hi2s);
652 /* Process Unlocked */
659 * @brief Resumes the audio stream playing from the Media.
660 * @param hi2s: I2S handle
663 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
668 if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
670 /* Disable the I2S DMA requests */
671 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
673 /* Disable the I2S DMA Channel */
674 HAL_DMA_Abort(hi2s->hdmatx);
676 else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
678 /* Disable the I2S DMA requests */
679 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
681 /* Disable the I2S DMA Channel */
682 HAL_DMA_Abort(hi2s->hdmarx);
684 #if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx) || \
685 defined (STM32F302xC) || defined (STM32F303xC) || defined (STM32F358xx)
686 else if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
688 /* Disable the I2S DMA requests */
689 hi2s->Instance->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
690 I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
692 /* Disable the I2S DMA Channels */
693 HAL_DMA_Abort(hi2s->hdmatx);
694 HAL_DMA_Abort(hi2s->hdmarx);
696 /* Disable I2Sext peripheral */
697 __HAL_I2SEXT_DISABLE(hi2s);
699 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
700 /* STM32F302xC || STM32F303xC || STM32F358xx */
702 /* Disable I2S peripheral */
703 __HAL_I2S_DISABLE(hi2s);
705 hi2s->State = HAL_I2S_STATE_READY;
707 /* Process Unlocked */
725 #if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx) || \
726 defined (STM32F302xC) || defined (STM32F303xC) || defined (STM32F358xx)
727 /** @addtogroup I2SEx I2S Extended HAL module driver
728 * @brief I2S Extended HAL module driver
732 /** @defgroup I2SEx_Exported_Functions I2S Extended Exported Functions
736 /** @defgroup I2SEx_Exported_Functions_Group1 Extended features functions
737 * @brief Extended features functions
740 ===============================================================================
741 ##### Extended features Functions #####
742 ===============================================================================
744 This subsection provides a set of functions allowing to manage the I2S data
747 (#) There is two mode of transfer:
748 (++) Blocking mode: The communication is performed in the polling mode.
749 The status of all data processing is returned by the same function
750 after finishing transfer.
751 (++) No-Blocking mode: The communication is performed using Interrupts
752 or DMA. These functions return the status of the transfer startup.
753 The end of the data processing will be indicated through the
754 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
757 (#) Blocking mode functions are :
758 (++) HAL_I2S_TransmitReceive()
760 (#) No-Blocking mode functions with Interrupt are:
761 (++) HAL_I2S_TransmitReceive_IT()
762 (++) HAL_I2SFullDuplex_IRQHandler()
764 (#) No-Blocking mode functions with DMA are:
765 (++) HAL_I2S_TransmitReceive_DMA()
767 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
768 (++) HAL_I2S_TxRxCpltCallback()
769 (++) HAL_I2S_TxRxErrorCallback()
776 * @brief Full-Duplex Transmit/Receive data in blocking mode.
777 * @param hi2s: I2S handle
778 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
779 * @param pRxData: a 16-bit pointer to the Receive data buffer.
780 * @param Size: number of data sample to be sent:
781 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
782 * configuration phase, the Size parameter means the number of 16-bit data length
783 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
784 * the Size parameter means the number of 16-bit data length.
785 * @param Timeout: Timeout duration
786 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
787 * between Master and Slave(example: audio streaming).
790 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size, uint32_t Timeout)
792 if((pTxData == HAL_NULL ) || (pRxData == HAL_NULL ) || (Size == 0))
797 /* Check the I2S State */
798 if(hi2s->State == HAL_I2S_STATE_READY)
800 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
801 is selected during the I2S configuration phase, the Size parameter means the number
802 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
803 frame is selected the Size parameter means the number of 16-bit data length. */
804 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
805 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
807 hi2s->TxXferSize = (Size << 1);
808 hi2s->TxXferCount = (Size << 1);
809 hi2s->RxXferSize = (Size << 1);
810 hi2s->RxXferCount = (Size << 1);
814 hi2s->TxXferSize = Size;
815 hi2s->TxXferCount = Size;
816 hi2s->RxXferSize = Size;
817 hi2s->RxXferCount = Size;
823 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
825 /* Set the I2S State busy TX/RX */
826 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
828 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
829 if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
831 /* Prepare the First Data before enabling the I2S */
832 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)
834 hi2s->Instance->DR = (*pTxData++);
838 /* Check if the I2S is already enabled: The I2S is kept enabled at the end of transaction
839 to avoid the clock de-synchronization between Master and Slave. */
840 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
842 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
843 __HAL_I2SEXT_ENABLE(hi2s);
845 /* Enable I2Sx peripheral */
846 __HAL_I2S_ENABLE(hi2s);
849 while(hi2s->RxXferCount > 0)
851 /* Wait until TXE flag is set */
852 if (I2S_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2S) != HAL_OK)
854 /* Set the error code and execute error callback*/
855 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
856 HAL_I2S_ErrorCallback(hi2s);
860 if (hi2s->TxXferCount > 0)
862 /* Check if an underrun occurs */
863 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
865 /* Set the I2S State ready */
866 hi2s->State = HAL_I2S_STATE_READY;
868 /* Process Unlocked */
871 /* Set the error code and execute error callback*/
872 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
873 HAL_I2S_ErrorCallback(hi2s);
878 hi2s->Instance->DR = (*pTxData++);
882 /* Wait until RXNE flag is set */
883 if (I2S_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK)
885 /* Set the error code and execute error callback*/
886 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
887 HAL_I2S_ErrorCallback(hi2s);
891 /* Check if an overrun occurs */
892 if(__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
894 /* Set the I2S State ready */
895 hi2s->State = HAL_I2S_STATE_READY;
897 /* Process Unlocked */
900 /* Set the error code and execute error callback*/
901 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
902 HAL_I2S_ErrorCallback(hi2s);
907 (*pRxData++) = I2SxEXT(hi2s->Instance)->DR;
911 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
914 /* Prepare the First Data before enabling the I2S */
915 I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
918 /* Check if the I2S is already enabled */
919 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
921 /* Enable I2S peripheral before the I2Sext*/
922 __HAL_I2S_ENABLE(hi2s);
924 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
925 __HAL_I2SEXT_ENABLE(hi2s);
928 /* Check if Master Receiver mode is selected */
929 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
931 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
932 access to the SPI_SR register. */
933 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
936 while(hi2s->RxXferCount > 0)
938 /* Wait until TXE flag is set */
939 if (I2S_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK)
941 /* Set the error code and execute error callback*/
942 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
943 HAL_I2S_ErrorCallback(hi2s);
947 if (hi2s->TxXferCount > 0)
949 /* Check if an underrun occurs */
950 if(__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
952 /* Set the I2S State ready */
953 hi2s->State = HAL_I2S_STATE_READY;
955 /* Process Unlocked */
958 /* Set the error code and execute error callback*/
959 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
960 HAL_I2S_ErrorCallback(hi2s);
965 I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
969 /* Wait until RXNE flag is set */
970 if (I2S_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2S) != HAL_OK)
972 /* Set the error code and execute error callback*/
973 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
974 HAL_I2S_ErrorCallback(hi2s);
978 /* Check if an overrun occurs */
979 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
981 /* Set the I2S State ready */
982 hi2s->State = HAL_I2S_STATE_READY;
984 /* Process Unlocked */
987 /* Set the error code and execute error callback*/
988 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
989 HAL_I2S_ErrorCallback(hi2s);
994 (*pRxData++) = hi2s->Instance->DR;
999 /* Set the I2S State ready */
1000 hi2s->State = HAL_I2S_STATE_READY;
1002 /* Process Unlocked */
1014 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
1015 * @param hi2s: I2S handle
1016 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
1017 * @param pRxData: a 16-bit pointer to the Receive data buffer.
1018 * @param Size: number of data sample to be sent:
1019 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1020 * configuration phase, the Size parameter means the number of 16-bit data length
1021 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1022 * the Size parameter means the number of 16-bit data length.
1023 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1024 * between Master and Slave(example: audio streaming).
1025 * @retval HAL status
1027 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
1029 if(hi2s->State == HAL_I2S_STATE_READY)
1031 if((pTxData == HAL_NULL ) || (pRxData == HAL_NULL ) || (Size == 0))
1036 hi2s->pTxBuffPtr = pTxData;
1037 hi2s->pRxBuffPtr = pRxData;
1039 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
1040 is selected during the I2S configuration phase, the Size parameter means the number
1041 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
1042 frame is selected the Size parameter means the number of 16-bit data length. */
1043 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
1044 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
1046 hi2s->TxXferSize = (Size << 1);
1047 hi2s->TxXferCount = (Size << 1);
1048 hi2s->RxXferSize = (Size << 1);
1049 hi2s->RxXferCount = (Size << 1);
1053 hi2s->TxXferSize = Size;
1054 hi2s->TxXferCount = Size;
1055 hi2s->RxXferSize = Size;
1056 hi2s->RxXferCount = Size;
1059 /* Process Locked */
1062 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1063 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
1065 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
1066 if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
1068 /* Enable I2Sext RXNE and ERR interrupts */
1069 __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1071 /* Enable I2Sx TXE and ERR interrupts */
1072 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1074 /* Check if the I2S is already enabled */
1075 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1077 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)
1079 /* Prepare the First Data before enabling the I2S */
1080 if(hi2s->TxXferCount != 0)
1082 /* Transmit First data */
1083 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
1084 hi2s->TxXferCount--;
1086 if(hi2s->TxXferCount == 0)
1088 /* Disable TXE and ERR interrupt */
1089 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1091 if(hi2s->RxXferCount == 0)
1093 /* Disable I2Sext RXNE and ERR interrupt */
1094 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE| I2S_IT_ERR));
1096 hi2s->State = HAL_I2S_STATE_READY;
1097 HAL_I2S_TxRxCpltCallback(hi2s);
1102 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
1103 __HAL_I2SEXT_ENABLE(hi2s);
1105 /* Enable I2Sx peripheral */
1106 __HAL_I2S_ENABLE(hi2s);
1109 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
1112 /* Enable I2Sext TXE and ERR interrupts */
1113 __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1115 /* Enable I2Sext RXNE and ERR interrupts */
1116 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1118 /* Check if the I2S is already enabled */
1119 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1121 /* Prepare the First Data before enabling the I2S */
1122 if(hi2s->TxXferCount != 0)
1124 /* Transmit First data */
1125 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
1126 hi2s->TxXferCount--;
1128 if(hi2s->TxXferCount == 0)
1130 /* Disable I2Sext TXE and ERR interrupt */
1131 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1133 if(hi2s->RxXferCount == 0)
1135 /* Disable RXNE and ERR interrupt */
1136 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE| I2S_IT_ERR));
1138 hi2s->State = HAL_I2S_STATE_READY;
1139 HAL_I2S_TxRxCpltCallback(hi2s);
1143 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
1144 __HAL_I2SEXT_ENABLE(hi2s);
1146 /* Enable I2S peripheral */
1147 __HAL_I2S_ENABLE(hi2s);
1150 /* Process Unlocked */
1162 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA
1163 * @param hi2s: I2S handle
1164 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
1165 * @param pRxData: a 16-bit pointer to the Receive data buffer.
1166 * @param Size: number of data sample to be sent:
1167 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1168 * configuration phase, the Size parameter means the number of 16-bit data length
1169 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1170 * the Size parameter means the number of 16-bit data length.
1171 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1172 * between Master and Slave(example: audio streaming).
1173 * @retval HAL status
1175 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
1179 if((pTxData == HAL_NULL ) || (pRxData == HAL_NULL ) || (Size == 0))
1184 if(hi2s->State == HAL_I2S_STATE_READY)
1186 hi2s->pTxBuffPtr = pTxData;
1187 hi2s->pRxBuffPtr = pRxData;
1189 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
1190 is selected during the I2S configuration phase, the Size parameter means the number
1191 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
1192 frame is selected the Size parameter means the number of 16-bit data length. */
1193 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
1194 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
1196 hi2s->TxXferSize = (Size << 1);
1197 hi2s->TxXferCount = (Size << 1);
1198 hi2s->RxXferSize = (Size << 1);
1199 hi2s->RxXferCount = (Size << 1);
1203 hi2s->TxXferSize = Size;
1204 hi2s->TxXferCount = Size;
1205 hi2s->RxXferSize = Size;
1206 hi2s->RxXferCount = Size;
1209 /* Process Locked */
1212 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1213 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
1215 /* Set the I2S Rx DMA transfer complete callback */
1216 hi2s->hdmarx->XferCpltCallback = I2S_TxRxDMACplt;
1218 /* Set the DMA error callback */
1219 hi2s->hdmarx->XferErrorCallback = I2S_TxRxDMAError;
1221 /* Set the I2S Tx DMA transfer complete callback */
1222 hi2s->hdmatx->XferCpltCallback = I2S_TxRxDMACplt;
1224 /* Set the DMA error callback */
1225 hi2s->hdmatx->XferErrorCallback = I2S_TxRxDMAError;
1227 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
1228 if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
1230 /* Enable the Rx DMA Channel */
1231 tmp = (uint32_t*)&pRxData;
1232 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
1234 /* Enable Rx DMA Request */
1235 I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_RXDMAEN;
1237 /* Enable the Tx DMA Channel */
1238 tmp = (uint32_t*)&pTxData;
1239 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
1241 /* Enable Tx DMA Request */
1242 hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN;
1244 /* Check if the I2S is already enabled */
1245 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1247 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
1248 __HAL_I2SEXT_ENABLE(hi2s);
1250 /* Enable I2S peripheral after the I2Sext*/
1251 __HAL_I2S_ENABLE(hi2s);
1256 /* Check if Master Receiver mode is selected */
1257 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
1259 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
1260 access to the SPI_SR register. */
1261 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1264 /* Enable the Tx DMA Channel */
1265 tmp = (uint32_t*)&pTxData;
1266 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize);
1268 /* Enable Tx DMA Request */
1269 I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_TXDMAEN;
1271 /* Enable the Rx DMA Channel */
1272 tmp = (uint32_t*)&pRxData;
1273 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
1275 /* Enable Rx DMA Request */
1276 hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;
1278 /* Check if the I2S is already enabled */
1279 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1281 /* Enable I2Sext(transmitter) before enabling I2Sx peripheral */
1282 __HAL_I2SEXT_ENABLE(hi2s);
1284 /* Enable I2S peripheral after the I2Sext*/
1285 __HAL_I2S_ENABLE(hi2s);
1289 /* Process Unlocked */
1308 /** @addtogroup I2SEx_Private_Functions I2S Extended Private Functions
1313 * @brief DMA I2S transmit receive process complete callback
1314 * @param hdma: DMA handle
1317 static void I2S_TxRxDMACplt(DMA_HandleTypeDef *hdma)
1319 I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1321 if (hi2s->hdmarx == hdma)
1323 /* Disable Rx DMA Request */
1324 if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
1326 I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
1330 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
1333 hi2s->RxXferCount = 0;
1335 if (hi2s->TxXferCount == 0)
1337 hi2s->State = HAL_I2S_STATE_READY;
1339 HAL_I2S_TxRxCpltCallback(hi2s);
1343 if (hi2s->hdmatx == hdma)
1345 /* Disable Tx DMA Request */
1346 if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
1348 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
1352 I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
1355 hi2s->TxXferCount = 0;
1357 if (hi2s->RxXferCount == 0)
1359 hi2s->State = HAL_I2S_STATE_READY;
1361 HAL_I2S_TxRxCpltCallback(hi2s);
1367 * @brief DMA I2S communication error callback
1368 * @param hdma : DMA handle
1371 static void I2S_TxRxDMAError(DMA_HandleTypeDef *hdma)
1373 I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1375 /* Disable Rx and Tx DMA Request */
1376 hi2s->Instance->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1377 I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1379 hi2s->TxXferCount = 0;
1380 hi2s->RxXferCount = 0;
1382 hi2s->State= HAL_I2S_STATE_READY;
1384 /* Set the error code and execute error callback*/
1385 hi2s->ErrorCode |= HAL_I2S_ERROR_DMA;
1386 HAL_I2S_ErrorCallback(hi2s);
1390 * @brief Full-Duplex IT handler transmit function
1391 * @param hi2s: I2S handle
1392 * @param i2sUsed: indicate if I2Sx or I2Sx_ext is concerned
1395 static void I2S_FullDuplexTx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed)
1397 if(i2sUsed == I2S_USE_I2S)
1400 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
1401 hi2s->TxXferCount--;
1403 if(hi2s->TxXferCount == 0)
1405 /* Disable TXE and ERR interrupt */
1406 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1408 if(hi2s->RxXferCount == 0)
1410 hi2s->State = HAL_I2S_STATE_READY;
1411 HAL_I2S_TxRxCpltCallback(hi2s);
1418 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
1419 hi2s->TxXferCount--;
1421 if(hi2s->TxXferCount == 0)
1423 /* Disable I2Sext TXE and ERR interrupt */
1424 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1426 if(hi2s->RxXferCount == 0)
1428 hi2s->State = HAL_I2S_STATE_READY;
1429 HAL_I2S_TxRxCpltCallback(hi2s);
1436 * @brief Full-Duplex IT handler receive function
1437 * @param hi2s: I2S handle
1438 * @param i2sUsed: indicate if I2Sx or I2Sx_ext is concerned
1441 static void I2S_FullDuplexRx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed)
1443 if(i2sUsed == I2S_USE_I2S)
1446 (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
1447 hi2s->RxXferCount--;
1449 if(hi2s->RxXferCount == 0)
1451 /* Disable RXNE and ERR interrupt */
1452 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1454 if(hi2s->TxXferCount == 0)
1456 hi2s->State = HAL_I2S_STATE_READY;
1457 HAL_I2S_TxRxCpltCallback(hi2s);
1464 (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR;
1465 hi2s->RxXferCount--;
1467 if(hi2s->RxXferCount == 0)
1469 /* Disable I2Sext RXNE and ERR interrupt */
1470 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1472 if(hi2s->TxXferCount == 0)
1474 hi2s->State = HAL_I2S_STATE_READY;
1475 HAL_I2S_TxRxCpltCallback(hi2s);
1482 * @brief This function handles I2S Communication Timeout.
1483 * @param hi2s: I2S handle
1484 * @param Flag: Flag checked
1485 * @param State: Value of the flag expected
1486 * @param Timeout: Duration of the timeout
1487 * @param i2sUsed: I2S instance reference
1488 * @retval HAL status
1490 static HAL_StatusTypeDef I2S_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag,
1491 uint32_t State, uint32_t Timeout, I2S_UseTypeDef i2sUsed)
1493 uint32_t tickstart = HAL_GetTick();
1495 if(i2sUsed == I2S_USE_I2S)
1497 while((__HAL_I2S_GET_FLAG(hi2s, Flag)) != State)
1499 if(Timeout != HAL_MAX_DELAY)
1501 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
1503 /* Set the I2S State ready */
1504 hi2s->State= HAL_I2S_STATE_READY;
1506 /* Process Unlocked */
1516 while((__HAL_I2SEXT_GET_FLAG(hi2s, Flag)) != State)
1518 if(Timeout != HAL_MAX_DELAY)
1520 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
1522 /* Set the I2S State ready */
1523 hi2s->State= HAL_I2S_STATE_READY;
1525 /* Process Unlocked */
1543 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
1544 /* STM32F302xC || STM32F303xC || STM32F358xx */
1546 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
1547 /* STM32F302xC || STM32F303xC || STM32F358xx || */
1548 /* STM32F301x8 || STM32F302x8 || STM32F318xx || */
1549 /* STM32F373xC || STM32F378xx */
1551 #endif /* HAL_I2S_MODULE_ENABLED */
1557 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/