1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_i2s.c
4   * @author  MCD Application Team
5   * @brief   I2S HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Integrated Interchip Sound (I2S) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral State and Errors functions
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2017 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23  ===============================================================================
24                   ##### How to use this driver #####
25  ===============================================================================
26  [..]
27     The I2S HAL driver can be used as follow:
28 
29     (#) Declare a I2S_HandleTypeDef handle structure.
30     (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
31         (##) Enable the SPIx interface clock.
32         (##) I2S pins configuration:
33             (+++) Enable the clock for the I2S GPIOs.
34             (+++) Configure these I2S pins as alternate function pull-up.
35         (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
36              and HAL_I2S_Receive_IT() APIs).
37             (+++) Configure the I2Sx interrupt priority.
38             (+++) Enable the NVIC I2S IRQ handle.
39         (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
40              and HAL_I2S_Receive_DMA() APIs:
41             (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel.
42             (+++) Enable the DMAx interface clock.
43             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
44             (+++) Configure the DMA Tx/Rx Stream/Channel.
45             (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
46             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
47                   DMA Tx/Rx Stream/Channel.
48 
49    (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
50        using HAL_I2S_Init() function.
51 
52    -@- The specific I2S interrupts (Transmission complete interrupt,
53        RXNE interrupt and Error Interrupts) will be managed using the macros
54        __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
55 
56         (+@) External clock source is configured after setting correctly
57              the define constant EXTERNAL_CLOCK_VALUE in the stm32h7xx_hal_conf.h file.
58 
59     (#) Three mode of operations are available within this driver :
60 
61    *** Polling mode IO operation ***
62    =================================
63    [..]
64      (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
65      (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
66 
67    *** Interrupt mode IO operation ***
68    ===================================
69    [..]
70      (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
71      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
72          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
73      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
74          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
75      (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
76      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
77          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
78      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
79          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
80      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
81          add his own code by customization of function pointer HAL_I2S_ErrorCallback
82 
83    *** DMA mode IO operation ***
84    ==============================
85    [..]
86      (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
87      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
88          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
89      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
90          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
91      (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
92      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
93          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
94      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
95          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
96      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
97          add his own code by customization of function pointer HAL_I2S_ErrorCallback
98      (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
99      (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
100      (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
101 
102    *** I2S HAL driver macros list ***
103    ===================================
104    [..]
105      Below the list of most used macros in I2S HAL driver.
106 
107       (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
108       (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
109       (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
110       (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
111       (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
112 
113     [..]
114       (@) You can refer to the I2S HAL driver header file for more useful macros
115 
116    *** I2S HAL driver macros list ***
117    ===================================
118    [..]
119        Callback registration:
120 
121       (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1UL
122           allows the user to configure dynamically the driver callbacks.
123           Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
124 
125           Function HAL_I2S_RegisterCallback() allows to register following callbacks:
126             (+) TxCpltCallback        : I2S Tx Completed callback
127             (+) RxCpltCallback        : I2S Rx Completed callback
128             (+) TxRxCpltCallback      : I2S TxRx Completed callback
129             (+) TxHalfCpltCallback    : I2S Tx Half Completed callback
130             (+) RxHalfCpltCallback    : I2S Rx Half Completed callback
131             (+) TxRxHalfCpltCallback  : I2S TxRx Half Completed callback
132             (+) ErrorCallback         : I2S Error callback
133             (+) MspInitCallback       : I2S Msp Init callback
134             (+) MspDeInitCallback     : I2S Msp DeInit callback
135           This function takes as parameters the HAL peripheral handle, the Callback ID
136           and a pointer to the user callback function.
137 
138 
139       (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default
140           weak function.
141           HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
142           and the Callback ID.
143           This function allows to reset following callbacks:
144             (+) TxCpltCallback        : I2S Tx Completed callback
145             (+) RxCpltCallback        : I2S Rx Completed callback
146             (+) TxRxCpltCallback      : I2S TxRx Completed callback
147             (+) TxHalfCpltCallback    : I2S Tx Half Completed callback
148             (+) RxHalfCpltCallback    : I2S Rx Half Completed callback
149             (+) TxRxHalfCpltCallback  : I2S TxRx Half Completed callback
150             (+) ErrorCallback         : I2S Error callback
151             (+) MspInitCallback       : I2S Msp Init callback
152             (+) MspDeInitCallback     : I2S Msp DeInit callback
153 
154        By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
155        all callbacks are set to the corresponding weak functions:
156        examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
157        Exception done for MspInit and MspDeInit functions that are
158        reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
159        these callbacks are null (not registered beforehand).
160        If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
161        keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
162 
163        Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
164        Exception done MspInit/MspDeInit functions that can be registered/unregistered
165        in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state,
166        thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
167        Then, the user first registers the MspInit/MspDeInit user callbacks
168        using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
169        or HAL_I2S_Init() function.
170 
171        When The compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
172        not defined, the callback registering feature is not available
173        and weak callbacks are used.
174 
175 
176   @endverbatim
177   */
178 
179 /* Includes ------------------------------------------------------------------*/
180 #include "stm32h7xx_hal.h"
181 
182 #ifdef HAL_I2S_MODULE_ENABLED
183 
184 /** @addtogroup STM32H7xx_HAL_Driver
185   * @{
186   */
187 
188 /** @defgroup I2S I2S
189   * @brief I2S HAL module driver
190   * @{
191   */
192 
193 /* Private typedef -----------------------------------------------------------*/
194 /* Private define ------------------------------------------------------------*/
195 /** @defgroup I2S_Private_Define I2S Private Define
196   * @{
197   */
198 #define I2S_TIMEOUT 0xFFFFUL
199 /**
200   * @}
201   */
202 
203 /* Private macro -------------------------------------------------------------*/
204 /* Private variables ---------------------------------------------------------*/
205 /* Private function prototypes -----------------------------------------------*/
206 /** @defgroup I2S_Private_Functions I2S Private Functions
207   * @{
208   */
209 static void               I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
210 static void               I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
211 static void               I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
212 static void               I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
213 static void               I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma);
214 static void               I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma);
215 static void               I2S_DMAError(DMA_HandleTypeDef *hdma);
216 static void               I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s);
217 static void               I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s);
218 static void               I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s);
219 static void               I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s);
220 static HAL_StatusTypeDef  I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
221                                                         uint32_t Tickstart, uint32_t Timeout);
222 /**
223   * @}
224   */
225 
226 /* Exported functions ---------------------------------------------------------*/
227 
228 /** @defgroup I2S_Exported_Functions I2S Exported Functions
229   * @{
230   */
231 
232 /** @defgroup  I2S_Exported_Functions_Group1 Initialization and de-initialization functions
233   *  @brief    Initialization and Configuration functions
234   *
235 @verbatim
236  ===============================================================================
237               ##### Initialization and de-initialization functions #####
238  ===============================================================================
239     [..]  This subsection provides a set of functions allowing to initialize and
240           de-initialize the I2Sx peripheral in simplex mode:
241 
242       (+) User must Implement HAL_I2S_MspInit() function in which he configures
243           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
244 
245       (+) Call the function HAL_I2S_Init() to configure the selected device with
246           the selected configuration:
247         (++) Mode
248         (++) Standard
249         (++) Data Format
250         (++) MCLK Output
251         (++) Audio frequency
252         (++) Polarity
253 
254      (+) Call the function HAL_I2S_DeInit() to restore the default configuration
255           of the selected I2Sx peripheral.
256   @endverbatim
257   * @{
258   */
259 
260 /**
261   * @brief  Initializes the I2S according to the specified parameters
262   *         in the I2S_InitTypeDef and create the associated handle.
263   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
264   *         the configuration information for I2S module
265   * @retval HAL status
266   */
HAL_I2S_Init(I2S_HandleTypeDef * hi2s)267 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
268 {
269   uint32_t i2sdiv;
270   uint32_t i2sodd;
271   uint32_t packetlength;
272   uint32_t tmp;
273   uint32_t i2sclk;
274   uint32_t ispcm;
275 
276   /* Check the I2S handle allocation */
277   if (hi2s == NULL)
278   {
279     return HAL_ERROR;
280   }
281 
282   /* Check the I2S parameters */
283   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
284   assert_param(IS_I2S_MODE(hi2s->Init.Mode));
285   assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
286   assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
287   assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
288   assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
289   assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
290   assert_param(IS_I2S_FIRST_BIT(hi2s->Init.FirstBit));
291   assert_param(IS_I2S_WS_INVERSION(hi2s->Init.WSInversion));
292   assert_param(IS_I2S_DATA_24BIT_ALIGNMENT(hi2s->Init.Data24BitAlignment));
293   assert_param(IS_I2S_MASTER_KEEP_IO_STATE(hi2s->Init.MasterKeepIOState));
294 
295   if (hi2s->State == HAL_I2S_STATE_RESET)
296   {
297     /* Allocate lock resource and initialize it */
298     hi2s->Lock = HAL_UNLOCKED;
299 
300 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
301     /* Init the I2S Callback settings */
302     hi2s->TxCpltCallback       = HAL_I2S_TxCpltCallback;          /* Legacy weak TxCpltCallback       */
303     hi2s->RxCpltCallback       = HAL_I2S_RxCpltCallback;          /* Legacy weak RxCpltCallback       */
304     hi2s->TxRxCpltCallback     = HAL_I2SEx_TxRxCpltCallback;      /* Legacy weak TxRxCpltCallback     */
305     hi2s->TxHalfCpltCallback   = HAL_I2S_TxHalfCpltCallback;      /* Legacy weak TxHalfCpltCallback   */
306     hi2s->RxHalfCpltCallback   = HAL_I2S_RxHalfCpltCallback;      /* Legacy weak RxHalfCpltCallback   */
307     hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback;  /* Legacy weak TxRxHalfCpltCallback */
308     hi2s->ErrorCallback        = HAL_I2S_ErrorCallback;           /* Legacy weak ErrorCallback        */
309 
310     if (hi2s->MspInitCallback == NULL)
311     {
312       hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit  */
313     }
314 
315     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
316     hi2s->MspInitCallback(hi2s);
317 #else
318     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
319     HAL_I2S_MspInit(hi2s);
320 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
321   }
322 
323   hi2s->State = HAL_I2S_STATE_BUSY;
324 
325   /* Disable the selected I2S peripheral */
326   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE)
327   {
328     /* Disable I2S peripheral */
329     __HAL_I2S_DISABLE(hi2s);
330   }
331 
332   /* Clear I2S configuration register */
333   CLEAR_REG(hi2s->Instance->I2SCFGR);
334 
335   if (IS_I2S_MASTER(hi2s->Init.Mode))
336   {
337     /*------------------------- I2SDIV and ODD Calculation ---------------------*/
338     /* If the requested audio frequency is not the default, compute the prescaler */
339     if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
340     {
341       /* Check the frame length (For the Prescaler computing) ********************/
342       if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
343       {
344         /* Channel length is 32 bits */
345         packetlength = 2UL;
346       }
347       else
348       {
349         /* Channel length is 16 bits */
350         packetlength = 1UL;
351       }
352 
353       /* Check if PCM standard is used */
354       if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) ||
355           (hi2s->Init.Standard == I2S_STANDARD_PCM_LONG))
356       {
357         ispcm = 1UL;
358       }
359       else
360       {
361         ispcm = 0UL;
362       }
363 
364       /* Get the source clock value: based on System Clock value */
365 #if defined (SPI_SPI6I2S_SUPPORT)
366       if (hi2s->Instance == SPI6)
367       {
368         /* SPI6 source clock */
369         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI6);
370       }
371       else
372       {
373         /* SPI1,SPI2 and SPI3 share the same source clock */
374         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI123);
375       }
376 #else
377       /* SPI1,SPI2 and SPI3 share the same source clock */
378       i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI123);
379 #endif  /* SPI_SPI6I2S_SUPPORT */
380 
381       /* Compute the Real divider depending on the MCLK output state, with a floating point */
382       if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
383       {
384         /* MCLK output is enabled */
385         tmp = (uint32_t)((((i2sclk / (256UL >> ispcm)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
386       }
387       else
388       {
389         /* MCLK output is disabled */
390         tmp = (uint32_t)((((i2sclk / ((32UL >> ispcm) * packetlength)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
391       }
392 
393       /* Remove the flatting point */
394       tmp = tmp / 10UL;
395 
396       /* Check the parity of the divider */
397       i2sodd = (uint32_t)(tmp & (uint32_t)1UL);
398 
399       /* Compute the i2sdiv prescaler */
400       i2sdiv = (uint32_t)((tmp - i2sodd) / 2UL);
401     }
402     else
403     {
404       /* Set the default values */
405       i2sdiv = 2UL;
406       i2sodd = 0UL;
407     }
408 
409     /* Test if the obtain values are forbidden or out of range */
410     if (((i2sodd == 1UL) && (i2sdiv == 1UL)) || (i2sdiv > 0xFFUL))
411     {
412       /* Set the error code */
413       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
414       return  HAL_ERROR;
415     }
416 
417     /* Force i2smod to 1 just to be sure that (2xi2sdiv + i2sodd) is always higher than 0 */
418     if (i2sdiv == 0UL)
419     {
420       i2sodd = 1UL;
421     }
422 
423     MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SDIV                 | SPI_I2SCFGR_ODD),
424                ((i2sdiv << SPI_I2SCFGR_I2SDIV_Pos) | (i2sodd << SPI_I2SCFGR_ODD_Pos)));
425   }
426 
427   /*-------------------------- I2Sx I2SCFGR Configuration --------------------*/
428   /* Configure I2SMOD, I2SCFG, I2SSTD, PCMSYNC, DATLEN ,CHLEN ,CKPOL, WSINV, DATAFMT, I2SDIV, ODD and MCKOE bits bits */
429   /* And configure the I2S with the I2S_InitStruct values */
430   MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SMOD   | SPI_I2SCFGR_I2SCFG     | \
431                                        SPI_I2SCFGR_I2SSTD   | SPI_I2SCFGR_PCMSYNC    | \
432                                        SPI_I2SCFGR_DATLEN   | SPI_I2SCFGR_CHLEN      | \
433                                        SPI_I2SCFGR_CKPOL    | SPI_I2SCFGR_WSINV      | \
434                                        SPI_I2SCFGR_DATFMT   | SPI_I2SCFGR_MCKOE),
435              (SPI_I2SCFGR_I2SMOD   | hi2s->Init.Mode        | \
436               hi2s->Init.Standard  | hi2s->Init.DataFormat  | \
437               hi2s->Init.CPOL      | hi2s->Init.WSInversion | \
438               hi2s->Init.Data24BitAlignment | hi2s->Init.MCLKOutput));
439   /*Clear status register*/
440   WRITE_REG(hi2s->Instance->IFCR, 0x0FF8);
441 
442   /*---------------------------- I2Sx CFG2 Configuration ----------------------*/
443 
444   /* Unlock the AF configuration to configure CFG2 register*/
445   CLEAR_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK);
446 
447   MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_LSBFRST, hi2s->Init.FirstBit);
448 
449   /* Insure that AFCNTR is managed only by Master */
450   if (IS_I2S_MASTER(hi2s->Init.Mode))
451   {
452     /* Alternate function GPIOs control */
453     MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_AFCNTR, (hi2s->Init.MasterKeepIOState));
454   }
455 
456   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
457   hi2s->State     = HAL_I2S_STATE_READY;
458 
459   return HAL_OK;
460 }
461 
462 /**
463   * @brief DeInitializes the I2S peripheral
464   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
465   *         the configuration information for I2S module
466   * @retval HAL status
467   */
HAL_I2S_DeInit(I2S_HandleTypeDef * hi2s)468 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
469 {
470   /* Check the I2S handle allocation */
471   if (hi2s == NULL)
472   {
473     return HAL_ERROR;
474   }
475 
476   /* Check the parameters */
477   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
478 
479   hi2s->State = HAL_I2S_STATE_BUSY;
480 
481   /* Disable the I2S Peripheral Clock */
482   __HAL_I2S_DISABLE(hi2s);
483 
484 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
485   if (hi2s->MspDeInitCallback == NULL)
486   {
487     hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit  */
488   }
489 
490   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
491   hi2s->MspDeInitCallback(hi2s);
492 #else
493   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
494   HAL_I2S_MspDeInit(hi2s);
495 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
496 
497   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
498   hi2s->State     = HAL_I2S_STATE_RESET;
499 
500   /* Release Lock */
501   __HAL_UNLOCK(hi2s);
502 
503   return HAL_OK;
504 }
505 
506 /**
507   * @brief I2S MSP Init
508   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
509   *         the configuration information for I2S module
510   * @retval None
511   */
HAL_I2S_MspInit(I2S_HandleTypeDef * hi2s)512 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
513 {
514   /* Prevent unused argument(s) compilation warning */
515   UNUSED(hi2s);
516 
517   /* NOTE : This function Should not be modified, when the callback is needed,
518             the HAL_I2S_MspInit could be implemented in the user file
519    */
520 }
521 
522 /**
523   * @brief I2S MSP DeInit
524   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
525   *         the configuration information for I2S module
526   * @retval None
527   */
HAL_I2S_MspDeInit(I2S_HandleTypeDef * hi2s)528 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
529 {
530   /* Prevent unused argument(s) compilation warning */
531   UNUSED(hi2s);
532 
533   /* NOTE : This function Should not be modified, when the callback is needed,
534             the HAL_I2S_MspDeInit could be implemented in the user file
535    */
536 }
537 
538 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
539 /**
540   * @brief  Register a User I2S Callback
541   *         To be used instead of the weak predefined callback
542   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
543   *                the configuration information for the specified I2S.
544   * @param  CallbackID ID of the callback to be registered
545   * @param  pCallback pointer to the Callback function
546   * @note   The HAL_I2S_RegisterCallback() may be called before HAL_I2S_Init() in HAL_I2S_STATE_RESET
547   *         to register callbacks for HAL_I2S_MSPINIT_CB_ID and HAL_I2S_MSPDEINIT_CB_ID
548   * @retval HAL status
549   */
HAL_I2S_RegisterCallback(I2S_HandleTypeDef * hi2s,HAL_I2S_CallbackIDTypeDef CallbackID,pI2S_CallbackTypeDef pCallback)550 HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID,
551                                            pI2S_CallbackTypeDef pCallback)
552 {
553   HAL_StatusTypeDef status = HAL_OK;
554 
555   if (pCallback == NULL)
556   {
557     /* Update the error code */
558     hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
559 
560     return HAL_ERROR;
561   }
562 
563   if (HAL_I2S_STATE_READY == hi2s->State)
564   {
565     switch (CallbackID)
566     {
567       case HAL_I2S_TX_COMPLETE_CB_ID :
568         hi2s->TxCpltCallback = pCallback;
569         break;
570 
571       case HAL_I2S_RX_COMPLETE_CB_ID :
572         hi2s->RxCpltCallback = pCallback;
573         break;
574 
575       case HAL_I2S_TX_RX_COMPLETE_CB_ID :
576         hi2s->TxRxCpltCallback = pCallback;
577         break;
578 
579       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
580         hi2s->TxHalfCpltCallback = pCallback;
581         break;
582 
583       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
584         hi2s->RxHalfCpltCallback = pCallback;
585         break;
586 
587 
588       case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
589         hi2s->TxRxHalfCpltCallback = pCallback;
590         break;
591 
592       case HAL_I2S_ERROR_CB_ID :
593         hi2s->ErrorCallback = pCallback;
594         break;
595 
596       case HAL_I2S_MSPINIT_CB_ID :
597         hi2s->MspInitCallback = pCallback;
598         break;
599 
600       case HAL_I2S_MSPDEINIT_CB_ID :
601         hi2s->MspDeInitCallback = pCallback;
602         break;
603 
604       default :
605         /* Update the error code */
606         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
607 
608         /* Return error status */
609         status =  HAL_ERROR;
610         break;
611     }
612   }
613   else if (HAL_I2S_STATE_RESET == hi2s->State)
614   {
615     switch (CallbackID)
616     {
617       case HAL_I2S_MSPINIT_CB_ID :
618         hi2s->MspInitCallback = pCallback;
619         break;
620 
621       case HAL_I2S_MSPDEINIT_CB_ID :
622         hi2s->MspDeInitCallback = pCallback;
623         break;
624 
625       default :
626         /* Update the error code */
627         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
628 
629         /* Return error status */
630         status =  HAL_ERROR;
631         break;
632     }
633   }
634   else
635   {
636     /* Update the error code */
637     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
638 
639     /* Return error status */
640     status =  HAL_ERROR;
641   }
642 
643   return status;
644 }
645 
646 /**
647   * @brief  Unregister an I2S Callback
648   *         I2S callback is redirected to the weak predefined callback
649   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
650   *                the configuration information for the specified I2S.
651   * @param  CallbackID ID of the callback to be unregistered
652   * @note   The HAL_I2S_UnRegisterCallback() may be called before HAL_I2S_Init() in HAL_I2S_STATE_RESET
653   *         to un-register callbacks for HAL_I2S_MSPINIT_CB_ID and HAL_I2S_MSPDEINIT_CB_ID
654   * @retval HAL status
655   */
HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef * hi2s,HAL_I2S_CallbackIDTypeDef CallbackID)656 HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
657 {
658   HAL_StatusTypeDef status = HAL_OK;
659 
660   if (HAL_I2S_STATE_READY == hi2s->State)
661   {
662     switch (CallbackID)
663     {
664       case HAL_I2S_TX_COMPLETE_CB_ID :
665         hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback;                /* Legacy weak TxCpltCallback       */
666         break;
667 
668       case HAL_I2S_RX_COMPLETE_CB_ID :
669         hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback;                /* Legacy weak RxCpltCallback       */
670         break;
671 
672       case HAL_I2S_TX_RX_COMPLETE_CB_ID :
673         hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback;          /* Legacy weak TxRxCpltCallback     */
674         break;
675 
676       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
677         hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback   */
678         break;
679 
680       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
681         hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback   */
682         break;
683 
684       case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
685         hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback;  /* Legacy weak TxRxHalfCpltCallback */
686         break;
687 
688       case HAL_I2S_ERROR_CB_ID :
689         hi2s->ErrorCallback = HAL_I2S_ErrorCallback;                  /* Legacy weak ErrorCallback        */
690         break;
691 
692       case HAL_I2S_MSPINIT_CB_ID :
693         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
694         break;
695 
696       case HAL_I2S_MSPDEINIT_CB_ID :
697         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
698         break;
699 
700       default :
701         /* Update the error code */
702         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
703 
704         /* Return error status */
705         status =  HAL_ERROR;
706         break;
707     }
708   }
709   else if (HAL_I2S_STATE_RESET == hi2s->State)
710   {
711     switch (CallbackID)
712     {
713       case HAL_I2S_MSPINIT_CB_ID :
714         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
715         break;
716 
717       case HAL_I2S_MSPDEINIT_CB_ID :
718         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
719         break;
720 
721       default :
722         /* Update the error code */
723         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
724 
725         /* Return error status */
726         status =  HAL_ERROR;
727         break;
728     }
729   }
730   else
731   {
732     /* Update the error code */
733     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
734 
735     /* Return error status */
736     status =  HAL_ERROR;
737   }
738 
739   return status;
740 }
741 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
742 /**
743   * @}
744   */
745 
746 /** @defgroup I2S_Exported_Functions_Group2 IO operation functions
747   *  @brief Data transfers functions
748   *
749 @verbatim
750  ===============================================================================
751                       ##### IO operation functions #####
752  ===============================================================================
753     [..]
754     This subsection provides a set of functions allowing to manage the I2S data
755     transfers.
756 
757     (#) There are two modes of transfer:
758        (++) Blocking mode : The communication is performed in the polling mode.
759             The status of all data processing is returned by the same function
760             after finishing transfer.
761        (++) No-Blocking mode : The communication is performed using Interrupts
762             or DMA. These functions return the status of the transfer startup.
763             The end of the data processing will be indicated through the
764             dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
765             using DMA mode.
766 
767     (#) Blocking mode functions are :
768         (++) HAL_I2S_Transmit()
769         (++) HAL_I2S_Receive()
770         (++) HAL_I2SEx_TransmitReceive()
771 
772     (#) No-Blocking mode functions with Interrupt are :
773         (++) HAL_I2S_Transmit_IT()
774         (++) HAL_I2S_Receive_IT()
775         (++) HAL_I2SEx_TransmitReceive_IT()
776 
777     (#) No-Blocking mode functions with DMA are :
778         (++) HAL_I2S_Transmit_DMA()
779         (++) HAL_I2S_Receive_DMA()
780         (++) HAL_I2SEx_TransmitReceive_DMA()
781 
782     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
783         (++) HAL_I2S_TxCpltCallback()
784         (++) HAL_I2S_RxCpltCallback()
785         (++) HAL_I2SEx_TxRxCpltCallback()
786         (++) HAL_I2S_ErrorCallback()
787 
788 @endverbatim
789   * @{
790   */
791 
792 /**
793   * @brief  Transmit an amount of data in blocking mode
794   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
795   *         the configuration information for I2S module
796   * @param  pData a 16-bit pointer to data buffer.
797   * @param  Size number of data sample to be sent:
798   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
799   *         configuration phase, the Size parameter means the number of 16-bit data length
800   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
801   *         the Size parameter means the number of 16-bit data length.
802   * @param  Timeout Timeout duration
803   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
804   *         between Master and Slave(example: audio streaming).
805   * @retval HAL status
806   */
HAL_I2S_Transmit(I2S_HandleTypeDef * hi2s,const uint16_t * pData,uint16_t Size,uint32_t Timeout)807 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size, uint32_t Timeout)
808 {
809 #if defined (__GNUC__)
810   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
811 #endif /* __GNUC__ */
812   uint32_t tickstart;
813 
814   if ((pData == NULL) || (Size == 0UL))
815   {
816     return  HAL_ERROR;
817   }
818 
819   if (hi2s->State != HAL_I2S_STATE_READY)
820   {
821     return HAL_BUSY;
822   }
823 
824   /* Process Locked */
825   __HAL_LOCK(hi2s);
826 
827   /* Init tickstart for timeout management*/
828   tickstart = HAL_GetTick();
829 
830   /* Set state and reset error code */
831   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
832   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
833   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
834   hi2s->TxXferSize  = Size;
835   hi2s->TxXferCount = Size;
836 
837   /* Initialize fields not used in handle to zero */
838   hi2s->pRxBuffPtr  = NULL;
839   hi2s->RxXferSize  = (uint16_t) 0UL;
840   hi2s->RxXferCount = (uint16_t) 0UL;
841 
842   /* Check if the I2S is already enabled */
843   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
844   {
845     /* Enable I2S peripheral */
846     __HAL_I2S_ENABLE(hi2s);
847   }
848 
849   /* Start the transfer */
850   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
851 
852 
853   /* Wait until TXP flag is set */
854   if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, tickstart, Timeout) != HAL_OK)
855   {
856     /* Set the error code */
857     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
858     hi2s->State = HAL_I2S_STATE_READY;
859     __HAL_UNLOCK(hi2s);
860     return HAL_TIMEOUT;
861   }
862 
863   while (hi2s->TxXferCount > 0UL)
864   {
865     if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
866     {
867       /* Transmit data in 32 Bit mode */
868       hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
869       hi2s->pTxBuffPtr += 2;
870       hi2s->TxXferCount--;
871     }
872     else
873     {
874       /* Transmit data in 16 Bit mode */
875 #if defined (__GNUC__)
876       *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
877 #else
878       *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
879 #endif /* __GNUC__ */
880 
881       hi2s->pTxBuffPtr++;
882       hi2s->TxXferCount--;
883     }
884 
885     /* Wait until TXP flag is set */
886     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, tickstart, Timeout) != HAL_OK)
887     {
888       /* Set the error code */
889       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
890       hi2s->State = HAL_I2S_STATE_READY;
891       __HAL_UNLOCK(hi2s);
892       return HAL_TIMEOUT;
893     }
894 
895     /* Check if an underrun occurs */
896     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
897     {
898       /* Clear underrun flag */
899       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
900 
901       /* Set the error code */
902       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
903     }
904   }
905 
906   hi2s->State = HAL_I2S_STATE_READY;
907   __HAL_UNLOCK(hi2s);
908   return HAL_OK;
909 }
910 
911 /**
912   * @brief  Receive an amount of data in blocking mode
913   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
914   *         the configuration information for I2S module
915   * @param  pData a 16-bit pointer to data buffer.
916   * @param  Size number of data sample to be sent:
917   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
918   *         configuration phase, the Size parameter means the number of 16-bit data length
919   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
920   *         the Size parameter means the number of 16-bit data length.
921   * @param  Timeout Timeout duration
922   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
923   *         between Master and Slave(example: audio streaming).
924   * @note   In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
925   *         in continuous way and as the I2S is not disabled at the end of the I2S transaction.
926   * @retval HAL status
927   */
HAL_I2S_Receive(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)928 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
929 {
930 #if defined (__GNUC__)
931   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
932 #endif /* __GNUC__ */
933   uint32_t tickstart;
934 
935   if ((pData == NULL) || (Size == 0UL))
936   {
937     return  HAL_ERROR;
938   }
939 
940   if (hi2s->State != HAL_I2S_STATE_READY)
941   {
942     return HAL_BUSY;
943   }
944 
945   /* Process Locked */
946   __HAL_LOCK(hi2s);
947 
948   /* Init tickstart for timeout management*/
949   tickstart = HAL_GetTick();
950 
951   /* Set state and reset error code */
952   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
953   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
954   hi2s->pRxBuffPtr  = pData;
955   hi2s->RxXferSize  = Size;
956   hi2s->RxXferCount = Size;
957 
958   /* Initialize fields not used in handle to zero */
959   hi2s->pTxBuffPtr  = NULL;
960   hi2s->TxXferSize  = (uint16_t) 0UL;
961   hi2s->TxXferCount = (uint16_t) 0UL;
962 
963   /* Check if the I2S is already enabled */
964   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
965   {
966     /* Enable I2S peripheral */
967     __HAL_I2S_ENABLE(hi2s);
968   }
969 
970   /* Start the transfer */
971   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
972 
973   /* Receive data */
974   while (hi2s->RxXferCount > 0UL)
975   {
976     /* Wait until RXP flag is set */
977     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXP, SET, tickstart, Timeout) != HAL_OK)
978     {
979       /* Set the error code */
980       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
981       hi2s->State = HAL_I2S_STATE_READY;
982       __HAL_UNLOCK(hi2s);
983       return HAL_TIMEOUT;
984     }
985 
986     if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
987     {
988       /* Receive data in 32 Bit mode */
989       *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
990       hi2s->pRxBuffPtr += 2;
991       hi2s->RxXferCount--;
992     }
993     else
994     {
995       /* Receive data in 16 Bit mode */
996 #if defined (__GNUC__)
997       *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
998 #else
999       *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
1000 #endif /* __GNUC__ */
1001       hi2s->pRxBuffPtr++;
1002       hi2s->RxXferCount--;
1003     }
1004 
1005     /* Check if an overrun occurs */
1006     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
1007     {
1008       /* Clear overrun flag */
1009       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1010 
1011       /* Set the error code */
1012       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1013     }
1014   }
1015 
1016   hi2s->State = HAL_I2S_STATE_READY;
1017   __HAL_UNLOCK(hi2s);
1018   return HAL_OK;
1019 }
1020 
1021 /**
1022   * @brief  Full-Duplex Transmit/Receive data in blocking mode.
1023   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1024   *         the configuration information for I2S module
1025   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1026   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1027   * @param  Size number of data sample to be sent:
1028   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1029   *         configuration phase, the Size parameter means the number of 16-bit data length
1030   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1031   *         the Size parameter means the number of 16-bit data length.
1032   * @param  Timeout Timeout duration
1033   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1034   *         between Master and Slave(example: audio streaming).
1035   * @retval HAL status
1036   */
1037 
HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef * hi2s,const uint16_t * pTxData,uint16_t * pRxData,uint16_t Size,uint32_t Timeout)1038 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1039                                             uint16_t Size, uint32_t Timeout)
1040 {
1041   uint32_t tmp_TxXferCount;
1042   uint32_t tmp_RxXferCount;
1043   uint32_t tickstart;
1044 
1045 #if defined (__GNUC__)
1046   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
1047   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
1048 #endif /* __GNUC__ */
1049 
1050   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1051   {
1052     return  HAL_ERROR;
1053   }
1054 
1055   if (hi2s->State != HAL_I2S_STATE_READY)
1056   {
1057     return HAL_BUSY;
1058   }
1059 
1060   /* Process Locked */
1061   __HAL_LOCK(hi2s);
1062 
1063   /* Init tickstart for timeout management*/
1064   tickstart = HAL_GetTick();
1065 
1066   hi2s->TxXferSize  = Size;
1067   hi2s->TxXferCount = Size;
1068   hi2s->pTxBuffPtr  = (const uint16_t *)pTxData;
1069   hi2s->RxXferSize  = Size;
1070   hi2s->RxXferCount = Size;
1071   hi2s->pRxBuffPtr  = pRxData;
1072 
1073   tmp_TxXferCount = hi2s->TxXferCount;
1074   tmp_RxXferCount = hi2s->RxXferCount;
1075 
1076   /* Set state and reset error code */
1077   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1078   hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
1079 
1080   /* Check if the I2S is already enabled */
1081   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1082   {
1083     /* Enable I2S peripheral */
1084     __HAL_I2S_ENABLE(hi2s);
1085   }
1086 
1087   /* Start the transfer */
1088   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1089 
1090   while ((tmp_TxXferCount > 0UL) || (tmp_RxXferCount > 0UL))
1091   {
1092     if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXP) == SET) && (tmp_TxXferCount != 0UL))
1093     {
1094       if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1095       {
1096         /* Transmit data in 32 Bit mode */
1097         hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
1098         hi2s->pTxBuffPtr += 2;
1099         tmp_TxXferCount--;
1100       }
1101       else
1102       {
1103         /* Transmit data in 16 Bit mode */
1104 #if defined (__GNUC__)
1105         *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
1106 #else
1107         *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
1108 #endif /* __GNUC__ */
1109 
1110         hi2s->pTxBuffPtr++;
1111         tmp_TxXferCount--;
1112       }
1113 
1114       /* Check if an underrun occurs */
1115       if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
1116       {
1117         /* Clear underrun flag */
1118         __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1119 
1120         /* Set the error code */
1121         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1122       }
1123     }
1124 
1125     if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXP) == SET) && (tmp_RxXferCount != 0UL))
1126     {
1127       if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1128       {
1129         /* Receive data in 32 Bit mode */
1130         *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
1131         hi2s->pRxBuffPtr += 2;
1132         tmp_RxXferCount--;
1133       }
1134       else
1135       {
1136         /* Receive data in 16 Bit mode */
1137 #if defined (__GNUC__)
1138         *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
1139 #else
1140         *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
1141 #endif /* __GNUC__ */
1142         hi2s->pRxBuffPtr++;
1143         tmp_RxXferCount--;
1144       }
1145 
1146       /* Check if an overrun occurs */
1147       if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
1148       {
1149         /* Clear overrun flag */
1150         __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1151 
1152         /* Set the error code */
1153         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1154       }
1155     }
1156 
1157     /* Timeout management */
1158     if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1159     {
1160       /* Set the error code */
1161       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1162       hi2s->State = HAL_I2S_STATE_READY;
1163       __HAL_UNLOCK(hi2s);
1164       return HAL_TIMEOUT;
1165     }
1166   }
1167 
1168   hi2s->State = HAL_I2S_STATE_READY;
1169   __HAL_UNLOCK(hi2s);
1170   return HAL_OK;
1171 }
1172 
1173 /**
1174   * @brief  Transmit an amount of data in non-blocking mode with Interrupt
1175   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1176   *         the configuration information for I2S module
1177   * @param  pData a 16-bit pointer to data buffer.
1178   * @param  Size number of data sample to be sent:
1179   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1180   *         configuration phase, the Size parameter means the number of 16-bit data length
1181   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1182   *         the Size parameter means the number of 16-bit data length.
1183   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1184   *         between Master and Slave(example: audio streaming).
1185   * @retval HAL status
1186   */
HAL_I2S_Transmit_IT(I2S_HandleTypeDef * hi2s,const uint16_t * pData,uint16_t Size)1187 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size)
1188 {
1189   if ((pData == NULL) || (Size == 0UL))
1190   {
1191     return  HAL_ERROR;
1192   }
1193 
1194   if (hi2s->State != HAL_I2S_STATE_READY)
1195   {
1196     return HAL_BUSY;
1197   }
1198 
1199   /* Process Locked */
1200   __HAL_LOCK(hi2s);
1201 
1202   /* Set state and reset error code */
1203   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
1204   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1205   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
1206   hi2s->TxXferSize  = Size;
1207   hi2s->TxXferCount = Size;
1208 
1209   /* Initialize fields not used in handle to zero */
1210   hi2s->pRxBuffPtr  = NULL;
1211   hi2s->RxXferSize  = (uint16_t) 0UL;
1212   hi2s->RxXferCount = (uint16_t) 0UL;
1213 
1214   /* Set the function for IT treatment */
1215   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1216   {
1217     hi2s->TxISR = I2S_Transmit_32Bit_IT;
1218   }
1219   else
1220   {
1221     hi2s->TxISR = I2S_Transmit_16Bit_IT;
1222   }
1223 
1224   /* Check if the I2S is already enabled */
1225   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1226   {
1227     /* Enable I2S peripheral */
1228     __HAL_I2S_ENABLE(hi2s);
1229   }
1230 
1231   /* Enable TXP and UDR interrupt */
1232   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_UDR));
1233 
1234   /* Enable TIFRE interrupt if the mode is Slave  */
1235   if (hi2s->Init.Mode == I2S_MODE_SLAVE_TX)
1236   {
1237     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1238   }
1239 
1240   /* Start the transfer */
1241   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1242 
1243   __HAL_UNLOCK(hi2s);
1244   return HAL_OK;
1245 }
1246 
1247 /**
1248   * @brief  Receive an amount of data in non-blocking mode with Interrupt
1249   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1250   *         the configuration information for I2S module
1251   * @param  pData a 16-bit pointer to the Receive data buffer.
1252   * @param  Size number of data sample to be sent:
1253   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1254   *         configuration phase, the Size parameter means the number of 16-bit data length
1255   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1256   *         the Size parameter means the number of 16-bit data length.
1257   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1258   *         between Master and Slave(example: audio streaming).
1259   * @note   It is recommended to use DMA for the I2S receiver to avoid de-synchronization
1260   * between Master and Slave otherwise the I2S interrupt should be optimized.
1261   * @retval HAL status
1262   */
HAL_I2S_Receive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1263 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1264 {
1265   if ((pData == NULL) || (Size == 0UL))
1266   {
1267     return  HAL_ERROR;
1268   }
1269 
1270   if (hi2s->State != HAL_I2S_STATE_READY)
1271   {
1272     return HAL_BUSY;
1273   }
1274 
1275   /* Process Locked */
1276   __HAL_LOCK(hi2s);
1277 
1278   /* Set state and reset error code */
1279   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
1280   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1281   hi2s->pRxBuffPtr  = pData;
1282   hi2s->RxXferSize  = Size;
1283   hi2s->RxXferCount = Size;
1284 
1285   /* Initialize fields not used in handle to zero */
1286   hi2s->pTxBuffPtr  = NULL;
1287   hi2s->TxXferSize  = (uint16_t) 0UL;
1288   hi2s->TxXferCount = (uint16_t) 0UL;
1289 
1290   /* Set the function for IT treatment */
1291   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1292   {
1293     hi2s->RxISR = I2S_Receive_32Bit_IT;
1294   }
1295   else
1296   {
1297     hi2s->RxISR = I2S_Receive_16Bit_IT;
1298   }
1299 
1300   /* Check if the I2S is already enabled */
1301   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1302   {
1303     /* Enable I2S peripheral */
1304     __HAL_I2S_ENABLE(hi2s);
1305   }
1306   /* Enable RXP and ERR interrupt */
1307   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_OVR));
1308 
1309   /* Enable TIFRE interrupt if the mode is Slave  */
1310   if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
1311   {
1312     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1313   }
1314 
1315   /* Start the transfer */
1316   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1317 
1318   __HAL_UNLOCK(hi2s);
1319   return HAL_OK;
1320 }
1321 
1322 /**
1323   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
1324   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1325   *         the configuration information for I2S module
1326   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1327   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1328   * @param  Size number of data sample to be sent:
1329   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1330   *         configuration phase, the Size parameter means the number of 16-bit data length
1331   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1332   *         the Size parameter means the number of 16-bit data length.
1333   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1334   *         between Master and Slave(example: audio streaming).
1335   * @retval HAL status
1336   */
HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef * hi2s,const uint16_t * pTxData,uint16_t * pRxData,uint16_t Size)1337 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1338                                                uint16_t Size)
1339 {
1340   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1341   {
1342     return  HAL_ERROR;
1343   }
1344 
1345   if (hi2s->State != HAL_I2S_STATE_READY)
1346   {
1347     return HAL_BUSY;
1348   }
1349 
1350   /* Process Locked */
1351   __HAL_LOCK(hi2s);
1352 
1353   hi2s->pTxBuffPtr  = (const uint16_t *)pTxData;
1354   hi2s->pRxBuffPtr  = pRxData;
1355 
1356   hi2s->TxXferSize  = Size;
1357   hi2s->TxXferCount = Size;
1358   hi2s->RxXferSize  = Size;
1359   hi2s->RxXferCount = Size;
1360 
1361   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1362   hi2s->State     = HAL_I2S_STATE_BUSY_TX_RX;
1363 
1364 
1365   /* Set the function for IT treatment */
1366   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1367   {
1368     hi2s->TxISR = I2S_Transmit_32Bit_IT;
1369     hi2s->RxISR = I2S_Receive_32Bit_IT;
1370   }
1371   else
1372   {
1373     hi2s->TxISR = I2S_Transmit_16Bit_IT;
1374     hi2s->RxISR = I2S_Receive_16Bit_IT;
1375   }
1376 
1377   /* Check if the I2S is already enabled */
1378   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1379   {
1380     /* Enable I2S peripheral */
1381     __HAL_I2S_ENABLE(hi2s);
1382   }
1383 
1384   /* Enable TXP, RXP, DXP, UDR, OVR interrupts */
1385   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_UDR | I2S_IT_OVR));
1386 
1387   /* Enable TIFRE interrupt if the mode is Slave  */
1388   if (hi2s->Init.Mode == I2S_MODE_SLAVE_FULLDUPLEX)
1389   {
1390     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1391   }
1392 
1393   /* Start the transfer */
1394   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1395 
1396   __HAL_UNLOCK(hi2s);
1397   return HAL_OK;
1398 
1399 }
1400 
1401 /**
1402   * @brief  Transmit an amount of data in non-blocking mode with DMA
1403   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1404   *         the configuration information for I2S module
1405   * @param  pData a 16-bit pointer to the Transmit data buffer.
1406   * @param  Size number of data sample to be sent:
1407   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1408   *         configuration phase, the Size parameter means the number of 16-bit data length
1409   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1410   *         the Size parameter means the number of 16-bit data length.
1411   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1412   *         between Master and Slave(example: audio streaming).
1413   * @retval HAL status
1414   */
HAL_I2S_Transmit_DMA(I2S_HandleTypeDef * hi2s,const uint16_t * pData,uint16_t Size)1415 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size)
1416 {
1417   HAL_StatusTypeDef errorcode = HAL_OK;
1418 
1419   if ((pData == NULL) || (Size == 0UL))
1420   {
1421     return  HAL_ERROR;
1422   }
1423 
1424   if (hi2s->State != HAL_I2S_STATE_READY)
1425   {
1426     return HAL_BUSY;
1427   }
1428 
1429   /* Process Locked */
1430   __HAL_LOCK(hi2s);
1431 
1432   /* Set state and reset error code */
1433   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
1434   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1435   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
1436   hi2s->TxXferSize  = Size;
1437   hi2s->TxXferCount = Size;
1438 
1439   /* Init field not used in handle to zero */
1440   hi2s->pRxBuffPtr  = NULL;
1441   hi2s->RxXferSize  = (uint16_t)0UL;
1442   hi2s->RxXferCount = (uint16_t)0UL;
1443 
1444   /* Set the I2S Tx DMA Half transfer complete callback */
1445   hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
1446 
1447   /* Set the I2S Tx DMA transfer complete callback */
1448   hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
1449 
1450   /* Set the DMA error callback */
1451   hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
1452 
1453   /* Enable the Tx DMA Stream/Channel */
1454   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR,
1455                                  hi2s->TxXferCount))
1456   {
1457     /* Update I2S error code */
1458     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1459     hi2s->State = HAL_I2S_STATE_READY;
1460 
1461     __HAL_UNLOCK(hi2s);
1462     errorcode = HAL_ERROR;
1463     return errorcode;
1464   }
1465 
1466   /* Check if the I2S Tx request is already enabled */
1467   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
1468   {
1469     /* Enable Tx DMA Request */
1470     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1471   }
1472 
1473   /* Check if the I2S is already enabled */
1474   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1475   {
1476     /* Enable I2S peripheral */
1477     __HAL_I2S_ENABLE(hi2s);
1478   }
1479 
1480   /* Start the transfer */
1481   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1482 
1483   __HAL_UNLOCK(hi2s);
1484   return errorcode;
1485 }
1486 
1487 /**
1488   * @brief  Receive an amount of data in non-blocking mode with DMA
1489   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1490   *         the configuration information for I2S module
1491   * @param  pData a 16-bit pointer to the Receive data buffer.
1492   * @param  Size number of data sample to be sent:
1493   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1494   *         configuration phase, the Size parameter means the number of 16-bit data length
1495   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1496   *         the Size parameter means the number of 16-bit data length.
1497   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1498   *         between Master and Slave(example: audio streaming).
1499   * @retval HAL status
1500   */
HAL_I2S_Receive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1501 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1502 {
1503   HAL_StatusTypeDef errorcode = HAL_OK;
1504 
1505   if ((pData == NULL) || (Size == 0UL))
1506   {
1507     return HAL_ERROR;
1508   }
1509 
1510   if (hi2s->State != HAL_I2S_STATE_READY)
1511   {
1512     return HAL_BUSY;
1513   }
1514 
1515   /* Process Locked */
1516   __HAL_LOCK(hi2s);
1517 
1518   /* Set state and reset error code */
1519   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
1520   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1521   hi2s->pRxBuffPtr  = pData;
1522   hi2s->RxXferSize  = Size;
1523   hi2s->RxXferCount = Size;
1524 
1525   /* Init field not used in handle to zero */
1526   hi2s->pTxBuffPtr  = NULL;
1527   hi2s->TxXferSize  = (uint16_t)0UL;
1528   hi2s->TxXferCount = (uint16_t)0UL;
1529 
1530 
1531   /* Set the I2S Rx DMA Half transfer complete callback */
1532   hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
1533 
1534   /* Set the I2S Rx DMA transfer complete callback */
1535   hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
1536 
1537   /* Set the DMA error callback */
1538   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1539 
1540   /* Enable the Rx DMA Stream/Channel */
1541   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr,
1542                                  hi2s->RxXferCount))
1543   {
1544     /* Update I2S error code */
1545     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1546     hi2s->State = HAL_I2S_STATE_READY;
1547     errorcode = HAL_ERROR;
1548     __HAL_UNLOCK(hi2s);
1549     return errorcode;
1550   }
1551 
1552   /* Check if the I2S Rx request is already enabled */
1553   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
1554   {
1555     /* Enable Rx DMA Request */
1556     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1557   }
1558 
1559   /* Check if the I2S is already enabled */
1560   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1561   {
1562     /* Enable I2S peripheral */
1563     __HAL_I2S_ENABLE(hi2s);
1564   }
1565 
1566   /* Start the transfer */
1567   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1568 
1569   __HAL_UNLOCK(hi2s);
1570   return errorcode;
1571 }
1572 
1573 /**
1574   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using DMA
1575   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1576   *         the configuration information for I2S module
1577   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1578   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1579   * @param  Size number of data sample to be sent:
1580   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1581   *         configuration phase, the Size parameter means the number of 16-bit data length
1582   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1583   *         the Size parameter means the number of 16-bit data length.
1584   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1585   *         between Master and Slave(example: audio streaming).
1586   * @retval HAL status
1587   */
HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef * hi2s,const uint16_t * pTxData,uint16_t * pRxData,uint16_t Size)1588 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1589                                                 uint16_t Size)
1590 {
1591   HAL_StatusTypeDef errorcode = HAL_OK;
1592 
1593 
1594   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1595   {
1596     return  HAL_ERROR;
1597   }
1598 
1599   if (hi2s->State != HAL_I2S_STATE_READY)
1600   {
1601     return HAL_BUSY;
1602   }
1603 
1604   /* Process Locked */
1605   __HAL_LOCK(hi2s);
1606 
1607   hi2s->pTxBuffPtr = (const uint16_t *)pTxData;
1608   hi2s->pRxBuffPtr = pRxData;
1609 
1610   hi2s->TxXferSize  = Size;
1611   hi2s->TxXferCount = Size;
1612   hi2s->RxXferSize  = Size;
1613   hi2s->RxXferCount = Size;
1614 
1615   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1616   hi2s->State       = HAL_I2S_STATE_BUSY_TX_RX;
1617 
1618   /* Reset the Tx/Rx DMA bits */
1619   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
1620 
1621   /* Set the I2S Rx DMA Half transfer complete callback */
1622   hi2s->hdmarx->XferHalfCpltCallback = I2SEx_DMATxRxHalfCplt;
1623 
1624   /* Set the I2S Rx DMA transfer complete callback */
1625   hi2s->hdmarx->XferCpltCallback  = I2SEx_DMATxRxCplt;
1626 
1627   /* Set the I2S Rx DMA error callback */
1628   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1629   /* Enable the Tx DMA Stream/Channel */
1630   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR,
1631                                  hi2s->TxXferCount))
1632   {
1633     /* Update I2S error code */
1634     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1635     hi2s->State = HAL_I2S_STATE_READY;
1636 
1637     __HAL_UNLOCK(hi2s);
1638     errorcode = HAL_ERROR;
1639     return errorcode;
1640   }
1641 
1642   /* Check if the I2S Tx request is already enabled */
1643   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
1644   {
1645     /* Enable Tx DMA Request */
1646     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1647   }
1648 
1649   /* Enable the Rx DMA Stream/Channel */
1650   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr,
1651                                  hi2s->RxXferCount))
1652   {
1653     /* Update I2S error code */
1654     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1655     hi2s->State = HAL_I2S_STATE_READY;
1656     errorcode = HAL_ERROR;
1657     __HAL_UNLOCK(hi2s);
1658     return errorcode;
1659   }
1660 
1661   /* Check if the I2S Rx request is already enabled */
1662   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
1663   {
1664     /* Enable Rx DMA Request */
1665     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1666   }
1667 
1668   /* Check if the I2S is already enabled */
1669   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1670   {
1671     /* Enable I2S peripheral */
1672     __HAL_I2S_ENABLE(hi2s);
1673   }
1674 
1675   /* Start the transfer */
1676   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1677 
1678   __HAL_UNLOCK(hi2s);
1679   return errorcode;
1680 }
1681 
1682 /**
1683   * @brief  Pauses the audio DMA Stream/Channel playing from the Media.
1684   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1685   *         the configuration information for I2S module
1686   * @retval HAL status
1687   */
HAL_I2S_DMAPause(I2S_HandleTypeDef * hi2s)1688 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1689 {
1690   /* Process Locked */
1691   __HAL_LOCK(hi2s);
1692 
1693   uint32_t tickstart;
1694 
1695   /* Get tick */
1696   tickstart = HAL_GetTick();
1697 
1698 
1699   /* Check if the I2S peripheral is in master mode */
1700   if (IS_I2S_MASTER(hi2s->Init.Mode))
1701   {
1702     /* Check if there is a transfer on-going */
1703     if (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) == 0UL)
1704     {
1705       /* Set error code to no on going transfer */
1706       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NO_OGT);
1707       hi2s->State = HAL_I2S_STATE_READY;
1708 
1709       __HAL_UNLOCK(hi2s);
1710       return HAL_ERROR;
1711     }
1712 
1713     SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSUSP);
1714 
1715     while (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) != 0UL)
1716     {
1717       if ((((HAL_GetTick() - tickstart) >=  I2S_TIMEOUT) && (I2S_TIMEOUT != HAL_MAX_DELAY)) || (I2S_TIMEOUT == 0U))
1718       {
1719         /* Set the I2S State ready */
1720         hi2s->State = HAL_I2S_STATE_READY;
1721 
1722         /* Process Unlocked */
1723         __HAL_UNLOCK(hi2s);
1724 
1725         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1726         hi2s->State = HAL_I2S_STATE_READY;
1727         return HAL_TIMEOUT;
1728       }
1729     }
1730 
1731     /* Disable I2S peripheral */
1732     __HAL_I2S_DISABLE(hi2s);
1733 
1734     hi2s->State = HAL_I2S_STATE_READY;
1735 
1736     /* Process Unlocked */
1737     __HAL_UNLOCK(hi2s);
1738 
1739     return HAL_OK;
1740   }
1741   else
1742   {
1743     /* Set error code to not supported */
1744     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NOT_SUPPORTED);
1745     hi2s->State = HAL_I2S_STATE_READY;
1746 
1747     /* Process Unlocked */
1748     __HAL_UNLOCK(hi2s);
1749 
1750     return HAL_ERROR;
1751   }
1752 }
1753 
1754 /**
1755   * @brief  Resumes the audio DMA Stream/Channel playing from the Media.
1756   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1757   *         the configuration information for I2S module
1758   * @retval HAL status
1759   */
HAL_I2S_DMAResume(I2S_HandleTypeDef * hi2s)1760 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1761 {
1762   /* Process Locked */
1763   __HAL_LOCK(hi2s);
1764 
1765   if (hi2s->State != HAL_I2S_STATE_READY)
1766   {
1767     hi2s->State = HAL_I2S_STATE_READY;
1768 
1769     __HAL_UNLOCK(hi2s);
1770     return HAL_ERROR;
1771   }
1772 
1773   /* Set state and reset error code */
1774   hi2s->State       = HAL_I2S_STATE_BUSY;
1775   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1776 
1777   /* Enable I2S peripheral */
1778   __HAL_I2S_ENABLE(hi2s);
1779 
1780   /* Start the transfer */
1781   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1782 
1783   /* Process Unlocked */
1784   __HAL_UNLOCK(hi2s);
1785 
1786   return HAL_OK;
1787 }
1788 
1789 /**
1790   * @brief  Stops the audio DMA Stream/Channel playing from the Media.
1791   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1792   *         the configuration information for I2S module
1793   * @retval HAL status
1794   */
HAL_I2S_DMAStop(I2S_HandleTypeDef * hi2s)1795 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1796 {
1797   HAL_StatusTypeDef errorcode = HAL_OK;
1798   /* The Lock is not implemented on this API to allow the user application
1799      to call the HAL I2S API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1800      when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1801      and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1802      */
1803 
1804   /* Disable the I2S Tx/Rx DMA requests */
1805   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1806   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1807 
1808   /* Abort the I2S DMA tx Stream/Channel */
1809   if (hi2s->hdmatx != NULL)
1810   {
1811     /* Disable the I2S DMA tx Stream/Channel */
1812     if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1813     {
1814       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1815       errorcode = HAL_ERROR;
1816     }
1817   }
1818 
1819   /* Abort the I2S DMA rx Stream/Channel */
1820   if (hi2s->hdmarx != NULL)
1821   {
1822     /* Disable the I2S DMA rx Stream/Channel */
1823     if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1824     {
1825       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1826       errorcode = HAL_ERROR;
1827     }
1828   }
1829 
1830   /* Disable I2S peripheral */
1831   __HAL_I2S_DISABLE(hi2s);
1832 
1833   hi2s->State = HAL_I2S_STATE_READY;
1834 
1835   return errorcode;
1836 }
1837 
1838 /**
1839   * @brief  Enable the SDO/SDI alternate functions inversion feature for the dedicated I2Sx.
1840   *         Original SDI pin becomes SDO and original SDO pin becomes SDI (Also applicable
1841   *         on half-duplex mode in case of single data line).
1842   * @param  hi2s Pointer to a @ref I2S_HandleTypeDef structure that contains
1843   *         the configuration information for I2S module.
1844   * @retval HAL_ERROR When IO is locked, handle is NULL or wrong state.
1845   * @retval HAL_OK IO Swap feature enabled successfully.
1846   */
HAL_I2S_EnableIOSwap(I2S_HandleTypeDef * hi2s)1847 HAL_StatusTypeDef HAL_I2S_EnableIOSwap(I2S_HandleTypeDef *hi2s)
1848 {
1849   /* Check the I2S handle allocation */
1850   if (hi2s == NULL)
1851   {
1852     return HAL_ERROR;
1853   }
1854 
1855   /* Check the global state */
1856   if (hi2s->State != HAL_I2S_STATE_READY)
1857   {
1858     return HAL_ERROR;
1859   }
1860 
1861   /* Check for IOLock */
1862   if (READ_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK) == (SPI_CR1_IOLOCK))
1863   {
1864     return  HAL_ERROR;
1865   }
1866 
1867   /* Check if the I2S is already enabled */
1868   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE)
1869   {
1870     /* Disable I2S peripheral */
1871     __HAL_I2S_DISABLE(hi2s);
1872   }
1873 
1874   /* Enable IO Swap feature */
1875   SET_BIT(hi2s->Instance->CFG2, SPI_CFG2_IOSWP);
1876 
1877   return HAL_OK;
1878 }
1879 
1880 /**
1881   * @brief  Disable the SDO/SDI alternate functions inversion feature for the dedicated I2Sx.
1882   *         Original SDI pin becomes SDI and original SDO pin becomes SDO (Also applicable
1883   *         on half-duplex mode in case of single data line).
1884   * @param  hi2s Pointer to a @ref I2S_HandleTypeDef structure that contains
1885   *         the configuration information for I2S module.
1886   * @retval HAL_ERROR When IO is locked, handle is NULL or wrong state.
1887   * @retval HAL_OK IO Swap feature disabled successfully.
1888   */
HAL_I2S_DisableIOSwap(I2S_HandleTypeDef * hi2s)1889 HAL_StatusTypeDef HAL_I2S_DisableIOSwap(I2S_HandleTypeDef *hi2s)
1890 {
1891   /* Check the I2S handle allocation */
1892   if (hi2s == NULL)
1893   {
1894     return HAL_ERROR;
1895   }
1896 
1897   /* Check the global state */
1898   if (hi2s->State != HAL_I2S_STATE_READY)
1899   {
1900     return HAL_ERROR;
1901   }
1902 
1903   /* Check for IOLock */
1904   if (READ_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK) == (SPI_CR1_IOLOCK))
1905   {
1906     return HAL_ERROR;
1907   }
1908 
1909   /* Check if the I2S is already enabled */
1910   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE)
1911   {
1912     /* Disable I2S peripheral */
1913     __HAL_I2S_DISABLE(hi2s);
1914   }
1915 
1916   /* Disable the IO Swap feature */
1917   CLEAR_BIT(hi2s->Instance->CFG2, SPI_CFG2_IOSWP);
1918 
1919   return HAL_OK;
1920 }
1921 
1922 /**
1923   * @brief  Retrieve the SDO/SDI alternate functions inversion feature status for the dedicated I2Sx.
1924   * @param  hi2s Pointer to a @ref I2S_HandleTypeDef structure that contains
1925   *         the configuration information for I2S module.
1926   * @retval 1 when I2S IO swap feature is enabled, 0 otherwise, or when hi2s pointer is null.
1927   */
HAL_I2S_IsEnabledIOSwap(const I2S_HandleTypeDef * hi2s)1928 uint32_t HAL_I2S_IsEnabledIOSwap(const I2S_HandleTypeDef *hi2s)
1929 {
1930   /* Check the I2S handle allocation */
1931   if (hi2s == NULL)
1932   {
1933     return 0;
1934   }
1935 
1936   return ((READ_BIT(hi2s->Instance->CFG2, SPI_CFG2_IOSWP) == (SPI_CFG2_IOSWP)) ? 1UL : 0UL);
1937 }
1938 
1939 /**
1940   * @brief  This function handles I2S interrupt request.
1941   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1942   *         the configuration information for I2S module
1943   * @retval None
1944   */
HAL_I2S_IRQHandler(I2S_HandleTypeDef * hi2s)1945 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1946 {
1947   uint32_t i2sier   = hi2s->Instance->IER;
1948   uint32_t i2ssr    = hi2s->Instance->SR;
1949   uint32_t trigger  = i2sier & i2ssr;
1950 
1951   if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1952   {
1953     /* I2S in mode Receiver ------------------------------------------------*/
1954     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_OVR))
1955     {
1956       hi2s->RxISR(hi2s);
1957     }
1958 
1959     /* I2S Overrun error interrupt occurred -------------------------------------*/
1960     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR))
1961     {
1962       /* Disable RXP and ERR interrupt */
1963       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
1964 
1965       /* Clear Overrun flag */
1966       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1967 
1968       /* Set the I2S State ready */
1969       hi2s->State = HAL_I2S_STATE_READY;
1970 
1971 
1972       /* Set the error code and execute error callback*/
1973       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1974       /* Call user error callback */
1975 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1976       hi2s->ErrorCallback(hi2s);
1977 #else
1978       HAL_I2S_ErrorCallback(hi2s);
1979 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1980     }
1981   }
1982 
1983   if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1984   {
1985     /* I2S in mode Transmitter -----------------------------------------------*/
1986     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_UDR))
1987     {
1988       hi2s->TxISR(hi2s);
1989     }
1990 
1991     /* I2S Underrun error interrupt occurred --------------------------------*/
1992     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR))
1993     {
1994       /* Disable TXP and ERR interrupt */
1995       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
1996 
1997       /* Clear Underrun flag */
1998       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1999 
2000       /* Set the I2S State ready */
2001       hi2s->State = HAL_I2S_STATE_READY;
2002 
2003       /* Set the error code and execute error callback*/
2004       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
2005       /* Call user error callback */
2006 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2007       hi2s->ErrorCallback(hi2s);
2008 #else
2009       HAL_I2S_ErrorCallback(hi2s);
2010 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2011     }
2012   }
2013   if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
2014   {
2015     /* I2S in mode Transmitter -----------------------------------------------*/
2016     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_DXP))
2017     {
2018       hi2s->TxISR(hi2s);
2019       hi2s->RxISR(hi2s);
2020     }
2021     /* I2S in mode Receiver ------------------------------------------------*/
2022     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP))
2023     {
2024       hi2s->RxISR(hi2s);
2025     }
2026     /* I2S in mode Transmitter -----------------------------------------------*/
2027     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP))
2028     {
2029       hi2s->TxISR(hi2s);
2030     }
2031 
2032     /* I2S Underrun error interrupt occurred --------------------------------*/
2033     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR))
2034     {
2035       /* Disable TXP, RXP and ERR interrupt */
2036       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_ERR));
2037 
2038       /* Clear Underrun flag */
2039       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
2040 
2041       /* Set the I2S State ready */
2042       hi2s->State = HAL_I2S_STATE_READY;
2043 
2044       /* Set the error code and execute error callback*/
2045       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
2046       /* Call user error callback */
2047 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2048       hi2s->ErrorCallback(hi2s);
2049 #else
2050       HAL_I2S_ErrorCallback(hi2s);
2051 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2052     }
2053 
2054     /* I2S Overrun error interrupt occurred -------------------------------------*/
2055     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR))
2056     {
2057       /* Disable TXP, RXP and ERR interrupt */
2058       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_ERR));
2059 
2060       /* Clear Overrun flag */
2061       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
2062 
2063       /* Set the I2S State ready */
2064       hi2s->State = HAL_I2S_STATE_READY;
2065 
2066 
2067       /* Set the error code and execute error callback*/
2068       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
2069 
2070       /* Call user error callback */
2071 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2072       hi2s->ErrorCallback(hi2s);
2073 #else
2074       HAL_I2S_ErrorCallback(hi2s);
2075 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2076     }
2077   }
2078 }
2079 
2080 /**
2081   * @brief  Tx Transfer Half completed callbacks
2082   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2083   *         the configuration information for I2S module
2084   * @retval None
2085   */
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef * hi2s)2086 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2087 {
2088   /* Prevent unused argument(s) compilation warning */
2089   UNUSED(hi2s);
2090 
2091   /* NOTE : This function Should not be modified, when the callback is needed,
2092             the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
2093    */
2094 }
2095 
2096 /**
2097   * @brief  Tx Transfer completed callbacks
2098   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2099   *         the configuration information for I2S module
2100   * @retval None
2101   */
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef * hi2s)2102 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
2103 {
2104   /* Prevent unused argument(s) compilation warning */
2105   UNUSED(hi2s);
2106 
2107   /* NOTE : This function Should not be modified, when the callback is needed,
2108             the HAL_I2S_TxCpltCallback could be implemented in the user file
2109    */
2110 }
2111 
2112 /**
2113   * @brief  Rx Transfer half completed callbacks
2114   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2115   *         the configuration information for I2S module
2116   * @retval None
2117   */
HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef * hi2s)2118 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2119 {
2120   /* Prevent unused argument(s) compilation warning */
2121   UNUSED(hi2s);
2122 
2123   /* NOTE : This function Should not be modified, when the callback is needed,
2124             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
2125    */
2126 }
2127 
2128 /**
2129   * @brief  Rx Transfer completed callbacks
2130   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2131   *         the configuration information for I2S module
2132   * @retval None
2133   */
HAL_I2S_RxCpltCallback(I2S_HandleTypeDef * hi2s)2134 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
2135 {
2136   /* Prevent unused argument(s) compilation warning */
2137   UNUSED(hi2s);
2138 
2139   /* NOTE : This function Should not be modified, when the callback is needed,
2140             the HAL_I2S_RxCpltCallback could be implemented in the user file
2141    */
2142 }
2143 
2144 /**
2145   * @brief  Rx Transfer half completed callbacks
2146   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2147   *         the configuration information for I2S module
2148   * @retval None
2149   */
HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef * hi2s)2150 __weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2151 {
2152   /* Prevent unused argument(s) compilation warning */
2153   UNUSED(hi2s);
2154 
2155   /* NOTE : This function Should not be modified, when the callback is needed,
2156             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
2157    */
2158 }
2159 
2160 /**
2161   * @brief  Rx Transfer completed callbacks
2162   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2163   *         the configuration information for I2S module
2164   * @retval None
2165   */
HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef * hi2s)2166 __weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
2167 {
2168   /* Prevent unused argument(s) compilation warning */
2169   UNUSED(hi2s);
2170 
2171   /* NOTE : This function Should not be modified, when the callback is needed,
2172             the HAL_I2S_RxCpltCallback could be implemented in the user file
2173    */
2174 }
2175 
2176 /**
2177   * @brief  I2S error callbacks
2178   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2179   *         the configuration information for I2S module
2180   * @retval None
2181   */
HAL_I2S_ErrorCallback(I2S_HandleTypeDef * hi2s)2182 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
2183 {
2184   /* Prevent unused argument(s) compilation warning */
2185   UNUSED(hi2s);
2186 
2187   /* NOTE : This function Should not be modified, when the callback is needed,
2188             the HAL_I2S_ErrorCallback could be implemented in the user file
2189    */
2190 }
2191 
2192 /**
2193   * @}
2194   */
2195 
2196 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
2197   *  @brief   Peripheral State functions
2198   *
2199 @verbatim
2200  ===============================================================================
2201                       ##### Peripheral State and Errors functions #####
2202  ===============================================================================
2203     [..]
2204     This subsection permits to get in run-time the status of the peripheral
2205     and the data flow.
2206 
2207 @endverbatim
2208   * @{
2209   */
2210 
2211 /**
2212   * @brief  Return the I2S state
2213   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2214   *         the configuration information for I2S module
2215   * @retval HAL state
2216   */
HAL_I2S_GetState(const I2S_HandleTypeDef * hi2s)2217 HAL_I2S_StateTypeDef HAL_I2S_GetState(const I2S_HandleTypeDef *hi2s)
2218 {
2219   return hi2s->State;
2220 }
2221 
2222 /**
2223   * @brief  Return the I2S error code
2224   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2225   *         the configuration information for I2S module
2226   * @retval I2S Error Code
2227   */
HAL_I2S_GetError(const I2S_HandleTypeDef * hi2s)2228 uint32_t HAL_I2S_GetError(const I2S_HandleTypeDef *hi2s)
2229 {
2230   return hi2s->ErrorCode;
2231 }
2232 /**
2233   * @}
2234   */
2235 
2236 /**
2237   * @}
2238   */
2239 
2240 /** @addtogroup I2S_Private_Functions
2241   * @{
2242   */
2243 /**
2244   * @brief  DMA I2S transmit process complete callback
2245   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2246   *                the configuration information for the specified DMA module.
2247   * @retval None
2248   */
I2S_DMATxCplt(DMA_HandleTypeDef * hdma)2249 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
2250 {
2251   /* Derogation MISRAC2012-Rule-11.5 */
2252   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2253 
2254   /* if DMA is configured in DMA_NORMAL Mode */
2255   if (hdma->Init.Mode == DMA_NORMAL)
2256   {
2257     /* Disable Tx DMA Request */
2258     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
2259 
2260     hi2s->TxXferCount = (uint16_t) 0UL;
2261     hi2s->State = HAL_I2S_STATE_READY;
2262   }
2263   /* Call user Tx complete callback */
2264 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2265   hi2s->TxCpltCallback(hi2s);
2266 #else
2267   HAL_I2S_TxCpltCallback(hi2s);
2268 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2269 }
2270 
2271 /**
2272   * @brief  DMA I2S transmit process half complete callback
2273   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2274   *         the configuration information for the specified DMA module.
2275   * @retval None
2276   */
I2S_DMATxHalfCplt(DMA_HandleTypeDef * hdma)2277 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2278 {
2279   /* Derogation MISRAC2012-Rule-11.5 */
2280   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2281 
2282   /* Call user Tx half complete callback */
2283 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2284   hi2s->TxHalfCpltCallback(hi2s);
2285 #else
2286   HAL_I2S_TxHalfCpltCallback(hi2s);
2287 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2288 }
2289 
2290 /**
2291   * @brief  DMA I2S receive process complete callback
2292   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2293   *         the configuration information for the specified DMA module.
2294   * @retval None
2295   */
I2S_DMARxCplt(DMA_HandleTypeDef * hdma)2296 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
2297 {
2298   /* Derogation MISRAC2012-Rule-11.5 */
2299   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2300 
2301   /* if DMA is configured in DMA_NORMAL Mode */
2302   if (hdma->Init.Mode == DMA_NORMAL)
2303   {
2304     /* Disable Rx DMA Request */
2305     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
2306     hi2s->RxXferCount = (uint16_t)0UL;
2307     hi2s->State = HAL_I2S_STATE_READY;
2308   }
2309   /* Call user Rx complete callback */
2310 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2311   hi2s->RxCpltCallback(hi2s);
2312 #else
2313   HAL_I2S_RxCpltCallback(hi2s);
2314 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2315 }
2316 
2317 /**
2318   * @brief  DMA I2S receive process half complete callback
2319   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2320   *         the configuration information for the specified DMA module.
2321   * @retval None
2322   */
I2S_DMARxHalfCplt(DMA_HandleTypeDef * hdma)2323 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2324 {
2325   /* Derogation MISRAC2012-Rule-11.5 */
2326   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2327 
2328   /* Call user Rx half complete callback */
2329 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2330   hi2s->RxHalfCpltCallback(hi2s);
2331 #else
2332   HAL_I2S_RxHalfCpltCallback(hi2s);
2333 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2334 }
2335 
2336 /**
2337   * @brief  DMA I2S transmit receive process complete callback
2338   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2339   *               the configuration information for the specified DMA module.
2340   * @retval None
2341   */
I2SEx_DMATxRxCplt(DMA_HandleTypeDef * hdma)2342 static void I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma)
2343 {
2344   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2345 
2346   /* if DMA is configured in DMA_NORMAL Mode */
2347   if (hdma->Init.Mode == DMA_NORMAL)
2348   {
2349     /* Disable Tx DMA Request */
2350     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
2351     hi2s->TxXferCount = (uint16_t) 0UL;
2352 
2353     /* Disable Rx DMA Request */
2354     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
2355     hi2s->RxXferCount = (uint16_t)0UL;
2356 
2357     /* Updated HAL State */
2358     hi2s->State = HAL_I2S_STATE_READY;
2359   }
2360 
2361   /* Call user TxRx complete callback */
2362 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
2363   hi2s->TxRxCpltCallback(hi2s);
2364 #else
2365   HAL_I2SEx_TxRxCpltCallback(hi2s);
2366 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2367 }
2368 
2369 /**
2370   * @brief  DMA I2S transmit receive process half complete callback
2371   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2372   *               the configuration information for the specified DMA module.
2373   * @retval None
2374   */
I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef * hdma)2375 static void I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma)
2376 {
2377   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2378 
2379   /* Call user TxRx Half complete callback */
2380 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
2381   hi2s->TxRxHalfCpltCallback(hi2s);
2382 #else
2383   HAL_I2SEx_TxRxHalfCpltCallback(hi2s);
2384 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2385 }
2386 
2387 /**
2388   * @brief  DMA I2S communication error callback
2389   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2390   *         the configuration information for the specified DMA module.
2391   * @retval None
2392   */
I2S_DMAError(DMA_HandleTypeDef * hdma)2393 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
2394 {
2395   /* Derogation MISRAC2012-Rule-11.5 */
2396   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2397 
2398   /* Disable Rx and Tx DMA Request */
2399   CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN));
2400   hi2s->TxXferCount = (uint16_t) 0UL;
2401   hi2s->RxXferCount = (uint16_t) 0UL;
2402 
2403   hi2s->State = HAL_I2S_STATE_READY;
2404 
2405   /* Set the error code and execute error callback*/
2406   SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
2407   /* Call user error callback */
2408 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2409   hi2s->ErrorCallback(hi2s);
2410 #else
2411   HAL_I2S_ErrorCallback(hi2s);
2412 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2413 }
2414 
2415 /**
2416   * @brief  Manage the transmission 16-bit in Interrupt context
2417   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2418   *         the configuration information for I2S module
2419   * @retval None
2420   */
I2S_Transmit_16Bit_IT(I2S_HandleTypeDef * hi2s)2421 static void I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s)
2422 {
2423   /* Transmit data */
2424 #if defined (__GNUC__)
2425   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
2426 
2427   *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
2428 #else
2429   *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
2430 #endif /* __GNUC__ */
2431   hi2s->pTxBuffPtr++;
2432   hi2s->TxXferCount--;
2433 
2434   if (hi2s->TxXferCount == 0UL)
2435   {
2436     /* Disable TXP and ERR interrupt */
2437     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
2438 
2439     if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX))
2440     {
2441       hi2s->State = HAL_I2S_STATE_READY;
2442 
2443       /* Call user Tx complete callback */
2444 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2445       hi2s->TxCpltCallback(hi2s);
2446 #else
2447       HAL_I2S_TxCpltCallback(hi2s);
2448 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2449     }
2450   }
2451 }
2452 
2453 /**
2454   * @brief  Manage the transmission 32-bit in Interrupt context
2455   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2456   *         the configuration information for I2S module
2457   * @retval None
2458   */
I2S_Transmit_32Bit_IT(I2S_HandleTypeDef * hi2s)2459 static void I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s)
2460 {
2461   /* Transmit data */
2462   hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
2463   hi2s->pTxBuffPtr += 2;
2464   hi2s->TxXferCount--;
2465 
2466   if (hi2s->TxXferCount == 0UL)
2467   {
2468     /* Disable TXP and ERR interrupt */
2469     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
2470 
2471     if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX))
2472     {
2473       hi2s->State = HAL_I2S_STATE_READY;
2474 
2475       /* Call user Tx complete callback */
2476 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2477       hi2s->TxCpltCallback(hi2s);
2478 #else
2479       HAL_I2S_TxCpltCallback(hi2s);
2480 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2481     }
2482   }
2483 }
2484 
2485 /**
2486   * @brief  Manage the reception 16-bit in Interrupt context
2487   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2488   *         the configuration information for I2S module
2489   * @retval None
2490   */
I2S_Receive_16Bit_IT(I2S_HandleTypeDef * hi2s)2491 static void I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s)
2492 {
2493   /* Receive data */
2494 #if defined (__GNUC__)
2495   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
2496 
2497   *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
2498 #else
2499   *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
2500 #endif /* __GNUC__ */
2501   hi2s->pRxBuffPtr++;
2502   hi2s->RxXferCount--;
2503 
2504   if (hi2s->RxXferCount == 0UL)
2505   {
2506     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2507     {
2508       /* Disable TXP, RXP, DXP, ERR interrupts */
2509       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR));
2510     }
2511     else
2512     {
2513       /* Disable RXP and ERR interrupt */
2514       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
2515     }
2516 
2517     hi2s->State = HAL_I2S_STATE_READY;
2518     /* Call user Rx complete callback */
2519 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2520     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2521     {
2522       hi2s->TxRxCpltCallback(hi2s);
2523     }
2524     else
2525     {
2526       hi2s->RxCpltCallback(hi2s);
2527     }
2528 #else
2529     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2530     {
2531       HAL_I2SEx_TxRxCpltCallback(hi2s);
2532     }
2533     else
2534     {
2535       HAL_I2S_RxCpltCallback(hi2s);
2536     }
2537 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2538   }
2539 }
2540 
2541 /**
2542   * @brief  Manage the reception 32-bit in Interrupt context
2543   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2544   *         the configuration information for I2S module
2545   * @retval None
2546   */
I2S_Receive_32Bit_IT(I2S_HandleTypeDef * hi2s)2547 static void I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s)
2548 {
2549   /* Receive data */
2550   *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
2551   hi2s->pRxBuffPtr += 2;
2552   hi2s->RxXferCount--;
2553 
2554   if (hi2s->RxXferCount == 0UL)
2555   {
2556     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2557     {
2558       /* Disable TXP, RXP, DXP, ERR interrupts */
2559       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR));
2560     }
2561     else
2562     {
2563       /* Disable RXP and ERR interrupt */
2564       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
2565     }
2566 
2567     hi2s->State = HAL_I2S_STATE_READY;
2568     /* Call user Rx complete callback */
2569 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2570     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2571     {
2572       hi2s->TxRxCpltCallback(hi2s);
2573     }
2574     else
2575     {
2576       hi2s->RxCpltCallback(hi2s);
2577     }
2578 #else
2579     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2580     {
2581       HAL_I2SEx_TxRxCpltCallback(hi2s);
2582     }
2583     else
2584     {
2585       HAL_I2S_RxCpltCallback(hi2s);
2586     }
2587 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2588   }
2589 }
2590 
2591 /**
2592   * @brief  This function handles I2S Communication Timeout.
2593   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2594   *         the configuration information for I2S module
2595   * @param  Flag Flag checked
2596   * @param  State Value of the flag expected
2597   * @param  Tickstart Tick start value
2598   * @param  Timeout Duration of the timeout
2599   * @retval HAL status
2600   */
I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)2601 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
2602                                                        uint32_t Tickstart, uint32_t Timeout)
2603 {
2604   /* Wait until flag is set to status*/
2605   while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
2606   {
2607     if (Timeout != HAL_MAX_DELAY)
2608     {
2609       if (((HAL_GetTick() - Tickstart) >= Timeout) || (Timeout == 0UL))
2610       {
2611         /* Set the I2S State ready */
2612         hi2s->State = HAL_I2S_STATE_READY;
2613 
2614         /* Process Unlocked */
2615         __HAL_UNLOCK(hi2s);
2616 
2617         return HAL_TIMEOUT;
2618       }
2619     }
2620   }
2621   return HAL_OK;
2622 }
2623 
2624 /**
2625   * @}
2626   */
2627 
2628 /**
2629   * @}
2630   */
2631 
2632 /**
2633   * @}
2634   */
2635 
2636 #endif /* HAL_I2S_MODULE_ENABLED */
2637 
2638