1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_i2s_ex.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 I2S extension peripheral:
8 * + Extension features Functions
9 ******************************************************************************
10 * @attention
11 *
12 * Copyright (c) 2016 STMicroelectronics.
13 * All rights reserved.
14 *
15 * This software is licensed under terms that can be found in the LICENSE file
16 * in the root directory of this software component.
17 * If no LICENSE file comes with this software, it is provided AS-IS.
18 *
19 ******************************************************************************
20 @verbatim
21 ==============================================================================
22 ##### I2S Extension features #####
23 ==============================================================================
24 [..]
25 (#) In I2S full duplex mode, each SPI peripheral is able to manage sending and receiving
26 data simultaneously using two data lines. Each SPI peripheral has an extended block
27 called I2Sxext (i.e I2S2ext for SPI2 and I2S3ext for SPI3).
28 (#) The extension block is not a full SPI IP, it is used only as I2S slave to
29 implement full duplex mode. The extension block uses the same clock sources
30 as its master.
31
32 (#) Both I2Sx and I2Sx_ext can be configured as transmitters or receivers.
33
34 [..]
35 (@) Only I2Sx can deliver SCK and WS to I2Sx_ext in full duplex mode, where
36 I2Sx can be I2S2 or I2S3.
37
38 ##### How to use this driver #####
39 ===============================================================================
40 [..]
41 Three operation modes are available within this driver :
42
43 *** Polling mode IO operation ***
44 =================================
45 [..]
46 (+) Send and receive in the same time an amount of data in blocking mode using HAL_I2SEx_TransmitReceive()
47
48 *** Interrupt mode IO operation ***
49 ===================================
50 [..]
51 (+) Send and receive in the same time an amount of data in non blocking mode using HAL_I2SEx_TransmitReceive_IT()
52 (+) At transmission/reception end of transfer HAL_I2SEx_TxRxCpltCallback is executed and user can
53 add his own code by customization of function pointer HAL_I2SEx_TxRxCpltCallback
54 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
55 add his own code by customization of function pointer HAL_I2S_ErrorCallback
56
57 *** DMA mode IO operation ***
58 ==============================
59 [..]
60 (+) Send and receive an amount of data in non blocking mode (DMA) using HAL_I2SEx_TransmitReceive_DMA()
61 (+) At transmission/reception end of transfer HAL_I2SEx_TxRxCpltCallback is executed and user can
62 add his own code by customization of function pointer HAL_I2S_TxRxCpltCallback
63 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
64 add his own code by customization of function pointer HAL_I2S_ErrorCallback
65 (+) __HAL_I2SEXT_FLUSH_RX_DR: In Full-Duplex Slave mode, if HAL_I2S_DMAStop is used to stop the
66 communication, an error HAL_I2S_ERROR_BUSY_LINE_RX is raised as the master continue to transmit data.
67 In this case __HAL_I2SEXT_FLUSH_RX_DR macro must be used to flush the remaining data
68 inside I2Sx and I2Sx_ext DR registers and avoid using DeInit/Init process for the next transfer.
69 @endverbatim
70
71 Additional Figure: The Extended block uses the same clock sources as its master.
72
73 +-----------------------+
74 I2Sx_SCK | |
75 ----------+-->| I2Sx |------------------->I2Sx_SD(in/out)
76 +--|-->| |
77 | | +-----------------------+
78 | |
79 I2S_WS | |
80 ------>| |
81 | | +-----------------------+
82 | +-->| |
83 | | I2Sx_ext |------------------->I2Sx_extSD(in/out)
84 +----->| |
85 +-----------------------+
86 */
87
88 /* Includes ------------------------------------------------------------------*/
89 #include "stm32f4xx_hal.h"
90
91 /** @addtogroup STM32F4xx_HAL_Driver
92 * @{
93 */
94
95 #ifdef HAL_I2S_MODULE_ENABLED
96
97 /** @defgroup I2SEx I2SEx
98 * @brief I2S Extended HAL module driver
99 * @{
100 */
101
102 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
103
104 /* Private typedef -----------------------------------------------------------*/
105 /** @defgroup I2SEx_Private_Typedef I2S Extended Private Typedef
106 * @{
107 */
108 typedef enum
109 {
110 I2S_USE_I2S = 0x00U, /*!< I2Sx should be used */
111 I2S_USE_I2SEXT = 0x01U, /*!< I2Sx_ext should be used */
112 } I2S_UseTypeDef;
113 /**
114 * @}
115 */
116 /* Private define ------------------------------------------------------------*/
117 /* Private macro -------------------------------------------------------------*/
118 /* Private variables ---------------------------------------------------------*/
119 /* Private function prototypes -----------------------------------------------*/
120 /** @defgroup I2SEx_Private_Functions I2S Extended Private Functions
121 * @{
122 */
123 static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma);
124 static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma);
125 static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma);
126 static void I2SEx_RxISR_I2S(I2S_HandleTypeDef *hi2s);
127 static void I2SEx_RxISR_I2SExt(I2S_HandleTypeDef *hi2s);
128 static void I2SEx_TxISR_I2S(I2S_HandleTypeDef *hi2s);
129 static void I2SEx_TxISR_I2SExt(I2S_HandleTypeDef *hi2s);
130 static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s,
131 uint32_t Flag,
132 uint32_t State,
133 uint32_t Timeout,
134 I2S_UseTypeDef i2sUsed);
135 /**
136 * @}
137 */
138
139 /**
140 * @}
141 */
142
143 /* Private functions ---------------------------------------------------------*/
144 /* Exported functions --------------------------------------------------------*/
145
146 /** @addtogroup I2SEx I2SEx
147 * @{
148 */
149
150 /** @addtogroup I2SEx_Exported_Functions I2S Extended Exported Functions
151 * @{
152 */
153
154 /** @defgroup I2SEx_Exported_Functions_Group1 I2S Extended IO operation functions
155 * @brief I2SEx IO operation functions
156 *
157 @verbatim
158 ===============================================================================
159 ##### IO operation functions#####
160 ===============================================================================
161 [..]
162 This subsection provides a set of functions allowing to manage the I2S data
163 transfers.
164
165 (#) There are two modes of transfer:
166 (++) Blocking mode : The communication is performed in the polling mode.
167 The status of all data processing is returned by the same function
168 after finishing transfer.
169 (++) No-Blocking mode : The communication is performed using Interrupts
170 or DMA. These functions return the status of the transfer startup.
171 The end of the data processing will be indicated through the
172 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
173 using DMA mode.
174
175 (#) Blocking mode functions are :
176 (++) HAL_I2SEx_TransmitReceive()
177
178 (#) No-Blocking mode functions with Interrupt are :
179 (++) HAL_I2SEx_TransmitReceive_IT()
180 (++) HAL_I2SEx_FullDuplex_IRQHandler()
181
182 (#) No-Blocking mode functions with DMA are :
183 (++) HAL_I2SEx_TransmitReceive_DMA()
184
185 (#) A set of Transfer Complete Callback are provided in non Blocking mode:
186 (++) HAL_I2SEx_TxRxCpltCallback()
187 @endverbatim
188 * @{
189 */
190 /**
191 * @brief Full-Duplex Transmit/Receive data in blocking mode.
192 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
193 * the configuration information for I2S module
194 * @param pTxData a 16-bit pointer to the Transmit data buffer.
195 * @param pRxData a 16-bit pointer to the Receive data buffer.
196 * @param Size number of data sample to be sent:
197 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
198 * configuration phase, the Size parameter means the number of 16-bit data length
199 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
200 * the Size parameter means the number of 16-bit data length.
201 * @param Timeout Timeout duration
202 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
203 * between Master and Slave(example: audio streaming).
204 * @retval HAL status
205 */
HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef * hi2s,uint16_t * pTxData,uint16_t * pRxData,uint16_t Size,uint32_t Timeout)206 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s,
207 uint16_t *pTxData,
208 uint16_t *pRxData,
209 uint16_t Size,
210 uint32_t Timeout)
211 {
212 uint32_t tmp1 = 0U;
213
214 if (hi2s->State != HAL_I2S_STATE_READY)
215 {
216 return HAL_BUSY;
217 }
218
219 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
220 {
221 return HAL_ERROR;
222 }
223
224 /* Process Locked */
225 __HAL_LOCK(hi2s);
226
227 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
228 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
229 is selected during the I2S configuration phase, the Size parameter means the number
230 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
231 frame is selected the Size parameter means the number of 16-bit data length. */
232 if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
233 {
234 hi2s->TxXferSize = (Size << 1U);
235 hi2s->TxXferCount = (Size << 1U);
236 hi2s->RxXferSize = (Size << 1U);
237 hi2s->RxXferCount = (Size << 1U);
238 }
239 else
240 {
241 hi2s->TxXferSize = Size;
242 hi2s->TxXferCount = Size;
243 hi2s->RxXferSize = Size;
244 hi2s->RxXferCount = Size;
245 }
246
247 /* Set state and reset error code */
248 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
249 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
250
251 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
252 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
253 if ((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX))
254 {
255 /* Prepare the First Data before enabling the I2S */
256 hi2s->Instance->DR = (*pTxData++);
257 hi2s->TxXferCount--;
258
259 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
260 __HAL_I2SEXT_ENABLE(hi2s);
261
262 /* Enable I2Sx peripheral */
263 __HAL_I2S_ENABLE(hi2s);
264
265 /* Check if Master Receiver mode is selected */
266 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX)
267 {
268 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
269 access to the SPI_SR register. */
270 __HAL_I2SEXT_CLEAR_OVRFLAG(hi2s);
271 }
272
273 while ((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U))
274 {
275 if (hi2s->TxXferCount > 0U)
276 {
277 /* Wait until TXE flag is set */
278 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2S) != HAL_OK)
279 {
280 /* Set the error code */
281 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
282 hi2s->State = HAL_I2S_STATE_READY;
283
284 /* Process UnLock */
285 __HAL_UNLOCK(hi2s);
286 return HAL_ERROR;
287 }
288 /* Write Data on DR register */
289 hi2s->Instance->DR = (*pTxData++);
290 hi2s->TxXferCount--;
291
292 /* Check if an underrun occurs */
293 if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_TX))
294 {
295 /* Clear Underrun flag */
296 __HAL_I2S_CLEAR_UDRFLAG(hi2s);
297
298 /* Set the error code */
299 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
300 }
301 }
302 if (hi2s->RxXferCount > 0U)
303 {
304 /* Wait until RXNE flag is set */
305 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK)
306 {
307 /* Set the error code */
308 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
309 hi2s->State = HAL_I2S_STATE_READY;
310
311 /* Process UnLock */
312 __HAL_UNLOCK(hi2s);
313 return HAL_ERROR;
314 }
315 /* Read Data from DR register */
316 (*pRxData++) = I2SxEXT(hi2s->Instance)->DR;
317 hi2s->RxXferCount--;
318
319 /* Check if an overrun occurs */
320 if (__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
321 {
322 /* Clear Overrun flag */
323 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
324
325 /* Set the error code */
326 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
327 }
328 }
329 }
330 }
331 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
332 else
333 {
334 /* Prepare the First Data before enabling the I2S */
335 I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
336 hi2s->TxXferCount--;
337
338 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
339 __HAL_I2SEXT_ENABLE(hi2s);
340
341 /* Enable I2S peripheral before the I2Sext*/
342 __HAL_I2S_ENABLE(hi2s);
343
344 /* Check if Master Receiver mode is selected */
345 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
346 {
347 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
348 access to the SPI_SR register. */
349 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
350 }
351
352 while ((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U))
353 {
354 if (hi2s->TxXferCount > 0U)
355 {
356 /* Wait until TXE flag is set */
357 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK)
358 {
359 /* Set the error code */
360 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
361 hi2s->State = HAL_I2S_STATE_READY;
362
363 /* Process UnLock */
364 __HAL_UNLOCK(hi2s);
365 return HAL_ERROR;
366 }
367 /* Write Data on DR register */
368 I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
369 hi2s->TxXferCount--;
370
371 /* Check if an underrun occurs */
372 if ((__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_RX))
373 {
374 /* Clear Underrun flag */
375 __HAL_I2S_CLEAR_UDRFLAG(hi2s);
376
377 /* Set the error code */
378 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
379 }
380 }
381 if (hi2s->RxXferCount > 0U)
382 {
383 /* Wait until RXNE flag is set */
384 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2S) != HAL_OK)
385 {
386 /* Set the error code */
387 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
388 hi2s->State = HAL_I2S_STATE_READY;
389
390 /* Process UnLock */
391 __HAL_UNLOCK(hi2s);
392 return HAL_ERROR;
393 }
394 /* Read Data from DR register */
395 (*pRxData++) = hi2s->Instance->DR;
396 hi2s->RxXferCount--;
397
398 /* Check if an overrun occurs */
399 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
400 {
401 /* Clear Overrun flag */
402 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
403
404 /* Set the error code */
405 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
406 }
407 }
408 }
409 }
410
411 hi2s->State = HAL_I2S_STATE_READY;
412 __HAL_UNLOCK(hi2s);
413
414 if (hi2s->ErrorCode != HAL_I2S_ERROR_NONE)
415 {
416 return HAL_ERROR;
417 }
418 else
419 {
420 return HAL_OK;
421 }
422 }
423
424 /**
425 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
426 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
427 * the configuration information for I2S module
428 * @param pTxData a 16-bit pointer to the Transmit data buffer.
429 * @param pRxData a 16-bit pointer to the Receive data buffer.
430 * @param Size number of data sample to be sent:
431 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
432 * configuration phase, the Size parameter means the number of 16-bit data length
433 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
434 * the Size parameter means the number of 16-bit data length.
435 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
436 * between Master and Slave(example: audio streaming).
437 * @retval HAL status
438 */
HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pTxData,uint16_t * pRxData,uint16_t Size)439 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s,
440 uint16_t *pTxData,
441 uint16_t *pRxData,
442 uint16_t Size)
443 {
444 uint32_t tmp1 = 0U;
445
446 if (hi2s->State != HAL_I2S_STATE_READY)
447 {
448 return HAL_BUSY;
449 }
450
451 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
452 {
453 return HAL_ERROR;
454 }
455
456 /* Process Locked */
457 __HAL_LOCK(hi2s);
458
459 hi2s->pTxBuffPtr = pTxData;
460 hi2s->pRxBuffPtr = pRxData;
461
462 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
463 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
464 is selected during the I2S configuration phase, the Size parameter means the number
465 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
466 frame is selected the Size parameter means the number of 16-bit data length. */
467 if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
468 {
469 hi2s->TxXferSize = (Size << 1U);
470 hi2s->TxXferCount = (Size << 1U);
471 hi2s->RxXferSize = (Size << 1U);
472 hi2s->RxXferCount = (Size << 1U);
473 }
474 else
475 {
476 hi2s->TxXferSize = Size;
477 hi2s->TxXferCount = Size;
478 hi2s->RxXferSize = Size;
479 hi2s->RxXferCount = Size;
480 }
481
482 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
483 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
484
485 /* Set the function for IT treatment */
486 if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
487 {
488 /* Enable I2Sext RXNE and ERR interrupts */
489 __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
490
491 /* Enable I2Sx TXE and ERR interrupts */
492 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
493
494 /* Transmit First data */
495 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
496 hi2s->TxXferCount--;
497
498 if (hi2s->TxXferCount == 0U)
499 {
500 /* Disable TXE and ERR interrupt */
501 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
502 }
503 }
504 else /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
505 {
506 /* Enable I2Sext TXE and ERR interrupts */
507 __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
508
509 /* Enable I2Sext RXNE and ERR interrupts */
510 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
511
512 /* Transmit First data */
513 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
514 hi2s->TxXferCount--;
515
516 if (hi2s->TxXferCount == 0U)
517 {
518 /* Disable I2Sext TXE and ERR interrupt */
519 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
520 }
521 }
522
523 __HAL_UNLOCK(hi2s);
524 /* Enable I2Sext peripheral */
525 __HAL_I2SEXT_ENABLE(hi2s);
526
527 /* Enable I2S peripheral */
528 __HAL_I2S_ENABLE(hi2s);
529
530 return HAL_OK;
531 }
532
533 /**
534 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA
535 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
536 * the configuration information for I2S module
537 * @param pTxData a 16-bit pointer to the Transmit data buffer.
538 * @param pRxData a 16-bit pointer to the Receive data buffer.
539 * @param Size number of data sample to be sent:
540 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
541 * configuration phase, the Size parameter means the number of 16-bit data length
542 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
543 * the Size parameter means the number of 16-bit data length.
544 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
545 * between Master and Slave(example: audio streaming).
546 * @retval HAL status
547 */
HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pTxData,uint16_t * pRxData,uint16_t Size)548 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s,
549 uint16_t *pTxData,
550 uint16_t *pRxData,
551 uint16_t Size)
552 {
553 uint32_t *tmp = NULL;
554 uint32_t tmp1 = 0U;
555
556 if (hi2s->State != HAL_I2S_STATE_READY)
557 {
558 return HAL_BUSY;
559 }
560
561 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
562 {
563 return HAL_ERROR;
564 }
565
566 /* Process Locked */
567 __HAL_LOCK(hi2s);
568
569 hi2s->pTxBuffPtr = pTxData;
570 hi2s->pRxBuffPtr = pRxData;
571
572 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
573 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
574 is selected during the I2S configuration phase, the Size parameter means the number
575 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
576 frame is selected the Size parameter means the number of 16-bit data length. */
577 if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
578 {
579 hi2s->TxXferSize = (Size << 1U);
580 hi2s->TxXferCount = (Size << 1U);
581 hi2s->RxXferSize = (Size << 1U);
582 hi2s->RxXferCount = (Size << 1U);
583 }
584 else
585 {
586 hi2s->TxXferSize = Size;
587 hi2s->TxXferCount = Size;
588 hi2s->RxXferSize = Size;
589 hi2s->RxXferCount = Size;
590 }
591
592 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
593 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
594
595 /* Set the I2S Rx DMA Half transfer complete callback */
596 hi2s->hdmarx->XferHalfCpltCallback = I2SEx_TxRxDMAHalfCplt;
597
598 /* Set the I2S Rx DMA transfer complete callback */
599 hi2s->hdmarx->XferCpltCallback = I2SEx_TxRxDMACplt;
600
601 /* Set the I2S Rx DMA error callback */
602 hi2s->hdmarx->XferErrorCallback = I2SEx_TxRxDMAError;
603
604 /* Set the I2S Tx DMA Half transfer complete callback as NULL */
605 hi2s->hdmatx->XferHalfCpltCallback = NULL;
606
607 /* Set the I2S Tx DMA transfer complete callback as NULL */
608 hi2s->hdmatx->XferCpltCallback = NULL;
609
610 /* Set the I2S Tx DMA error callback */
611 hi2s->hdmatx->XferErrorCallback = I2SEx_TxRxDMAError;
612
613 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
614 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
615 if ((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX))
616 {
617 /* Enable the Rx DMA Stream */
618 tmp = (uint32_t *)&pRxData;
619 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t *)tmp, hi2s->RxXferSize);
620
621 /* Enable Rx DMA Request */
622 SET_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_RXDMAEN);
623
624 /* Enable the Tx DMA Stream */
625 tmp = (uint32_t *)&pTxData;
626 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t *)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
627
628 /* Enable Tx DMA Request */
629 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
630 }
631 else
632 {
633 /* Check if Master Receiver mode is selected */
634 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
635 {
636 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
637 access to the SPI_SR register. */
638 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
639 }
640 /* Enable the Tx DMA Stream */
641 tmp = (uint32_t *)&pTxData;
642 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t *)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize);
643
644 /* Enable Tx DMA Request */
645 SET_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_TXDMAEN);
646
647 /* Enable the Rx DMA Stream */
648 tmp = (uint32_t *)&pRxData;
649 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t *)tmp, hi2s->RxXferSize);
650
651 /* Enable Rx DMA Request */
652 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
653 }
654
655 __HAL_UNLOCK(hi2s);
656 /* Check if the I2S is already enabled */
657 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
658 {
659 /* Enable I2Sext(transmitter) before enabling I2Sx peripheral */
660 __HAL_I2SEXT_ENABLE(hi2s);
661 /* Enable I2S peripheral before the I2Sext */
662 __HAL_I2S_ENABLE(hi2s);
663 }
664
665 return HAL_OK;
666 }
667
668 /**
669 * @brief This function handles I2S/I2Sext interrupt requests in full-duplex mode.
670 * @param hi2s I2S handle
671 * @retval HAL status
672 */
HAL_I2SEx_FullDuplex_IRQHandler(I2S_HandleTypeDef * hi2s)673 void HAL_I2SEx_FullDuplex_IRQHandler(I2S_HandleTypeDef *hi2s)
674 {
675 __IO uint32_t i2ssr = hi2s->Instance->SR;
676 __IO uint32_t i2sextsr = I2SxEXT(hi2s->Instance)->SR;
677 __IO uint32_t i2scr2 = hi2s->Instance->CR2;
678 __IO uint32_t i2sextcr2 = I2SxEXT(hi2s->Instance)->CR2;
679
680 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
681 if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
682 {
683 /* I2S in mode Transmitter -------------------------------------------------*/
684 if (((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && ((i2scr2 & I2S_IT_TXE) != RESET))
685 {
686 /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX,
687 the I2S TXE interrupt will be generated to manage the full-duplex transmit phase. */
688 I2SEx_TxISR_I2S(hi2s);
689 }
690
691 /* I2Sext in mode Receiver -----------------------------------------------*/
692 if (((i2sextsr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && ((i2sextcr2 & I2S_IT_RXNE) != RESET))
693 {
694 /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX,
695 the I2Sext RXNE interrupt will be generated to manage the full-duplex receive phase. */
696 I2SEx_RxISR_I2SExt(hi2s);
697 }
698
699 /* I2Sext Overrun error interrupt occurred --------------------------------*/
700 if (((i2sextsr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && ((i2sextcr2 & I2S_IT_ERR) != RESET))
701 {
702 /* Disable RXNE and ERR interrupt */
703 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
704
705 /* Disable TXE and ERR interrupt */
706 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
707
708 /* Clear Overrun flag */
709 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
710
711 /* Set the I2S State ready */
712 hi2s->State = HAL_I2S_STATE_READY;
713
714 /* Set the error code and execute error callback*/
715 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
716 /* Call user error callback */
717 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
718 hi2s->ErrorCallback(hi2s);
719 #else
720 HAL_I2S_ErrorCallback(hi2s);
721 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
722 }
723
724 /* I2S Underrun error interrupt occurred ----------------------------------*/
725 if (((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && ((i2scr2 & I2S_IT_ERR) != RESET))
726 {
727 /* Disable TXE and ERR interrupt */
728 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
729
730 /* Disable RXNE and ERR interrupt */
731 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
732
733 /* Clear underrun flag */
734 __HAL_I2S_CLEAR_UDRFLAG(hi2s);
735
736 /* Set the I2S State ready */
737 hi2s->State = HAL_I2S_STATE_READY;
738
739 /* Set the error code and execute error callback*/
740 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
741 /* Call user error callback */
742 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
743 hi2s->ErrorCallback(hi2s);
744 #else
745 HAL_I2S_ErrorCallback(hi2s);
746 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
747 }
748 }
749 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
750 else
751 {
752 /* I2Sext in mode Transmitter ----------------------------------------------*/
753 if (((i2sextsr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && ((i2sextcr2 & I2S_IT_TXE) != RESET))
754 {
755 /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX,
756 the I2Sext TXE interrupt will be generated to manage the full-duplex transmit phase. */
757 I2SEx_TxISR_I2SExt(hi2s);
758 }
759
760 /* I2S in mode Receiver --------------------------------------------------*/
761 if (((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && ((i2scr2 & I2S_IT_RXNE) != RESET))
762 {
763 /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX,
764 the I2S RXNE interrupt will be generated to manage the full-duplex receive phase. */
765 I2SEx_RxISR_I2S(hi2s);
766 }
767
768 /* I2S Overrun error interrupt occurred -------------------------------------*/
769 if (((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && ((i2scr2 & I2S_IT_ERR) != RESET))
770 {
771 /* Disable RXNE and ERR interrupt */
772 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
773
774 /* Disable TXE and ERR interrupt */
775 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
776
777 /* Set the I2S State ready */
778 hi2s->State = HAL_I2S_STATE_READY;
779
780 /* Set the error code and execute error callback*/
781 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
782 /* Call user error callback */
783 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
784 hi2s->ErrorCallback(hi2s);
785 #else
786 HAL_I2S_ErrorCallback(hi2s);
787 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
788 }
789
790 /* I2Sext Underrun error interrupt occurred -------------------------------*/
791 if (((i2sextsr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && ((i2sextcr2 & I2S_IT_ERR) != RESET))
792 {
793 /* Disable TXE and ERR interrupt */
794 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
795
796 /* Disable RXNE and ERR interrupt */
797 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
798
799 /* Set the I2S State ready */
800 hi2s->State = HAL_I2S_STATE_READY;
801
802 /* Set the error code and execute error callback*/
803 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
804 /* Call user error callback */
805 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
806 hi2s->ErrorCallback(hi2s);
807 #else
808 HAL_I2S_ErrorCallback(hi2s);
809 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
810 }
811 }
812 }
813
814 /**
815 * @brief Tx and Rx Transfer half completed callback
816 * @param hi2s I2S handle
817 * @retval None
818 */
HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef * hi2s)819 __weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
820 {
821 /* Prevent unused argument(s) compilation warning */
822 UNUSED(hi2s);
823
824 /* NOTE : This function Should not be modified, when the callback is needed,
825 the HAL_I2SEx_TxRxHalfCpltCallback could be implemented in the user file
826 */
827 }
828
829 /**
830 * @brief Tx and Rx Transfer completed callback
831 * @param hi2s I2S handle
832 * @retval None
833 */
HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef * hi2s)834 __weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
835 {
836 /* Prevent unused argument(s) compilation warning */
837 UNUSED(hi2s);
838
839 /* NOTE : This function should not be modified, when the callback is needed,
840 the HAL_I2SEx_TxRxCpltCallback could be implemented in the user file
841 */
842 }
843
844 /**
845 * @}
846 */
847
848 /**
849 * @}
850 */
851
852 /** @addtogroup I2SEx_Private_Functions I2S Extended Private Functions
853 * @{
854 */
855
856 /**
857 * @brief DMA I2S transmit receive process half complete callback
858 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
859 * the configuration information for the specified DMA module.
860 * @retval None
861 */
I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef * hdma)862 static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma)
863 {
864 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
865
866 /* Call user TxRx Half complete callback */
867 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
868 hi2s->TxRxHalfCpltCallback(hi2s);
869 #else
870 HAL_I2SEx_TxRxHalfCpltCallback(hi2s);
871 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
872 }
873
874 /**
875 * @brief DMA I2S transmit receive process complete callback
876 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
877 * the configuration information for the specified DMA module.
878 * @retval None
879 */
I2SEx_TxRxDMACplt(DMA_HandleTypeDef * hdma)880 static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma)
881 {
882 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
883
884 /* If DMA is configured in DMA_NORMAL mode */
885 if (hdma->Init.Mode == DMA_NORMAL)
886 {
887 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || \
888 ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
889 /* Disable Tx & Rx DMA Requests */
890 {
891 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_RXDMAEN);
892 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
893 }
894 else
895 {
896 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
897 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_TXDMAEN);
898 }
899
900 hi2s->RxXferCount = 0U;
901 hi2s->TxXferCount = 0U;
902
903 hi2s->State = HAL_I2S_STATE_READY;
904 }
905
906 /* Call user TxRx complete callback */
907 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
908 hi2s->TxRxCpltCallback(hi2s);
909 #else
910 HAL_I2SEx_TxRxCpltCallback(hi2s);
911 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
912 }
913
914 /**
915 * @brief DMA I2S communication error callback
916 * @param hdma DMA handle
917 * @retval None
918 */
I2SEx_TxRxDMAError(DMA_HandleTypeDef * hdma)919 static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma)
920 {
921 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
922
923 /* Disable Rx and Tx DMA Request */
924 CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
925 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
926
927 hi2s->TxXferCount = 0U;
928 hi2s->RxXferCount = 0U;
929
930 hi2s->State = HAL_I2S_STATE_READY;
931
932 /* Set the error code and execute error callback*/
933 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
934 /* Call user error callback */
935 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
936 hi2s->ErrorCallback(hi2s);
937 #else
938 HAL_I2S_ErrorCallback(hi2s);
939 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
940 }
941
942 /**
943 * @brief I2S Full-Duplex IT handler transmit function
944 * @param hi2s I2S handle
945 * @retval None
946 */
I2SEx_TxISR_I2S(I2S_HandleTypeDef * hi2s)947 static void I2SEx_TxISR_I2S(I2S_HandleTypeDef *hi2s)
948 {
949 /* Write Data on DR register */
950 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
951 hi2s->TxXferCount--;
952
953 if (hi2s->TxXferCount == 0U)
954 {
955 /* Disable TXE and ERR interrupt */
956 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
957
958 if (hi2s->RxXferCount == 0U)
959 {
960 hi2s->State = HAL_I2S_STATE_READY;
961 /* Call user TxRx complete callback */
962 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
963 hi2s->TxRxCpltCallback(hi2s);
964 #else
965 HAL_I2SEx_TxRxCpltCallback(hi2s);
966 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
967 }
968 }
969 }
970
971 /**
972 * @brief I2SExt Full-Duplex IT handler transmit function
973 * @param hi2s I2S handle
974 * @retval None
975 */
I2SEx_TxISR_I2SExt(I2S_HandleTypeDef * hi2s)976 static void I2SEx_TxISR_I2SExt(I2S_HandleTypeDef *hi2s)
977 {
978 /* Write Data on DR register */
979 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
980 hi2s->TxXferCount--;
981
982 if (hi2s->TxXferCount == 0U)
983 {
984 /* Disable I2Sext TXE and ERR interrupt */
985 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
986
987 if (hi2s->RxXferCount == 0U)
988 {
989 hi2s->State = HAL_I2S_STATE_READY;
990 /* Call user TxRx complete callback */
991 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
992 hi2s->TxRxCpltCallback(hi2s);
993 #else
994 HAL_I2SEx_TxRxCpltCallback(hi2s);
995 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
996 }
997 }
998 }
999
1000 /**
1001 * @brief I2S Full-Duplex IT handler receive function
1002 * @param hi2s I2S handle
1003 * @retval None
1004 */
I2SEx_RxISR_I2S(I2S_HandleTypeDef * hi2s)1005 static void I2SEx_RxISR_I2S(I2S_HandleTypeDef *hi2s)
1006 {
1007 /* Read Data from DR register */
1008 (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
1009 hi2s->RxXferCount--;
1010
1011 if (hi2s->RxXferCount == 0U)
1012 {
1013 /* Disable RXNE and ERR interrupt */
1014 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1015
1016 if (hi2s->TxXferCount == 0U)
1017 {
1018 hi2s->State = HAL_I2S_STATE_READY;
1019 /* Call user TxRx complete callback */
1020 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1021 hi2s->TxRxCpltCallback(hi2s);
1022 #else
1023 HAL_I2SEx_TxRxCpltCallback(hi2s);
1024 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1025 }
1026 }
1027 }
1028
1029 /**
1030 * @brief I2SExt Full-Duplex IT handler receive function
1031 * @param hi2s I2S handle
1032 * @retval None
1033 */
I2SEx_RxISR_I2SExt(I2S_HandleTypeDef * hi2s)1034 static void I2SEx_RxISR_I2SExt(I2S_HandleTypeDef *hi2s)
1035 {
1036 /* Read Data from DR register */
1037 (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR;
1038 hi2s->RxXferCount--;
1039
1040 if (hi2s->RxXferCount == 0U)
1041 {
1042 /* Disable I2Sext RXNE and ERR interrupt */
1043 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1044
1045 if (hi2s->TxXferCount == 0U)
1046 {
1047 hi2s->State = HAL_I2S_STATE_READY;
1048 /* Call user TxRx complete callback */
1049 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1050 hi2s->TxRxCpltCallback(hi2s);
1051 #else
1052 HAL_I2SEx_TxRxCpltCallback(hi2s);
1053 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1054 }
1055 }
1056 }
1057
1058 /**
1059 * @brief This function handles I2S Communication Timeout.
1060 * @param hi2s I2S handle
1061 * @param Flag Flag checked
1062 * @param State Value of the flag expected
1063 * @param Timeout Duration of the timeout
1064 * @param i2sUsed I2S instance reference
1065 * @retval HAL status
1066 */
I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,uint32_t State,uint32_t Timeout,I2S_UseTypeDef i2sUsed)1067 static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s,
1068 uint32_t Flag,
1069 uint32_t State,
1070 uint32_t Timeout,
1071 I2S_UseTypeDef i2sUsed)
1072 {
1073 uint32_t tickstart = HAL_GetTick();
1074
1075 if (i2sUsed == I2S_USE_I2S)
1076 {
1077 /* Wait until flag is reset */
1078 while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1079 {
1080 if (Timeout != HAL_MAX_DELAY)
1081 {
1082 if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1083 {
1084 /* Set the I2S State ready */
1085 hi2s->State = HAL_I2S_STATE_READY;
1086
1087 /* Process Unlocked */
1088 __HAL_UNLOCK(hi2s);
1089
1090 return HAL_TIMEOUT;
1091 }
1092 }
1093 }
1094 }
1095 else /* i2sUsed == I2S_USE_I2SEXT */
1096 {
1097 /* Wait until flag is reset */
1098 while (((__HAL_I2SEXT_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1099 {
1100 if (Timeout != HAL_MAX_DELAY)
1101 {
1102 if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1103 {
1104 /* Set the I2S State ready */
1105 hi2s->State = HAL_I2S_STATE_READY;
1106
1107 /* Process Unlocked */
1108 __HAL_UNLOCK(hi2s);
1109
1110 return HAL_TIMEOUT;
1111 }
1112 }
1113 }
1114 }
1115 return HAL_OK;
1116 }
1117
1118 /**
1119 * @}
1120 */
1121 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
1122
1123 /**
1124 * @}
1125 */
1126 #endif /* HAL_I2S_MODULE_ENABLED */
1127
1128 /**
1129 * @}
1130 */
1131
1132