2 ******************************************************************************
3 * @file stm32f4xx_hal_i2s_ex.c
4 * @author MCD Application Team
7 * @brief I2S HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of I2S extension peripheral:
10 * + Extension features Functions
13 ==============================================================================
14 ##### I2S Extension 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 (i.e I2S2ext for SPI2 and I2S3ext for SPI3).
20 (#) The extension block is not a full SPI IP, it is used only as I2S slave to
21 implement full duplex mode. The extension block uses the same clock sources
24 (#) Both I2Sx and I2Sx_ext can be configured as transmitters or receivers.
27 (@) Only I2Sx can deliver SCK and WS to I2Sx_ext in full duplex mode, where
28 I2Sx can be I2S2 or I2S3.
30 ##### How to use this driver #####
31 ===============================================================================
33 Three operation modes are available within this driver :
35 *** Polling mode IO operation ***
36 =================================
38 (+) Send and receive in the same time an amount of data in blocking mode using HAL_I2S_TransmitReceive()
40 *** Interrupt mode IO operation ***
41 ===================================
43 (+) Send and receive in the same time an amount of data in non blocking mode using HAL_I2S_TransmitReceive_IT()
44 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
45 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
46 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
47 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
48 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
49 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
50 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
51 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
52 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
53 add his own code by customization of function pointer HAL_I2S_ErrorCallback
55 *** DMA mode IO operation ***
56 ==============================
58 (+) Send and receive an amount of data in non blocking mode (DMA) using HAL_I2S_TransmitReceive_DMA()
59 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
60 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
61 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
62 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
63 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
64 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
65 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
66 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
67 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
68 add his own code by customization of function pointer HAL_I2S_ErrorCallback
69 (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
70 (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
71 (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
74 ******************************************************************************
77 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
79 * Redistribution and use in source and binary forms, with or without modification,
80 * are permitted provided that the following conditions are met:
81 * 1. Redistributions of source code must retain the above copyright notice,
82 * this list of conditions and the following disclaimer.
83 * 2. Redistributions in binary form must reproduce the above copyright notice,
84 * this list of conditions and the following disclaimer in the documentation
85 * and/or other materials provided with the distribution.
86 * 3. Neither the name of STMicroelectronics nor the names of its contributors
87 * may be used to endorse or promote products derived from this software
88 * without specific prior written permission.
90 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
91 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
92 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
94 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
95 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
96 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
97 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
98 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
99 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101 ******************************************************************************
104 /* Includes ------------------------------------------------------------------*/
105 #include "stm32f4xx_hal.h"
107 /** @addtogroup STM32F4xx_HAL_Driver
112 * @brief I2S HAL module driver
116 #ifdef HAL_I2S_MODULE_ENABLED
118 /* Private typedef -----------------------------------------------------------*/
119 /* Private define ------------------------------------------------------------*/
120 /* Private macro -------------------------------------------------------------*/
121 /* Private variables ---------------------------------------------------------*/
122 /* Private function prototypes -----------------------------------------------*/
123 /* Private functions ---------------------------------------------------------*/
125 /** @defgroup I2SEx_Private_Functions
129 /** @defgroup I2SEx_Group1 Extension features functions
130 * @brief Extension features functions
133 ===============================================================================
134 ##### Extension features Functions #####
135 ===============================================================================
137 This subsection provides a set of functions allowing to manage the I2S data
140 (#) There are two modes of transfer:
141 (++) Blocking mode : The communication is performed in the polling mode.
142 The status of all data processing is returned by the same function
143 after finishing transfer.
144 (++) No-Blocking mode : The communication is performed using Interrupts
145 or DMA. These functions return the status of the transfer startup.
146 The end of the data processing will be indicated through the
147 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
150 (#) Blocking mode functions are :
151 (++) HAL_I2S_TransmitReceive()
153 (#) No-Blocking mode functions with Interrupt are :
154 (++) HAL_I2S_TransmitReceive_IT()
156 (#) No-Blocking mode functions with DMA are :
157 (++) HAL_I2S_TransmitReceive_DMA()
159 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
160 (++) HAL_I2S_TxCpltCallback()
161 (++) HAL_I2S_RxCpltCallback()
162 (++) HAL_I2S_ErrorCallback()
169 * @brief Full-Duplex Transmit/Receive data in blocking mode.
170 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
171 * the configuration information for I2S module
172 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
173 * @param pRxData: a 16-bit pointer to the Receive data buffer.
174 * @param Size: number of data sample to be sent:
175 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
176 * configuration phase, the Size parameter means the number of 16-bit data length
177 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
178 * the Size parameter means the number of 16-bit data length.
179 * @param Timeout: Timeout duration
180 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
181 * between Master and Slave(example: audio streaming).
184 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size, uint32_t Timeout)
186 uint32_t tickstart = 0;
187 uint32_t tmp1 = 0, tmp2 = 0;
189 if((pTxData == HAL_NULL ) || (pRxData == HAL_NULL ) || (Size == 0))
194 /* Check the I2S State */
195 if(hi2s->State == HAL_I2S_STATE_READY)
197 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
198 tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
199 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
200 is selected during the I2S configuration phase, the Size parameter means the number
201 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
202 frame is selected the Size parameter means the number of 16-bit data length. */
203 if((tmp1 == I2S_DATAFORMAT_24B)|| \
204 (tmp2 == I2S_DATAFORMAT_32B))
206 hi2s->TxXferSize = Size*2;
207 hi2s->TxXferCount = Size*2;
208 hi2s->RxXferSize = Size*2;
209 hi2s->RxXferCount = Size*2;
213 hi2s->TxXferSize = Size;
214 hi2s->TxXferCount = Size;
215 hi2s->RxXferSize = Size;
216 hi2s->RxXferCount = Size;
222 /* Set the I2S State busy TX/RX */
223 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
225 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
226 tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
227 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
228 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
230 /* Check if the I2S is already enabled: The I2S is kept enabled at the end of transaction
231 to avoid the clock de-synchronization between Master and Slave. */
232 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
234 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
235 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
237 /* Enable I2Sx peripheral */
238 __HAL_I2S_ENABLE(hi2s);
241 while(hi2s->TxXferCount > 0)
243 /* Wait until TXE flag is set */
244 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK)
248 hi2s->Instance->DR = (*pTxData++);
251 tickstart = HAL_GetTick();
253 /* Wait until RXNE flag is set */
254 while((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) != SPI_SR_RXNE)
256 if(Timeout != HAL_MAX_DELAY)
258 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
260 /* Process Unlocked */
267 (*pRxData++) = I2SxEXT(hi2s->Instance)->DR;
273 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
276 /* Check if the I2S is already enabled */
277 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
279 /* Enable I2S peripheral before the I2Sext*/
280 __HAL_I2S_ENABLE(hi2s);
282 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
283 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
287 /* Check if Master Receiver mode is selected */
288 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
290 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
291 access to the SPI_SR register. */
292 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
295 while(hi2s->TxXferCount > 0)
298 tickstart = HAL_GetTick();
300 /* Wait until TXE flag is set */
301 while((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) != SPI_SR_TXE)
303 if(Timeout != HAL_MAX_DELAY)
305 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
307 /* Process Unlocked */
314 I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
316 /* Wait until RXNE flag is set */
317 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, RESET, Timeout) != HAL_OK)
321 (*pRxData++) = hi2s->Instance->DR;
328 /* Set the I2S State ready */
329 hi2s->State = HAL_I2S_STATE_READY;
331 /* Process Unlocked */
343 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
344 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
345 * the configuration information for I2S module
346 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
347 * @param pRxData: a 16-bit pointer to the Receive data buffer.
348 * @param Size: number of data sample to be sent:
349 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
350 * configuration phase, the Size parameter means the number of 16-bit data length
351 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
352 * the Size parameter means the number of 16-bit data length.
353 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
354 * between Master and Slave(example: audio streaming).
357 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
359 uint32_t tmp1 = 0, tmp2 = 0;
361 if(hi2s->State == HAL_I2S_STATE_READY)
363 if((pTxData == HAL_NULL ) || (pRxData == HAL_NULL ) || (Size == 0))
368 hi2s->pTxBuffPtr = pTxData;
369 hi2s->pRxBuffPtr = pRxData;
371 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
372 tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
373 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
374 is selected during the I2S configuration phase, the Size parameter means the number
375 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
376 frame is selected the Size parameter means the number of 16-bit data length. */
377 if((tmp1 == I2S_DATAFORMAT_24B)||\
378 (tmp2 == I2S_DATAFORMAT_32B))
380 hi2s->TxXferSize = Size*2;
381 hi2s->TxXferCount = Size*2;
382 hi2s->RxXferSize = Size*2;
383 hi2s->RxXferCount = Size*2;
387 hi2s->TxXferSize = Size;
388 hi2s->TxXferCount = Size;
389 hi2s->RxXferSize = Size;
390 hi2s->RxXferCount = Size;
396 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
397 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
399 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
400 tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
401 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
402 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
404 /* Enable I2Sext RXNE and ERR interrupts */
405 I2SxEXT(hi2s->Instance)->CR2 |= (I2S_IT_RXNE | I2S_IT_ERR);
407 /* Enable I2Sx TXE and ERR interrupts */
408 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
410 /* Check if the I2S is already enabled */
411 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
413 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
414 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
416 /* Enable I2Sx peripheral */
417 __HAL_I2S_ENABLE(hi2s);
420 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
423 /* Enable I2Sext TXE and ERR interrupts */
424 I2SxEXT(hi2s->Instance)->CR2 |= (I2S_IT_TXE |I2S_IT_ERR);
426 /* Enable I2Sext RXNE and ERR interrupts */
427 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
429 /* Check if the I2S is already enabled */
430 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
432 /* Check if the I2S_MODE_MASTER_RX is selected */
433 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
435 /* Prepare the First Data before enabling the I2S */
436 if(hi2s->TxXferCount != 0)
438 /* Transmit First data */
439 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
442 if(hi2s->TxXferCount == 0)
444 /* Disable I2Sext TXE interrupt */
445 I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE;
449 /* Enable I2S peripheral */
450 __HAL_I2S_ENABLE(hi2s);
452 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
453 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
456 /* Process Unlocked */
469 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA
470 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
471 * the configuration information for I2S module
472 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
473 * @param pRxData: a 16-bit pointer to the Receive data buffer.
474 * @param Size: number of data sample to be sent:
475 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
476 * configuration phase, the Size parameter means the number of 16-bit data length
477 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
478 * the Size parameter means the number of 16-bit data length.
479 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
480 * between Master and Slave(example: audio streaming).
483 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
486 uint32_t tmp1 = 0, tmp2 = 0;
488 if((pTxData == HAL_NULL ) || (pRxData == HAL_NULL ) || (Size == 0))
493 if(hi2s->State == HAL_I2S_STATE_READY)
495 hi2s->pTxBuffPtr = pTxData;
496 hi2s->pRxBuffPtr = pRxData;
498 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
499 tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
500 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
501 is selected during the I2S configuration phase, the Size parameter means the number
502 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
503 frame is selected the Size parameter means the number of 16-bit data length. */
504 if((tmp1 == I2S_DATAFORMAT_24B)||\
505 (tmp2 == I2S_DATAFORMAT_32B))
507 hi2s->TxXferSize = Size*2;
508 hi2s->TxXferCount = Size*2;
509 hi2s->RxXferSize = Size*2;
510 hi2s->RxXferCount = Size*2;
514 hi2s->TxXferSize = Size;
515 hi2s->TxXferCount = Size;
516 hi2s->RxXferSize = Size;
517 hi2s->RxXferCount = Size;
523 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
524 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
526 /* Set the I2S Rx DMA Half transfert complete callback */
527 hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
529 /* Set the I2S Rx DMA transfert complete callback */
530 hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
532 /* Set the I2S Rx DMA error callback */
533 hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
535 /* Set the I2S Tx DMA Half transfert complete callback */
536 hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
538 /* Set the I2S Tx DMA transfert complete callback */
539 hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
541 /* Set the I2S Tx DMA error callback */
542 hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
544 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
545 tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
546 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
547 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
549 /* Enable the Rx DMA Stream */
550 tmp = (uint32_t*)&pRxData;
551 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
553 /* Enable Rx DMA Request */
554 I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_RXDMAEN;
556 /* Enable the Tx DMA Stream */
557 tmp = (uint32_t*)&pTxData;
558 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
560 /* Enable Tx DMA Request */
561 hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN;
563 /* Check if the I2S is already enabled */
564 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
566 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
567 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
569 /* Enable I2S peripheral after the I2Sext */
570 __HAL_I2S_ENABLE(hi2s);
575 /* Enable the Tx DMA Stream */
576 tmp = (uint32_t*)&pTxData;
577 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize);
579 /* Enable Tx DMA Request */
580 I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_TXDMAEN;
582 /* Enable the Rx DMA Stream */
583 tmp = (uint32_t*)&pRxData;
584 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
586 /* Enable Rx DMA Request */
587 hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;
589 /* Check if the I2S is already enabled */
590 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
592 /* Enable I2S peripheral before the I2Sext */
593 __HAL_I2S_ENABLE(hi2s);
595 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
596 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
600 /* Check if Master Receiver mode is selected */
601 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
603 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
604 access to the SPI_SR register. */
605 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
610 /* Process Unlocked */
626 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
627 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
628 * the configuration information for I2S module
631 HAL_StatusTypeDef I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s)
633 uint32_t tmp1 = 0, tmp2 = 0;
635 if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
640 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
641 tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
642 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
643 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
645 if(hi2s->TxXferCount != 0)
647 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE) != RESET)
650 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
653 if(hi2s->TxXferCount == 0)
655 /* Disable TXE interrupt */
656 __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_TXE);
661 if(hi2s->RxXferCount != 0)
663 if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) == SPI_SR_RXNE)
666 (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR;
669 if(hi2s->RxXferCount == 0)
671 /* Disable I2Sext RXNE interrupt */
672 I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_RXNE;
677 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
680 if(hi2s->TxXferCount != 0)
682 if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) == SPI_SR_TXE)
685 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
688 if(hi2s->TxXferCount == 0)
690 /* Disable I2Sext TXE interrupt */
691 I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE;
693 HAL_I2S_TxCpltCallback(hi2s);
697 if(hi2s->RxXferCount != 0)
699 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE) != RESET)
702 (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
705 if(hi2s->RxXferCount == 0)
707 /* Disable RXNE interrupt */
708 __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_RXNE);
710 HAL_I2S_RxCpltCallback(hi2s);
716 tmp1 = hi2s->RxXferCount;
717 tmp2 = hi2s->TxXferCount;
718 if((tmp1 == 0) && (tmp2 == 0))
720 /* Disable I2Sx ERR interrupt */
721 __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_ERR);
722 /* Disable I2Sext ERR interrupt */
723 I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_ERR;
725 hi2s->State = HAL_I2S_STATE_READY;
728 /* Process Unlocked */
743 #endif /* HAL_I2S_MODULE_ENABLED */
752 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/