1 /**
2   ******************************************************************************
3   * @file    stm32f3xx_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 "stm32f3xx_hal.h"
90 
91 /** @addtogroup STM32F3xx_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   HAL_StatusTypeDef errorcode = HAL_OK;
214 
215   if (hi2s->State != HAL_I2S_STATE_READY)
216   {
217     errorcode = HAL_BUSY;
218     goto error;
219   }
220 
221   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
222   {
223     return  HAL_ERROR;
224   }
225 
226   /* Process Locked */
227   __HAL_LOCK(hi2s);
228 
229   tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
230   /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
231      is selected during the I2S configuration phase, the Size parameter means the number
232      of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
233      frame is selected the Size parameter means the number of 16-bit data length. */
234   if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
235   {
236     hi2s->TxXferSize  = (Size << 1U);
237     hi2s->TxXferCount = (Size << 1U);
238     hi2s->RxXferSize  = (Size << 1U);
239     hi2s->RxXferCount = (Size << 1U);
240   }
241   else
242   {
243     hi2s->TxXferSize  = Size;
244     hi2s->TxXferCount = Size;
245     hi2s->RxXferSize  = Size;
246     hi2s->RxXferCount = Size;
247   }
248 
249   /* Set state and reset error code */
250   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
251   hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
252 
253   tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
254   /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
255   if ((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX))
256   {
257     /* Prepare the First Data before enabling the I2S */
258     hi2s->Instance->DR = (*pTxData++);
259     hi2s->TxXferCount--;
260 
261     /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
262     __HAL_I2SEXT_ENABLE(hi2s);
263 
264     /* Enable I2Sx peripheral */
265     __HAL_I2S_ENABLE(hi2s);
266 
267     /* Check if Master Receiver mode is selected */
268     if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX)
269     {
270       /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
271       access to the SPI_SR register. */
272       __HAL_I2SEXT_CLEAR_OVRFLAG(hi2s);
273     }
274 
275     while ((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U))
276     {
277       if (hi2s->TxXferCount > 0U)
278       {
279         /* Wait until TXE flag is set */
280         if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2S) != HAL_OK)
281         {
282           /* Set the error code */
283           SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
284           errorcode = HAL_ERROR;
285           goto error;
286         }
287         /* Write Data on DR register */
288         hi2s->Instance->DR = (*pTxData++);
289         hi2s->TxXferCount--;
290 
291         /* Check if an underrun occurs */
292         if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_TX))
293         {
294           /* Clear Underrun flag */
295           __HAL_I2S_CLEAR_UDRFLAG(hi2s);
296 
297           /* Set the error code */
298           SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
299         }
300       }
301       if (hi2s->RxXferCount > 0U)
302       {
303         /* Wait until RXNE flag is set */
304         if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK)
305         {
306           /* Set the error code */
307           SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
308           errorcode = HAL_ERROR;
309           goto error;
310         }
311         /* Read Data from DR register */
312         (*pRxData++) = I2SxEXT(hi2s->Instance)->DR;
313         hi2s->RxXferCount--;
314 
315         /* Check if an overrun occurs */
316         if (__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
317         {
318           /* Clear Overrun flag */
319           __HAL_I2S_CLEAR_OVRFLAG(hi2s);
320 
321           /* Set the error code */
322           SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
323         }
324       }
325     }
326   }
327   /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
328   else
329   {
330     /* Prepare the First Data before enabling the I2S */
331     I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
332     hi2s->TxXferCount--;
333 
334     /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
335     __HAL_I2SEXT_ENABLE(hi2s);
336 
337     /* Enable I2S peripheral before the I2Sext*/
338     __HAL_I2S_ENABLE(hi2s);
339 
340     /* Check if Master Receiver mode is selected */
341     if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
342     {
343       /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
344       access to the SPI_SR register. */
345       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
346     }
347 
348     while ((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U))
349     {
350       if (hi2s->TxXferCount > 0U)
351       {
352         /* Wait until TXE flag is set */
353         if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK)
354         {
355           /* Set the error code */
356           SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
357           errorcode = HAL_ERROR;
358           goto error;
359         }
360         /* Write Data on DR register */
361         I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
362         hi2s->TxXferCount--;
363 
364         /* Check if an underrun occurs */
365         if ((__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_RX))
366         {
367           /* Clear Underrun flag */
368           __HAL_I2S_CLEAR_UDRFLAG(hi2s);
369 
370           /* Set the error code */
371           SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
372         }
373       }
374       if (hi2s->RxXferCount > 0U)
375       {
376         /* Wait until RXNE flag is set */
377         if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2S) != HAL_OK)
378         {
379           /* Set the error code */
380           SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
381           errorcode = HAL_ERROR;
382           goto error;
383         }
384         /* Read Data from DR register */
385         (*pRxData++) = hi2s->Instance->DR;
386         hi2s->RxXferCount--;
387 
388         /* Check if an overrun occurs */
389         if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
390         {
391           /* Clear Overrun flag */
392           __HAL_I2S_CLEAR_OVRFLAG(hi2s);
393 
394           /* Set the error code */
395           SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
396         }
397       }
398     }
399   }
400 
401   if (hi2s->ErrorCode != HAL_I2S_ERROR_NONE)
402   {
403     errorcode = HAL_ERROR;
404   }
405 
406 error :
407   hi2s->State = HAL_I2S_STATE_READY;
408   __HAL_UNLOCK(hi2s);
409   return errorcode;
410 }
411 
412 /**
413   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
414   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
415   *         the configuration information for I2S module
416   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
417   * @param  pRxData a 16-bit pointer to the Receive data buffer.
418   * @param  Size number of data sample to be sent:
419   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
420   *         configuration phase, the Size parameter means the number of 16-bit data length
421   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
422   *         the Size parameter means the number of 16-bit data length.
423   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
424   *         between Master and Slave(example: audio streaming).
425   * @retval HAL status
426   */
HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pTxData,uint16_t * pRxData,uint16_t Size)427 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s,
428                                                uint16_t *pTxData,
429                                                uint16_t *pRxData,
430                                                uint16_t Size)
431 {
432   uint32_t tmp1 = 0U;
433   HAL_StatusTypeDef errorcode = HAL_OK;
434 
435   if (hi2s->State != HAL_I2S_STATE_READY)
436   {
437     errorcode = HAL_BUSY;
438     goto error;
439   }
440 
441   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
442   {
443     return  HAL_ERROR;
444   }
445 
446   /* Process Locked */
447   __HAL_LOCK(hi2s);
448 
449   hi2s->pTxBuffPtr = pTxData;
450   hi2s->pRxBuffPtr = pRxData;
451 
452   tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
453   /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
454   is selected during the I2S configuration phase, the Size parameter means the number
455   of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
456   frame is selected the Size parameter means the number of 16-bit data length. */
457   if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
458   {
459     hi2s->TxXferSize  = (Size << 1U);
460     hi2s->TxXferCount = (Size << 1U);
461     hi2s->RxXferSize  = (Size << 1U);
462     hi2s->RxXferCount = (Size << 1U);
463   }
464   else
465   {
466     hi2s->TxXferSize  = Size;
467     hi2s->TxXferCount = Size;
468     hi2s->RxXferSize  = Size;
469     hi2s->RxXferCount = Size;
470   }
471 
472   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
473   hi2s->State     = HAL_I2S_STATE_BUSY_TX_RX;
474 
475   /* Set the function for IT treatment */
476   if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
477   {
478     /* Enable I2Sext RXNE and ERR interrupts */
479     __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
480 
481     /* Enable I2Sx TXE and ERR interrupts */
482     __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
483 
484     /* Transmit First data */
485     hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
486     hi2s->TxXferCount--;
487 
488     if (hi2s->TxXferCount == 0U)
489     {
490       /* Disable TXE and ERR interrupt */
491       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
492     }
493   }
494   else  /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
495   {
496     /* Enable I2Sext TXE and ERR interrupts */
497     __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
498 
499     /* Enable I2Sext RXNE and ERR interrupts */
500     __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
501 
502     /* Transmit First data */
503     I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
504     hi2s->TxXferCount--;
505 
506     if (hi2s->TxXferCount == 0U)
507     {
508       /* Disable I2Sext TXE and ERR interrupt */
509       __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
510     }
511   }
512 
513   /* Enable I2Sext peripheral */
514   __HAL_I2SEXT_ENABLE(hi2s);
515 
516   /* Enable I2S peripheral */
517   __HAL_I2S_ENABLE(hi2s);
518 
519 error :
520   __HAL_UNLOCK(hi2s);
521   return errorcode;
522 }
523 
524 /**
525   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using DMA
526   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
527   *         the configuration information for I2S module
528   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
529   * @param  pRxData a 16-bit pointer to the Receive data buffer.
530   * @param  Size number of data sample to be sent:
531   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
532   *         configuration phase, the Size parameter means the number of 16-bit data length
533   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
534   *         the Size parameter means the number of 16-bit data length.
535   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
536   *         between Master and Slave(example: audio streaming).
537   * @retval HAL status
538   */
HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pTxData,uint16_t * pRxData,uint16_t Size)539 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s,
540                                                 uint16_t *pTxData,
541                                                 uint16_t *pRxData,
542                                                 uint16_t Size)
543 {
544   uint32_t *tmp = NULL;
545   uint32_t tmp1 = 0U;
546   HAL_StatusTypeDef errorcode = HAL_OK;
547 
548   if (hi2s->State != HAL_I2S_STATE_READY)
549   {
550     errorcode = HAL_BUSY;
551     goto error;
552   }
553 
554   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
555   {
556     return  HAL_ERROR;
557   }
558 
559   /* Process Locked */
560   __HAL_LOCK(hi2s);
561 
562   hi2s->pTxBuffPtr = pTxData;
563   hi2s->pRxBuffPtr = pRxData;
564 
565   tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
566   /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
567   is selected during the I2S configuration phase, the Size parameter means the number
568   of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
569   frame is selected the Size parameter means the number of 16-bit data length. */
570   if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
571   {
572     hi2s->TxXferSize  = (Size << 1U);
573     hi2s->TxXferCount = (Size << 1U);
574     hi2s->RxXferSize  = (Size << 1U);
575     hi2s->RxXferCount = (Size << 1U);
576   }
577   else
578   {
579     hi2s->TxXferSize  = Size;
580     hi2s->TxXferCount = Size;
581     hi2s->RxXferSize  = Size;
582     hi2s->RxXferCount = Size;
583   }
584 
585   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
586   hi2s->State     = HAL_I2S_STATE_BUSY_TX_RX;
587 
588   /* Set the I2S Rx DMA Half transfer complete callback */
589   hi2s->hdmarx->XferHalfCpltCallback = I2SEx_TxRxDMAHalfCplt;
590 
591   /* Set the I2S Rx DMA transfer complete callback */
592   hi2s->hdmarx->XferCpltCallback  = I2SEx_TxRxDMACplt;
593 
594   /* Set the I2S Rx DMA error callback */
595   hi2s->hdmarx->XferErrorCallback = I2SEx_TxRxDMAError;
596 
597   /* Set the I2S Tx DMA Half transfer complete callback as NULL */
598   hi2s->hdmatx->XferHalfCpltCallback  = NULL;
599 
600   /* Set the I2S Tx DMA transfer complete callback as NULL */
601   hi2s->hdmatx->XferCpltCallback  = NULL;
602 
603   /* Set the I2S Tx DMA error callback */
604   hi2s->hdmatx->XferErrorCallback = I2SEx_TxRxDMAError;
605 
606   tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
607   /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
608   if ((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX))
609   {
610     /* Enable the Rx DMA Stream */
611     tmp = (uint32_t *)&pRxData;
612     HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t *)tmp, hi2s->RxXferSize);
613 
614     /* Enable Rx DMA Request */
615     SET_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_RXDMAEN);
616 
617     /* Enable the Tx DMA Stream */
618     tmp = (uint32_t *)&pTxData;
619     HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t *)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
620 
621     /* Enable Tx DMA Request */
622     SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
623 
624     /* Check if the I2S is already enabled */
625     if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
626     {
627       /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
628       __HAL_I2SEXT_ENABLE(hi2s);
629 
630       /* Enable I2S peripheral after the I2Sext */
631       __HAL_I2S_ENABLE(hi2s);
632     }
633   }
634   else
635   {
636     /* Check if Master Receiver mode is selected */
637     if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
638     {
639       /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
640       access to the SPI_SR register. */
641       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
642     }
643     /* Enable the Tx DMA Stream */
644     tmp = (uint32_t *)&pTxData;
645     HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t *)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize);
646 
647     /* Enable Tx DMA Request */
648     SET_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_TXDMAEN);
649 
650     /* Enable the Rx DMA Stream */
651     tmp = (uint32_t *)&pRxData;
652     HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t *)tmp, hi2s->RxXferSize);
653 
654     /* Enable Rx DMA Request */
655     SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
656 
657     /* Check if the I2S is already enabled */
658     if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
659     {
660       /* Enable I2Sext(transmitter) before enabling I2Sx peripheral */
661       __HAL_I2SEXT_ENABLE(hi2s);
662       /* Enable I2S peripheral before the I2Sext */
663       __HAL_I2S_ENABLE(hi2s);
664     }
665   }
666 
667 error :
668   __HAL_UNLOCK(hi2s);
669   return errorcode;
670 }
671 
672 /**
673   * @brief  This function handles I2S/I2Sext interrupt requests in full-duplex mode.
674   * @param  hi2s I2S handle
675   * @retval HAL status
676   */
HAL_I2SEx_FullDuplex_IRQHandler(I2S_HandleTypeDef * hi2s)677 void HAL_I2SEx_FullDuplex_IRQHandler(I2S_HandleTypeDef *hi2s)
678 {
679   __IO uint32_t i2ssr     = hi2s->Instance->SR;
680   __IO uint32_t i2sextsr  = I2SxEXT(hi2s->Instance)->SR;
681   __IO uint32_t i2scr2    = hi2s->Instance->CR2;
682   __IO uint32_t i2sextcr2 = I2SxEXT(hi2s->Instance)->CR2;
683 
684   /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
685   if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
686   {
687     /* I2S in mode Transmitter -------------------------------------------------*/
688     if (((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && ((i2scr2 & I2S_IT_TXE) != RESET))
689     {
690       /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX,
691       the I2S TXE interrupt will be generated to manage the full-duplex transmit phase. */
692       I2SEx_TxISR_I2S(hi2s);
693     }
694 
695     /* I2Sext in mode Receiver -----------------------------------------------*/
696     if (((i2sextsr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && ((i2sextcr2 & I2S_IT_RXNE) != RESET))
697     {
698       /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX,
699       the I2Sext RXNE interrupt will be generated to manage the full-duplex receive phase. */
700       I2SEx_RxISR_I2SExt(hi2s);
701     }
702 
703     /* I2Sext Overrun error interrupt occurred --------------------------------*/
704     if (((i2sextsr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && ((i2sextcr2 & I2S_IT_ERR) != RESET))
705     {
706       /* Disable RXNE and ERR interrupt */
707       __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
708 
709       /* Disable TXE and ERR interrupt */
710       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
711 
712       /* Clear Overrun flag */
713       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
714 
715       /* Set the I2S State ready */
716       hi2s->State = HAL_I2S_STATE_READY;
717 
718       /* Set the error code and execute error callback*/
719       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
720       /* Call user error callback */
721 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
722       hi2s->ErrorCallback(hi2s);
723 #else
724       HAL_I2S_ErrorCallback(hi2s);
725 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
726     }
727 
728     /* I2S Underrun error interrupt occurred ----------------------------------*/
729     if (((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && ((i2scr2 & I2S_IT_ERR) != RESET))
730     {
731       /* Disable TXE and ERR interrupt */
732       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
733 
734       /* Disable RXNE and ERR interrupt */
735       __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
736 
737       /* Clear underrun flag */
738       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
739 
740       /* Set the I2S State ready */
741       hi2s->State = HAL_I2S_STATE_READY;
742 
743       /* Set the error code and execute error callback*/
744       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
745       /* Call user error callback */
746 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
747       hi2s->ErrorCallback(hi2s);
748 #else
749       HAL_I2S_ErrorCallback(hi2s);
750 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
751     }
752   }
753   /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
754   else
755   {
756     /* I2Sext in mode Transmitter ----------------------------------------------*/
757     if (((i2sextsr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && ((i2sextcr2 & I2S_IT_TXE) != RESET))
758     {
759       /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX,
760       the I2Sext TXE interrupt will be generated to manage the full-duplex transmit phase. */
761       I2SEx_TxISR_I2SExt(hi2s);
762     }
763 
764     /* I2S in mode Receiver --------------------------------------------------*/
765     if (((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && ((i2scr2 & I2S_IT_RXNE) != RESET))
766     {
767       /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX,
768       the I2S RXNE interrupt will be generated to manage the full-duplex receive phase. */
769       I2SEx_RxISR_I2S(hi2s);
770     }
771 
772     /* I2S Overrun error interrupt occurred -------------------------------------*/
773     if (((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && ((i2scr2 & I2S_IT_ERR) != RESET))
774     {
775       /* Disable RXNE and ERR interrupt */
776       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
777 
778       /* Disable TXE and ERR interrupt */
779       __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
780 
781       /* Set the I2S State ready */
782       hi2s->State = HAL_I2S_STATE_READY;
783 
784       /* Set the error code and execute error callback*/
785       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
786       /* Call user error callback */
787 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
788       hi2s->ErrorCallback(hi2s);
789 #else
790       HAL_I2S_ErrorCallback(hi2s);
791 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
792     }
793 
794     /* I2Sext Underrun error interrupt occurred -------------------------------*/
795     if (((i2sextsr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && ((i2sextcr2 & I2S_IT_ERR) != RESET))
796     {
797       /* Disable TXE and ERR interrupt */
798       __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
799 
800       /* Disable RXNE and ERR interrupt */
801       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
802 
803       /* Set the I2S State ready */
804       hi2s->State = HAL_I2S_STATE_READY;
805 
806       /* Set the error code and execute error callback*/
807       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
808       /* Call user error callback */
809 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
810       hi2s->ErrorCallback(hi2s);
811 #else
812       HAL_I2S_ErrorCallback(hi2s);
813 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
814     }
815   }
816 }
817 
818 /**
819   * @brief  Tx and Rx Transfer half completed callback
820   * @param  hi2s I2S handle
821   * @retval None
822   */
HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef * hi2s)823 __weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
824 {
825   /* Prevent unused argument(s) compilation warning */
826   UNUSED(hi2s);
827 
828   /* NOTE : This function Should not be modified, when the callback is needed,
829             the HAL_I2SEx_TxRxHalfCpltCallback could be implemented in the user file
830    */
831 }
832 
833 /**
834   * @brief  Tx and Rx Transfer completed callback
835   * @param  hi2s I2S handle
836   * @retval None
837   */
HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef * hi2s)838 __weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
839 {
840   /* Prevent unused argument(s) compilation warning */
841   UNUSED(hi2s);
842 
843   /* NOTE : This function should not be modified, when the callback is needed,
844             the HAL_I2SEx_TxRxCpltCallback could be implemented in the user file
845    */
846 }
847 
848 /**
849   * @}
850   */
851 
852 /**
853   * @}
854   */
855 
856 /** @addtogroup I2SEx_Private_Functions I2S Extended Private Functions
857   * @{
858   */
859 
860 /**
861   * @brief  DMA I2S transmit receive process half complete callback
862   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
863   *               the configuration information for the specified DMA module.
864   * @retval None
865   */
I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef * hdma)866 static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma)
867 {
868   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
869 
870   /* Call user TxRx Half complete callback */
871 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
872   hi2s->TxRxHalfCpltCallback(hi2s);
873 #else
874   HAL_I2SEx_TxRxHalfCpltCallback(hi2s);
875 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
876 }
877 
878 /**
879   * @brief  DMA I2S transmit receive process complete callback
880   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
881   *               the configuration information for the specified DMA module.
882   * @retval None
883   */
I2SEx_TxRxDMACplt(DMA_HandleTypeDef * hdma)884 static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma)
885 {
886   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
887 
888   /* If DMA is configured in DMA_NORMAL mode */
889   if (hdma->Init.Mode == DMA_NORMAL)
890   {
891     if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || \
892         ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
893     /* Disable Tx & Rx DMA Requests */
894     {
895       CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_RXDMAEN);
896       CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
897     }
898     else
899     {
900       CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
901       CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_TXDMAEN);
902     }
903 
904     hi2s->RxXferCount = 0U;
905     hi2s->TxXferCount = 0U;
906 
907     hi2s->State = HAL_I2S_STATE_READY;
908   }
909 
910   /* Call user TxRx complete callback */
911 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
912   hi2s->TxRxCpltCallback(hi2s);
913 #else
914   HAL_I2SEx_TxRxCpltCallback(hi2s);
915 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
916 }
917 
918 /**
919   * @brief  DMA I2S communication error callback
920   * @param  hdma DMA handle
921   * @retval None
922   */
I2SEx_TxRxDMAError(DMA_HandleTypeDef * hdma)923 static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma)
924 {
925   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
926 
927   /* Disable Rx and Tx DMA Request */
928   CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
929   CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
930 
931   hi2s->TxXferCount = 0U;
932   hi2s->RxXferCount = 0U;
933 
934   hi2s->State = HAL_I2S_STATE_READY;
935 
936   /* Set the error code and execute error callback*/
937   SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
938   /* Call user error callback */
939 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
940   hi2s->ErrorCallback(hi2s);
941 #else
942   HAL_I2S_ErrorCallback(hi2s);
943 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
944 }
945 
946 /**
947   * @brief  I2S Full-Duplex IT handler transmit function
948   * @param  hi2s I2S handle
949   * @retval None
950   */
I2SEx_TxISR_I2S(I2S_HandleTypeDef * hi2s)951 static void I2SEx_TxISR_I2S(I2S_HandleTypeDef *hi2s)
952 {
953   /* Write Data on DR register */
954   hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
955   hi2s->TxXferCount--;
956 
957   if (hi2s->TxXferCount == 0U)
958   {
959     /* Disable TXE and ERR interrupt */
960     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
961 
962     if (hi2s->RxXferCount == 0U)
963     {
964       hi2s->State = HAL_I2S_STATE_READY;
965       /* Call user TxRx complete callback */
966 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
967       hi2s->TxRxCpltCallback(hi2s);
968 #else
969       HAL_I2SEx_TxRxCpltCallback(hi2s);
970 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
971     }
972   }
973 }
974 
975 /**
976   * @brief  I2SExt Full-Duplex IT handler transmit function
977   * @param  hi2s I2S handle
978   * @retval None
979   */
I2SEx_TxISR_I2SExt(I2S_HandleTypeDef * hi2s)980 static void I2SEx_TxISR_I2SExt(I2S_HandleTypeDef *hi2s)
981 {
982   /* Write Data on DR register */
983   I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
984   hi2s->TxXferCount--;
985 
986   if (hi2s->TxXferCount == 0U)
987   {
988     /* Disable I2Sext TXE and ERR interrupt */
989     __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
990 
991     if (hi2s->RxXferCount == 0U)
992     {
993       hi2s->State = HAL_I2S_STATE_READY;
994       /* Call user TxRx complete callback */
995 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
996       hi2s->TxRxCpltCallback(hi2s);
997 #else
998       HAL_I2SEx_TxRxCpltCallback(hi2s);
999 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1000     }
1001   }
1002 }
1003 
1004 /**
1005   * @brief  I2S Full-Duplex IT handler receive function
1006   * @param  hi2s I2S handle
1007   * @retval None
1008   */
I2SEx_RxISR_I2S(I2S_HandleTypeDef * hi2s)1009 static void I2SEx_RxISR_I2S(I2S_HandleTypeDef *hi2s)
1010 {
1011   /* Read Data from DR register */
1012   (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
1013   hi2s->RxXferCount--;
1014 
1015   if (hi2s->RxXferCount == 0U)
1016   {
1017     /* Disable RXNE and ERR interrupt */
1018     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1019 
1020     if (hi2s->TxXferCount == 0U)
1021     {
1022       hi2s->State = HAL_I2S_STATE_READY;
1023       /* Call user TxRx complete callback */
1024 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1025       hi2s->TxRxCpltCallback(hi2s);
1026 #else
1027       HAL_I2SEx_TxRxCpltCallback(hi2s);
1028 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1029     }
1030   }
1031 }
1032 
1033 /**
1034   * @brief  I2SExt Full-Duplex IT handler receive function
1035   * @param  hi2s I2S handle
1036   * @retval None
1037   */
I2SEx_RxISR_I2SExt(I2S_HandleTypeDef * hi2s)1038 static void I2SEx_RxISR_I2SExt(I2S_HandleTypeDef *hi2s)
1039 {
1040   /* Read Data from DR register */
1041   (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR;
1042   hi2s->RxXferCount--;
1043 
1044   if (hi2s->RxXferCount == 0U)
1045   {
1046     /* Disable I2Sext RXNE and ERR interrupt */
1047     __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1048 
1049     if (hi2s->TxXferCount == 0U)
1050     {
1051       hi2s->State = HAL_I2S_STATE_READY;
1052       /* Call user TxRx complete callback */
1053 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1054       hi2s->TxRxCpltCallback(hi2s);
1055 #else
1056       HAL_I2SEx_TxRxCpltCallback(hi2s);
1057 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1058     }
1059   }
1060 }
1061 
1062 /**
1063   * @brief This function handles I2S Communication Timeout.
1064   * @param hi2s I2S handle
1065   * @param Flag Flag checked
1066   * @param State Value of the flag expected
1067   * @param Timeout Duration of the timeout
1068   * @param i2sUsed I2S instance reference
1069   * @retval HAL status
1070   */
I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,uint32_t State,uint32_t Timeout,I2S_UseTypeDef i2sUsed)1071 static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s,
1072                                                                    uint32_t Flag,
1073                                                                    uint32_t State,
1074                                                                    uint32_t Timeout,
1075                                                                    I2S_UseTypeDef i2sUsed)
1076 {
1077   uint32_t tickstart = HAL_GetTick();
1078 
1079   if (i2sUsed == I2S_USE_I2S)
1080   {
1081     /* Wait until flag is reset */
1082     while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1083     {
1084       if (Timeout != HAL_MAX_DELAY)
1085       {
1086         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1087         {
1088           /* Set the I2S State ready */
1089           hi2s->State = HAL_I2S_STATE_READY;
1090 
1091           /* Process Unlocked */
1092           __HAL_UNLOCK(hi2s);
1093 
1094           return HAL_TIMEOUT;
1095         }
1096       }
1097     }
1098   }
1099   else /* i2sUsed == I2S_USE_I2SEXT */
1100   {
1101     /* Wait until flag is reset */
1102     while (((__HAL_I2SEXT_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1103     {
1104       if (Timeout != HAL_MAX_DELAY)
1105       {
1106         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1107         {
1108           /* Set the I2S State ready */
1109           hi2s->State = HAL_I2S_STATE_READY;
1110 
1111           /* Process Unlocked */
1112           __HAL_UNLOCK(hi2s);
1113 
1114           return HAL_TIMEOUT;
1115         }
1116       }
1117     }
1118   }
1119   return HAL_OK;
1120 }
1121 
1122 /**
1123   * @}
1124   */
1125 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
1126 
1127 /**
1128   * @}
1129   */
1130 #endif /* HAL_I2S_MODULE_ENABLED */
1131 
1132 /**
1133   * @}
1134   */
1135 
1136