1 /**
2   ******************************************************************************
3   * @file    stm32f0xx_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) 2016 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    -@- Make sure that either:
56         (+@) External clock source is configured after setting correctly
57              the define constant EXTERNAL_CLOCK_VALUE in the stm32f0xx_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          In Slave mode, if HAL_I2S_DMAStop is used to stop the communication, an error
102          HAL_I2S_ERROR_BUSY_LINE_RX is raised as the master continue to transmit data.
103          In this case __HAL_I2S_FLUSH_RX_DR macro must be used to flush the remaining data
104          inside DR register and avoid using DeInit/Init process for the next transfer.
105 
106    *** I2S HAL driver macros list ***
107    ===================================
108    [..]
109      Below the list of most used macros in I2S HAL driver.
110 
111       (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
112       (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
113       (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
114       (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
115       (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
116       (+) __HAL_I2S_FLUSH_RX_DR: Read DR Register to Flush RX Data
117 
118     [..]
119       (@) You can refer to the I2S HAL driver header file for more useful macros
120 
121    *** I2S HAL driver macros list ***
122    ===================================
123    [..]
124        Callback registration:
125 
126       (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1U
127           allows the user to configure dynamically the driver callbacks.
128           Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
129 
130           Function HAL_I2S_RegisterCallback() allows to register following callbacks:
131             (++) TxCpltCallback        : I2S Tx Completed callback
132             (++) RxCpltCallback        : I2S Rx Completed callback
133             (++) TxHalfCpltCallback    : I2S Tx Half Completed callback
134             (++) RxHalfCpltCallback    : I2S Rx Half Completed callback
135             (++) ErrorCallback         : I2S Error callback
136             (++) MspInitCallback       : I2S Msp Init callback
137             (++) MspDeInitCallback     : I2S Msp DeInit callback
138           This function takes as parameters the HAL peripheral handle, the Callback ID
139           and a pointer to the user callback function.
140 
141 
142       (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default
143           weak function.
144           HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
145           and the Callback ID.
146           This function allows to reset following callbacks:
147             (++) TxCpltCallback        : I2S Tx Completed callback
148             (++) RxCpltCallback        : I2S Rx Completed callback
149             (++) TxHalfCpltCallback    : I2S Tx Half Completed callback
150             (++) RxHalfCpltCallback    : I2S Rx Half Completed callback
151             (++) ErrorCallback         : I2S Error callback
152             (++) MspInitCallback       : I2S Msp Init callback
153             (++) MspDeInitCallback     : I2S Msp DeInit callback
154 
155        [..]
156        By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
157        all callbacks are set to the corresponding weak functions:
158        examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
159        Exception done for MspInit and MspDeInit functions that are
160        reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
161        these callbacks are null (not registered beforehand).
162        If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
163        keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
164 
165        [..]
166        Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
167        Exception done MspInit/MspDeInit functions that can be registered/unregistered
168        in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state,
169        thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
170        Then, the user first registers the MspInit/MspDeInit user callbacks
171        using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
172        or HAL_I2S_Init() function.
173 
174        [..]
175        When the compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
176        not defined, the callback registering feature is not available
177        and weak (surcharged) callbacks are used.
178 
179   @endverbatim
180 
181   */
182 
183 /* Includes ------------------------------------------------------------------*/
184 #include "stm32f0xx_hal.h"
185 
186 #ifdef HAL_I2S_MODULE_ENABLED
187 
188 #if defined(SPI_I2S_SUPPORT)
189 /** @addtogroup STM32F0xx_HAL_Driver
190   * @{
191   */
192 
193 /** @defgroup I2S I2S
194   * @brief I2S HAL module driver
195   * @{
196   */
197 
198 /* Private typedef -----------------------------------------------------------*/
199 /* Private define ------------------------------------------------------------*/
200 #define I2S_TIMEOUT_FLAG          100U         /*!< Timeout 100 ms            */
201 /* Private macro -------------------------------------------------------------*/
202 /* Private variables ---------------------------------------------------------*/
203 /* Private function prototypes -----------------------------------------------*/
204 /** @defgroup I2S_Private_Functions I2S Private Functions
205   * @{
206   */
207 static void               I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
208 static void               I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
209 static void               I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
210 static void               I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
211 static void               I2S_DMAError(DMA_HandleTypeDef *hdma);
212 static void               I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
213 static void               I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
214 static HAL_StatusTypeDef  I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
215                                                         uint32_t Timeout);
216 /**
217   * @}
218   */
219 
220 /* Exported functions ---------------------------------------------------------*/
221 
222 /** @defgroup I2S_Exported_Functions I2S Exported Functions
223   * @{
224   */
225 
226 /** @defgroup  I2S_Exported_Functions_Group1 Initialization and de-initialization functions
227   *  @brief    Initialization and Configuration functions
228   *
229 @verbatim
230  ===============================================================================
231               ##### Initialization and de-initialization functions #####
232  ===============================================================================
233     [..]  This subsection provides a set of functions allowing to initialize and
234           de-initialize the I2Sx peripheral in simplex mode:
235 
236       (+) User must Implement HAL_I2S_MspInit() function in which he configures
237           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
238 
239       (+) Call the function HAL_I2S_Init() to configure the selected device with
240           the selected configuration:
241         (++) Mode
242         (++) Standard
243         (++) Data Format
244         (++) MCLK Output
245         (++) Audio frequency
246         (++) Polarity
247 
248      (+) Call the function HAL_I2S_DeInit() to restore the default configuration
249           of the selected I2Sx peripheral.
250   @endverbatim
251   * @{
252   */
253 
254 /**
255   * @brief  Initializes the I2S according to the specified parameters
256   *         in the I2S_InitTypeDef and create the associated handle.
257   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
258   *         the configuration information for I2S module
259   * @retval HAL status
260   */
HAL_I2S_Init(I2S_HandleTypeDef * hi2s)261 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
262 {
263   uint32_t i2sdiv;
264   uint32_t i2sodd;
265   uint32_t packetlength;
266   uint32_t tmp;
267   uint32_t i2sclk;
268 
269   /* Check the I2S handle allocation */
270   if (hi2s == NULL)
271   {
272     return HAL_ERROR;
273   }
274 
275   /* Check the I2S parameters */
276   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
277   assert_param(IS_I2S_MODE(hi2s->Init.Mode));
278   assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
279   assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
280   assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
281   assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
282   assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
283 
284   if (hi2s->State == HAL_I2S_STATE_RESET)
285   {
286     /* Allocate lock resource and initialize it */
287     hi2s->Lock = HAL_UNLOCKED;
288 
289 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
290     /* Init the I2S Callback settings */
291     hi2s->TxCpltCallback       = HAL_I2S_TxCpltCallback;          /* Legacy weak TxCpltCallback       */
292     hi2s->RxCpltCallback       = HAL_I2S_RxCpltCallback;          /* Legacy weak RxCpltCallback       */
293     hi2s->TxHalfCpltCallback   = HAL_I2S_TxHalfCpltCallback;      /* Legacy weak TxHalfCpltCallback   */
294     hi2s->RxHalfCpltCallback   = HAL_I2S_RxHalfCpltCallback;      /* Legacy weak RxHalfCpltCallback   */
295     hi2s->ErrorCallback        = HAL_I2S_ErrorCallback;           /* Legacy weak ErrorCallback        */
296 
297     if (hi2s->MspInitCallback == NULL)
298     {
299       hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit  */
300     }
301 
302     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
303     hi2s->MspInitCallback(hi2s);
304 #else
305     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
306     HAL_I2S_MspInit(hi2s);
307 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
308   }
309 
310   hi2s->State = HAL_I2S_STATE_BUSY;
311 
312   /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
313   /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
314   CLEAR_BIT(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
315                                       SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
316                                       SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD));
317   hi2s->Instance->I2SPR = 0x0002U;
318 
319   /*----------------------- I2SPR: I2SDIV and ODD Calculation -----------------*/
320   /* If the requested audio frequency is not the default, compute the prescaler */
321   if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
322   {
323     /* Check the frame length (For the Prescaler computing) ********************/
324     if (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B)
325     {
326       /* Packet length is 16 bits */
327       packetlength = 16U;
328     }
329     else
330     {
331       /* Packet length is 32 bits */
332       packetlength = 32U;
333     }
334 
335     /* I2S standard */
336     if (hi2s->Init.Standard <= I2S_STANDARD_LSB)
337     {
338       /* In I2S standard packet length is multiplied by 2 */
339       packetlength = packetlength * 2U;
340     }
341 
342     /* Get the source clock value: based on System Clock value */
343     i2sclk = HAL_RCC_GetSysClockFreq();
344 
345     /* Compute the Real divider depending on the MCLK output state, with a floating point */
346     if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
347     {
348       /* MCLK output is enabled */
349       if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
350       {
351         tmp = (uint32_t)(((((i2sclk / (packetlength * 4U)) * 10U) / hi2s->Init.AudioFreq)) + 5U);
352       }
353       else
354       {
355         tmp = (uint32_t)(((((i2sclk / (packetlength * 8U)) * 10U) / hi2s->Init.AudioFreq)) + 5U);
356       }
357     }
358     else
359     {
360       /* MCLK output is disabled */
361       tmp = (uint32_t)(((((i2sclk / packetlength) * 10U) / hi2s->Init.AudioFreq)) + 5U);
362     }
363 
364     /* Remove the flatting point */
365     tmp = tmp / 10U;
366 
367     /* Check the parity of the divider */
368     i2sodd = (uint32_t)(tmp & (uint32_t)1U);
369 
370     /* Compute the i2sdiv prescaler */
371     i2sdiv = (uint32_t)((tmp - i2sodd) / 2U);
372 
373     /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
374     i2sodd = (uint32_t)(i2sodd << 8U);
375   }
376   else
377   {
378     /* Set the default values */
379     i2sdiv = 2U;
380     i2sodd = 0U;
381   }
382 
383   /* Test if the divider is 1 or 0 or greater than 0xFF */
384   if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
385   {
386     /* Set the error code and execute error callback*/
387     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
388     return  HAL_ERROR;
389   }
390 
391   /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
392 
393   /* Write to SPIx I2SPR register the computed value */
394   hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput));
395 
396   /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
397   /* And configure the I2S with the I2S_InitStruct values                      */
398   MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
399                                        SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
400                                        SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
401                                        SPI_I2SCFGR_I2SE  | SPI_I2SCFGR_I2SMOD), \
402              (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | \
403               hi2s->Init.Standard | hi2s->Init.DataFormat | \
404               hi2s->Init.CPOL));
405 
406 #if defined(SPI_I2SCFGR_ASTRTEN)
407   if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) || ((hi2s->Init.Standard == I2S_STANDARD_PCM_LONG)))
408   {
409     /* Write to SPIx I2SCFGR */
410     SET_BIT(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_ASTRTEN);
411   }
412 #endif /* SPI_I2SCFGR_ASTRTEN */
413 
414   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
415   hi2s->State     = HAL_I2S_STATE_READY;
416 
417   return HAL_OK;
418 }
419 
420 /**
421   * @brief DeInitializes the I2S peripheral
422   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
423   *         the configuration information for I2S module
424   * @retval HAL status
425   */
HAL_I2S_DeInit(I2S_HandleTypeDef * hi2s)426 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
427 {
428   /* Check the I2S handle allocation */
429   if (hi2s == NULL)
430   {
431     return HAL_ERROR;
432   }
433 
434   /* Check the parameters */
435   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
436 
437   hi2s->State = HAL_I2S_STATE_BUSY;
438 
439   /* Disable the I2S Peripheral Clock */
440   __HAL_I2S_DISABLE(hi2s);
441 
442 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
443   if (hi2s->MspDeInitCallback == NULL)
444   {
445     hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit  */
446   }
447 
448   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
449   hi2s->MspDeInitCallback(hi2s);
450 #else
451   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
452   HAL_I2S_MspDeInit(hi2s);
453 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
454 
455   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
456   hi2s->State     = HAL_I2S_STATE_RESET;
457 
458   /* Release Lock */
459   __HAL_UNLOCK(hi2s);
460 
461   return HAL_OK;
462 }
463 
464 /**
465   * @brief I2S MSP Init
466   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
467   *         the configuration information for I2S module
468   * @retval None
469   */
HAL_I2S_MspInit(I2S_HandleTypeDef * hi2s)470 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
471 {
472   /* Prevent unused argument(s) compilation warning */
473   UNUSED(hi2s);
474 
475   /* NOTE : This function Should not be modified, when the callback is needed,
476             the HAL_I2S_MspInit could be implemented in the user file
477    */
478 }
479 
480 /**
481   * @brief I2S MSP DeInit
482   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
483   *         the configuration information for I2S module
484   * @retval None
485   */
HAL_I2S_MspDeInit(I2S_HandleTypeDef * hi2s)486 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
487 {
488   /* Prevent unused argument(s) compilation warning */
489   UNUSED(hi2s);
490 
491   /* NOTE : This function Should not be modified, when the callback is needed,
492             the HAL_I2S_MspDeInit could be implemented in the user file
493    */
494 }
495 
496 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
497 /**
498   * @brief  Register a User I2S Callback
499   *         To be used instead of the weak predefined callback
500   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
501   *                the configuration information for the specified I2S.
502   * @param  CallbackID ID of the callback to be registered
503   * @param  pCallback pointer to the Callback function
504   * @retval HAL status
505   */
HAL_I2S_RegisterCallback(I2S_HandleTypeDef * hi2s,HAL_I2S_CallbackIDTypeDef CallbackID,pI2S_CallbackTypeDef pCallback)506 HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID,
507                                            pI2S_CallbackTypeDef pCallback)
508 {
509   HAL_StatusTypeDef status = HAL_OK;
510 
511   if (pCallback == NULL)
512   {
513     /* Update the error code */
514     hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
515 
516     return HAL_ERROR;
517   }
518   /* Process locked */
519   __HAL_LOCK(hi2s);
520 
521   if (HAL_I2S_STATE_READY == hi2s->State)
522   {
523     switch (CallbackID)
524     {
525       case HAL_I2S_TX_COMPLETE_CB_ID :
526         hi2s->TxCpltCallback = pCallback;
527         break;
528 
529       case HAL_I2S_RX_COMPLETE_CB_ID :
530         hi2s->RxCpltCallback = pCallback;
531         break;
532 
533       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
534         hi2s->TxHalfCpltCallback = pCallback;
535         break;
536 
537       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
538         hi2s->RxHalfCpltCallback = pCallback;
539         break;
540 
541       case HAL_I2S_ERROR_CB_ID :
542         hi2s->ErrorCallback = pCallback;
543         break;
544 
545       case HAL_I2S_MSPINIT_CB_ID :
546         hi2s->MspInitCallback = pCallback;
547         break;
548 
549       case HAL_I2S_MSPDEINIT_CB_ID :
550         hi2s->MspDeInitCallback = pCallback;
551         break;
552 
553       default :
554         /* Update the error code */
555         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
556 
557         /* Return error status */
558         status =  HAL_ERROR;
559         break;
560     }
561   }
562   else if (HAL_I2S_STATE_RESET == hi2s->State)
563   {
564     switch (CallbackID)
565     {
566       case HAL_I2S_MSPINIT_CB_ID :
567         hi2s->MspInitCallback = pCallback;
568         break;
569 
570       case HAL_I2S_MSPDEINIT_CB_ID :
571         hi2s->MspDeInitCallback = pCallback;
572         break;
573 
574       default :
575         /* Update the error code */
576         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
577 
578         /* Return error status */
579         status =  HAL_ERROR;
580         break;
581     }
582   }
583   else
584   {
585     /* Update the error code */
586     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
587 
588     /* Return error status */
589     status =  HAL_ERROR;
590   }
591 
592   /* Release Lock */
593   __HAL_UNLOCK(hi2s);
594   return status;
595 }
596 
597 /**
598   * @brief  Unregister an I2S Callback
599   *         I2S callback is redirected to the weak predefined callback
600   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
601   *                the configuration information for the specified I2S.
602   * @param  CallbackID ID of the callback to be unregistered
603   * @retval HAL status
604   */
HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef * hi2s,HAL_I2S_CallbackIDTypeDef CallbackID)605 HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
606 {
607   HAL_StatusTypeDef status = HAL_OK;
608 
609   /* Process locked */
610   __HAL_LOCK(hi2s);
611 
612   if (HAL_I2S_STATE_READY == hi2s->State)
613   {
614     switch (CallbackID)
615     {
616       case HAL_I2S_TX_COMPLETE_CB_ID :
617         hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback;                /* Legacy weak TxCpltCallback       */
618         break;
619 
620       case HAL_I2S_RX_COMPLETE_CB_ID :
621         hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback;                /* Legacy weak RxCpltCallback       */
622         break;
623 
624       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
625         hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback   */
626         break;
627 
628       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
629         hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback   */
630         break;
631 
632       case HAL_I2S_ERROR_CB_ID :
633         hi2s->ErrorCallback = HAL_I2S_ErrorCallback;                  /* Legacy weak ErrorCallback        */
634         break;
635 
636       case HAL_I2S_MSPINIT_CB_ID :
637         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
638         break;
639 
640       case HAL_I2S_MSPDEINIT_CB_ID :
641         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
642         break;
643 
644       default :
645         /* Update the error code */
646         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
647 
648         /* Return error status */
649         status =  HAL_ERROR;
650         break;
651     }
652   }
653   else if (HAL_I2S_STATE_RESET == hi2s->State)
654   {
655     switch (CallbackID)
656     {
657       case HAL_I2S_MSPINIT_CB_ID :
658         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
659         break;
660 
661       case HAL_I2S_MSPDEINIT_CB_ID :
662         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
663         break;
664 
665       default :
666         /* Update the error code */
667         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
668 
669         /* Return error status */
670         status =  HAL_ERROR;
671         break;
672     }
673   }
674   else
675   {
676     /* Update the error code */
677     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
678 
679     /* Return error status */
680     status =  HAL_ERROR;
681   }
682 
683   /* Release Lock */
684   __HAL_UNLOCK(hi2s);
685   return status;
686 }
687 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
688 /**
689   * @}
690   */
691 
692 /** @defgroup I2S_Exported_Functions_Group2 IO operation functions
693   *  @brief Data transfers functions
694   *
695 @verbatim
696  ===============================================================================
697                       ##### IO operation functions #####
698  ===============================================================================
699     [..]
700     This subsection provides a set of functions allowing to manage the I2S data
701     transfers.
702 
703     (#) There are two modes of transfer:
704        (++) Blocking mode : The communication is performed in the polling mode.
705             The status of all data processing is returned by the same function
706             after finishing transfer.
707        (++) No-Blocking mode : The communication is performed using Interrupts
708             or DMA. These functions return the status of the transfer startup.
709             The end of the data processing will be indicated through the
710             dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
711             using DMA mode.
712 
713     (#) Blocking mode functions are :
714         (++) HAL_I2S_Transmit()
715         (++) HAL_I2S_Receive()
716 
717     (#) No-Blocking mode functions with Interrupt are :
718         (++) HAL_I2S_Transmit_IT()
719         (++) HAL_I2S_Receive_IT()
720 
721     (#) No-Blocking mode functions with DMA are :
722         (++) HAL_I2S_Transmit_DMA()
723         (++) HAL_I2S_Receive_DMA()
724 
725     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
726         (++) HAL_I2S_TxCpltCallback()
727         (++) HAL_I2S_RxCpltCallback()
728         (++) HAL_I2S_ErrorCallback()
729 
730 @endverbatim
731   * @{
732   */
733 
734 /**
735   * @brief  Transmit an amount of data in blocking mode
736   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
737   *         the configuration information for I2S module
738   * @param  pData a 16-bit pointer to data buffer.
739   * @param  Size number of data sample to be sent:
740   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
741   *         configuration phase, the Size parameter means the number of 16-bit data length
742   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
743   *         the Size parameter means the number of 24-bit or 32-bit data length.
744   * @param  Timeout Timeout duration
745   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
746   *         between Master and Slave(example: audio streaming).
747   * @retval HAL status
748   */
HAL_I2S_Transmit(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)749 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
750 {
751   uint32_t tmpreg_cfgr;
752 
753   if ((pData == NULL) || (Size == 0U))
754   {
755     return  HAL_ERROR;
756   }
757 
758   /* Process Locked */
759   __HAL_LOCK(hi2s);
760 
761   if (hi2s->State != HAL_I2S_STATE_READY)
762   {
763     __HAL_UNLOCK(hi2s);
764     return HAL_BUSY;
765   }
766 
767   /* Set state and reset error code */
768   hi2s->State = HAL_I2S_STATE_BUSY_TX;
769   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
770   hi2s->pTxBuffPtr = pData;
771 
772   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
773 
774   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
775   {
776     hi2s->TxXferSize = (Size << 1U);
777     hi2s->TxXferCount = (Size << 1U);
778   }
779   else
780   {
781     hi2s->TxXferSize = Size;
782     hi2s->TxXferCount = Size;
783   }
784 
785   tmpreg_cfgr = hi2s->Instance->I2SCFGR;
786 
787   /* Check if the I2S is already enabled */
788   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
789   {
790     /* Enable I2S peripheral */
791     __HAL_I2S_ENABLE(hi2s);
792   }
793 
794   /* Wait until TXE flag is set */
795   if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
796   {
797     /* Set the error code */
798     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
799     hi2s->State = HAL_I2S_STATE_READY;
800     __HAL_UNLOCK(hi2s);
801     return HAL_ERROR;
802   }
803 
804   while (hi2s->TxXferCount > 0U)
805   {
806     hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
807     hi2s->pTxBuffPtr++;
808     hi2s->TxXferCount--;
809 
810     /* Wait until TXE flag is set */
811     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
812     {
813       /* Set the error code */
814       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
815       hi2s->State = HAL_I2S_STATE_READY;
816       __HAL_UNLOCK(hi2s);
817       return HAL_ERROR;
818     }
819 
820     /* Check if an underrun occurs */
821     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
822     {
823       /* Clear underrun flag */
824       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
825 
826       /* Set the error code */
827       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
828     }
829   }
830 
831   /* Check if Slave mode is selected */
832   if (((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)
833       || ((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX))
834   {
835     /* Wait until Busy flag is reset */
836     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK)
837     {
838       /* Set the error code */
839       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
840       hi2s->State = HAL_I2S_STATE_READY;
841       __HAL_UNLOCK(hi2s);
842       return HAL_ERROR;
843     }
844   }
845 
846   hi2s->State = HAL_I2S_STATE_READY;
847   __HAL_UNLOCK(hi2s);
848   return HAL_OK;
849 }
850 
851 /**
852   * @brief  Receive an amount of data in blocking mode
853   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
854   *         the configuration information for I2S module
855   * @param  pData a 16-bit pointer to data buffer.
856   * @param  Size number of data sample to be sent:
857   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
858   *         configuration phase, the Size parameter means the number of 16-bit data length
859   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
860   *         the Size parameter means the number of 24-bit or 32-bit data length.
861   * @param  Timeout Timeout duration
862   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
863   *         between Master and Slave(example: audio streaming).
864   * @note   In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
865   *         in continuous way and as the I2S is not disabled at the end of the I2S transaction.
866   * @retval HAL status
867   */
HAL_I2S_Receive(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)868 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
869 {
870   uint32_t tmpreg_cfgr;
871 
872   if ((pData == NULL) || (Size == 0U))
873   {
874     return  HAL_ERROR;
875   }
876 
877   /* Process Locked */
878   __HAL_LOCK(hi2s);
879 
880   if (hi2s->State != HAL_I2S_STATE_READY)
881   {
882     __HAL_UNLOCK(hi2s);
883     return HAL_BUSY;
884   }
885 
886   /* Set state and reset error code */
887   hi2s->State = HAL_I2S_STATE_BUSY_RX;
888   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
889   hi2s->pRxBuffPtr = pData;
890 
891   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
892 
893   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
894   {
895     hi2s->RxXferSize = (Size << 1U);
896     hi2s->RxXferCount = (Size << 1U);
897   }
898   else
899   {
900     hi2s->RxXferSize = Size;
901     hi2s->RxXferCount = Size;
902   }
903 
904   /* Check if the I2S is already enabled */
905   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
906   {
907     /* Enable I2S peripheral */
908     __HAL_I2S_ENABLE(hi2s);
909   }
910 
911   /* Check if Master Receiver mode is selected */
912   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
913   {
914     /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
915     access to the SPI_SR register. */
916     __HAL_I2S_CLEAR_OVRFLAG(hi2s);
917   }
918 
919   /* Receive data */
920   while (hi2s->RxXferCount > 0U)
921   {
922     /* Wait until RXNE flag is set */
923     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
924     {
925       /* Set the error code */
926       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
927       hi2s->State = HAL_I2S_STATE_READY;
928       __HAL_UNLOCK(hi2s);
929       return HAL_ERROR;
930     }
931 
932     (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
933     hi2s->pRxBuffPtr++;
934     hi2s->RxXferCount--;
935 
936     /* Check if an overrun occurs */
937     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
938     {
939       /* Clear overrun flag */
940       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
941 
942       /* Set the error code */
943       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
944     }
945   }
946 
947   hi2s->State = HAL_I2S_STATE_READY;
948   __HAL_UNLOCK(hi2s);
949   return HAL_OK;
950 }
951 
952 /**
953   * @brief  Transmit an amount of data in non-blocking mode with Interrupt
954   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
955   *         the configuration information for I2S module
956   * @param  pData a 16-bit pointer to data buffer.
957   * @param  Size number of data sample to be sent:
958   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
959   *         configuration phase, the Size parameter means the number of 16-bit data length
960   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
961   *         the Size parameter means the number of 24-bit or 32-bit data length.
962   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
963   *         between Master and Slave(example: audio streaming).
964   * @retval HAL status
965   */
HAL_I2S_Transmit_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)966 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
967 {
968   uint32_t tmpreg_cfgr;
969 
970   if ((pData == NULL) || (Size == 0U))
971   {
972     return  HAL_ERROR;
973   }
974 
975   /* Process Locked */
976   __HAL_LOCK(hi2s);
977 
978   if (hi2s->State != HAL_I2S_STATE_READY)
979   {
980     __HAL_UNLOCK(hi2s);
981     return HAL_BUSY;
982   }
983 
984   /* Set state and reset error code */
985   hi2s->State = HAL_I2S_STATE_BUSY_TX;
986   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
987   hi2s->pTxBuffPtr = pData;
988 
989   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
990 
991   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
992   {
993     hi2s->TxXferSize = (Size << 1U);
994     hi2s->TxXferCount = (Size << 1U);
995   }
996   else
997   {
998     hi2s->TxXferSize = Size;
999     hi2s->TxXferCount = Size;
1000   }
1001 
1002   /* Enable TXE and ERR interrupt */
1003   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1004 
1005   /* Check if the I2S is already enabled */
1006   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1007   {
1008     /* Enable I2S peripheral */
1009     __HAL_I2S_ENABLE(hi2s);
1010   }
1011 
1012   __HAL_UNLOCK(hi2s);
1013   return HAL_OK;
1014 }
1015 
1016 /**
1017   * @brief  Receive an amount of data in non-blocking mode with Interrupt
1018   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1019   *         the configuration information for I2S module
1020   * @param  pData a 16-bit pointer to the Receive data buffer.
1021   * @param  Size number of data sample to be sent:
1022   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1023   *         configuration phase, the Size parameter means the number of 16-bit data length
1024   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1025   *         the Size parameter means the number of 24-bit or 32-bit data length.
1026   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1027   *         between Master and Slave(example: audio streaming).
1028   * @note   It is recommended to use DMA for the I2S receiver to avoid de-synchronization
1029   * between Master and Slave otherwise the I2S interrupt should be optimized.
1030   * @retval HAL status
1031   */
HAL_I2S_Receive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1032 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1033 {
1034   uint32_t tmpreg_cfgr;
1035 
1036   if ((pData == NULL) || (Size == 0U))
1037   {
1038     return  HAL_ERROR;
1039   }
1040 
1041   /* Process Locked */
1042   __HAL_LOCK(hi2s);
1043 
1044   if (hi2s->State != HAL_I2S_STATE_READY)
1045   {
1046     __HAL_UNLOCK(hi2s);
1047     return HAL_BUSY;
1048   }
1049 
1050   /* Set state and reset error code */
1051   hi2s->State = HAL_I2S_STATE_BUSY_RX;
1052   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1053   hi2s->pRxBuffPtr = pData;
1054 
1055   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1056 
1057   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1058   {
1059     hi2s->RxXferSize = (Size << 1U);
1060     hi2s->RxXferCount = (Size << 1U);
1061   }
1062   else
1063   {
1064     hi2s->RxXferSize = Size;
1065     hi2s->RxXferCount = Size;
1066   }
1067 
1068   /* Enable RXNE and ERR interrupt */
1069   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1070 
1071   /* Check if the I2S is already enabled */
1072   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1073   {
1074     /* Enable I2S peripheral */
1075     __HAL_I2S_ENABLE(hi2s);
1076   }
1077 
1078   __HAL_UNLOCK(hi2s);
1079   return HAL_OK;
1080 }
1081 
1082 /**
1083   * @brief  Transmit an amount of data in non-blocking mode with DMA
1084   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1085   *         the configuration information for I2S module
1086   * @param  pData a 16-bit pointer to the Transmit data buffer.
1087   * @param  Size number of data sample to be sent:
1088   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1089   *         configuration phase, the Size parameter means the number of 16-bit data length
1090   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1091   *         the Size parameter means the number of 24-bit or 32-bit data length.
1092   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1093   *         between Master and Slave(example: audio streaming).
1094   * @retval HAL status
1095   */
HAL_I2S_Transmit_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1096 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1097 {
1098   uint32_t tmpreg_cfgr;
1099 
1100   if ((pData == NULL) || (Size == 0U))
1101   {
1102     return  HAL_ERROR;
1103   }
1104 
1105   /* Process Locked */
1106   __HAL_LOCK(hi2s);
1107 
1108   if (hi2s->State != HAL_I2S_STATE_READY)
1109   {
1110     __HAL_UNLOCK(hi2s);
1111     return HAL_BUSY;
1112   }
1113 
1114   /* Set state and reset error code */
1115   hi2s->State = HAL_I2S_STATE_BUSY_TX;
1116   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1117   hi2s->pTxBuffPtr = pData;
1118 
1119   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1120 
1121   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1122   {
1123     hi2s->TxXferSize = (Size << 1U);
1124     hi2s->TxXferCount = (Size << 1U);
1125   }
1126   else
1127   {
1128     hi2s->TxXferSize = Size;
1129     hi2s->TxXferCount = Size;
1130   }
1131 
1132   /* Set the I2S Tx DMA Half transfer complete callback */
1133   hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
1134 
1135   /* Set the I2S Tx DMA transfer complete callback */
1136   hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
1137 
1138   /* Set the DMA error callback */
1139   hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
1140 
1141   /* Enable the Tx DMA Stream/Channel */
1142   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx,
1143                                  (uint32_t)hi2s->pTxBuffPtr,
1144                                  (uint32_t)&hi2s->Instance->DR,
1145                                  hi2s->TxXferSize))
1146   {
1147     /* Update SPI error code */
1148     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1149     hi2s->State = HAL_I2S_STATE_READY;
1150 
1151     __HAL_UNLOCK(hi2s);
1152     return HAL_ERROR;
1153   }
1154 
1155   /* Check if the I2S is already enabled */
1156   if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1157   {
1158     /* Enable I2S peripheral */
1159     __HAL_I2S_ENABLE(hi2s);
1160   }
1161 
1162   /* Check if the I2S Tx request is already enabled */
1163   if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN))
1164   {
1165     /* Enable Tx DMA Request */
1166     SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1167   }
1168 
1169   __HAL_UNLOCK(hi2s);
1170   return HAL_OK;
1171 }
1172 
1173 /**
1174   * @brief  Receive an amount of data in non-blocking mode with DMA
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 the Receive 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 24-bit or 32-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_Receive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1187 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1188 {
1189   uint32_t tmpreg_cfgr;
1190 
1191   if ((pData == NULL) || (Size == 0U))
1192   {
1193     return  HAL_ERROR;
1194   }
1195 
1196   /* Process Locked */
1197   __HAL_LOCK(hi2s);
1198 
1199   if (hi2s->State != HAL_I2S_STATE_READY)
1200   {
1201     __HAL_UNLOCK(hi2s);
1202     return HAL_BUSY;
1203   }
1204 
1205   /* Set state and reset error code */
1206   hi2s->State = HAL_I2S_STATE_BUSY_RX;
1207   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1208   hi2s->pRxBuffPtr = pData;
1209 
1210   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1211 
1212   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1213   {
1214     hi2s->RxXferSize = (Size << 1U);
1215     hi2s->RxXferCount = (Size << 1U);
1216   }
1217   else
1218   {
1219     hi2s->RxXferSize = Size;
1220     hi2s->RxXferCount = Size;
1221   }
1222 
1223   /* Set the I2S Rx DMA Half transfer complete callback */
1224   hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
1225 
1226   /* Set the I2S Rx DMA transfer complete callback */
1227   hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
1228 
1229   /* Set the DMA error callback */
1230   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1231 
1232   /* Check if Master Receiver mode is selected */
1233   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
1234   {
1235     /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
1236     access to the SPI_SR register. */
1237     __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1238   }
1239 
1240   /* Enable the Rx DMA Stream/Channel */
1241   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr,
1242                                  hi2s->RxXferSize))
1243   {
1244     /* Update SPI error code */
1245     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1246     hi2s->State = HAL_I2S_STATE_READY;
1247 
1248     __HAL_UNLOCK(hi2s);
1249     return HAL_ERROR;
1250   }
1251 
1252   /* Check if the I2S is already enabled */
1253   if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1254   {
1255     /* Enable I2S peripheral */
1256     __HAL_I2S_ENABLE(hi2s);
1257   }
1258 
1259   /* Check if the I2S Rx request is already enabled */
1260   if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN))
1261   {
1262     /* Enable Rx DMA Request */
1263     SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1264   }
1265 
1266   __HAL_UNLOCK(hi2s);
1267   return HAL_OK;
1268 }
1269 
1270 /**
1271   * @brief  Pauses the audio DMA Stream/Channel playing from the Media.
1272   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1273   *         the configuration information for I2S module
1274   * @retval HAL status
1275   */
HAL_I2S_DMAPause(I2S_HandleTypeDef * hi2s)1276 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1277 {
1278   /* Process Locked */
1279   __HAL_LOCK(hi2s);
1280 
1281   if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1282   {
1283     /* Disable the I2S DMA Tx request */
1284     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1285   }
1286   else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1287   {
1288     /* Disable the I2S DMA Rx request */
1289     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1290   }
1291   else
1292   {
1293     /* nothing to do */
1294   }
1295 
1296   /* Process Unlocked */
1297   __HAL_UNLOCK(hi2s);
1298 
1299   return HAL_OK;
1300 }
1301 
1302 /**
1303   * @brief  Resumes the audio DMA Stream/Channel playing from the Media.
1304   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1305   *         the configuration information for I2S module
1306   * @retval HAL status
1307   */
HAL_I2S_DMAResume(I2S_HandleTypeDef * hi2s)1308 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1309 {
1310   /* Process Locked */
1311   __HAL_LOCK(hi2s);
1312 
1313   if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1314   {
1315     /* Enable the I2S DMA Tx request */
1316     SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1317   }
1318   else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1319   {
1320     /* Enable the I2S DMA Rx request */
1321     SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1322   }
1323   else
1324   {
1325     /* nothing to do */
1326   }
1327 
1328   /* If the I2S peripheral is still not enabled, enable it */
1329   if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1330   {
1331     /* Enable I2S peripheral */
1332     __HAL_I2S_ENABLE(hi2s);
1333   }
1334 
1335   /* Process Unlocked */
1336   __HAL_UNLOCK(hi2s);
1337 
1338   return HAL_OK;
1339 }
1340 
1341 /**
1342   * @brief  Stops the audio DMA Stream/Channel playing from the Media.
1343   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1344   *         the configuration information for I2S module
1345   * @retval HAL status
1346   */
HAL_I2S_DMAStop(I2S_HandleTypeDef * hi2s)1347 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1348 {
1349   HAL_StatusTypeDef errorcode = HAL_OK;
1350   /* The Lock is not implemented on this API to allow the user application
1351      to call the HAL SPI API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1352      when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1353      and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1354      */
1355 
1356   if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
1357   {
1358     /* Abort the I2S DMA tx Stream/Channel */
1359     if (hi2s->hdmatx != NULL)
1360     {
1361       /* Disable the I2S DMA tx Stream/Channel */
1362       if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1363       {
1364         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1365         errorcode = HAL_ERROR;
1366       }
1367     }
1368 
1369     /* Wait until TXE flag is set */
1370     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, I2S_TIMEOUT_FLAG) != HAL_OK)
1371     {
1372       /* Set the error code */
1373       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1374       hi2s->State = HAL_I2S_STATE_READY;
1375       errorcode   = HAL_ERROR;
1376     }
1377 
1378     /* Wait until BSY flag is Reset */
1379     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, I2S_TIMEOUT_FLAG) != HAL_OK)
1380     {
1381       /* Set the error code */
1382       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1383       hi2s->State = HAL_I2S_STATE_READY;
1384       errorcode   = HAL_ERROR;
1385     }
1386 
1387     /* Disable I2S peripheral */
1388     __HAL_I2S_DISABLE(hi2s);
1389 
1390     /* Clear UDR flag */
1391     __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1392 
1393     /* Disable the I2S Tx DMA requests */
1394     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1395 
1396   }
1397 
1398   else if ((hi2s->Init.Mode == I2S_MODE_MASTER_RX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_RX))
1399   {
1400     /* Abort the I2S DMA rx Stream/Channel */
1401     if (hi2s->hdmarx != NULL)
1402     {
1403       /* Disable the I2S DMA rx Stream/Channel */
1404       if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1405       {
1406         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1407         errorcode = HAL_ERROR;
1408       }
1409     }
1410 
1411     /* Disable I2S peripheral */
1412     __HAL_I2S_DISABLE(hi2s);
1413 
1414     /* Clear OVR flag */
1415     __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1416 
1417     /* Disable the I2S Rx DMA request */
1418     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1419 
1420     if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
1421     {
1422       /* Set the error code */
1423       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_BUSY_LINE_RX);
1424 
1425       /* Set the I2S State ready */
1426       hi2s->State = HAL_I2S_STATE_READY;
1427       errorcode = HAL_ERROR;
1428     }
1429     else
1430     {
1431       /* Read DR to Flush RX Data */
1432       READ_REG((hi2s->Instance)->DR);
1433     }
1434   }
1435 
1436   hi2s->State = HAL_I2S_STATE_READY;
1437 
1438   return errorcode;
1439 }
1440 
1441 /**
1442   * @brief  This function handles I2S interrupt request.
1443   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1444   *         the configuration information for I2S module
1445   * @retval None
1446   */
HAL_I2S_IRQHandler(I2S_HandleTypeDef * hi2s)1447 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1448 {
1449   uint32_t itsource = hi2s->Instance->CR2;
1450   uint32_t itflag   = hi2s->Instance->SR;
1451 
1452   /* I2S in mode Receiver ------------------------------------------------*/
1453   if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) == RESET) &&
1454       (I2S_CHECK_FLAG(itflag, I2S_FLAG_RXNE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_RXNE) != RESET))
1455   {
1456     I2S_Receive_IT(hi2s);
1457     return;
1458   }
1459 
1460   /* I2S in mode Tramitter -----------------------------------------------*/
1461   if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_TXE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_TXE) != RESET))
1462   {
1463     I2S_Transmit_IT(hi2s);
1464     return;
1465   }
1466 
1467   /* I2S interrupt error -------------------------------------------------*/
1468   if (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_ERR) != RESET)
1469   {
1470     /* I2S Overrun error interrupt occurred ---------------------------------*/
1471     if (I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) != RESET)
1472     {
1473       /* Disable RXNE and ERR interrupt */
1474       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1475 
1476       /* Set the error code and execute error callback*/
1477       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1478     }
1479 
1480     /* I2S Underrun error interrupt occurred --------------------------------*/
1481     if (I2S_CHECK_FLAG(itflag, I2S_FLAG_UDR) != RESET)
1482     {
1483       /* Disable TXE and ERR interrupt */
1484       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1485 
1486       /* Set the error code and execute error callback*/
1487       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1488     }
1489 
1490     /* Set the I2S State ready */
1491     hi2s->State = HAL_I2S_STATE_READY;
1492 
1493     /* Call user error callback */
1494 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1495     hi2s->ErrorCallback(hi2s);
1496 #else
1497     HAL_I2S_ErrorCallback(hi2s);
1498 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1499   }
1500 }
1501 
1502 /**
1503   * @brief  Tx Transfer Half completed callbacks
1504   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1505   *         the configuration information for I2S module
1506   * @retval None
1507   */
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1508 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1509 {
1510   /* Prevent unused argument(s) compilation warning */
1511   UNUSED(hi2s);
1512 
1513   /* NOTE : This function Should not be modified, when the callback is needed,
1514             the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1515    */
1516 }
1517 
1518 /**
1519   * @brief  Tx Transfer completed callbacks
1520   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1521   *         the configuration information for I2S module
1522   * @retval None
1523   */
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef * hi2s)1524 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
1525 {
1526   /* Prevent unused argument(s) compilation warning */
1527   UNUSED(hi2s);
1528 
1529   /* NOTE : This function Should not be modified, when the callback is needed,
1530             the HAL_I2S_TxCpltCallback could be implemented in the user file
1531    */
1532 }
1533 
1534 /**
1535   * @brief  Rx Transfer half completed callbacks
1536   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1537   *         the configuration information for I2S module
1538   * @retval None
1539   */
HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1540 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1541 {
1542   /* Prevent unused argument(s) compilation warning */
1543   UNUSED(hi2s);
1544 
1545   /* NOTE : This function Should not be modified, when the callback is needed,
1546             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
1547    */
1548 }
1549 
1550 /**
1551   * @brief  Rx Transfer completed callbacks
1552   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1553   *         the configuration information for I2S module
1554   * @retval None
1555   */
HAL_I2S_RxCpltCallback(I2S_HandleTypeDef * hi2s)1556 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1557 {
1558   /* Prevent unused argument(s) compilation warning */
1559   UNUSED(hi2s);
1560 
1561   /* NOTE : This function Should not be modified, when the callback is needed,
1562             the HAL_I2S_RxCpltCallback could be implemented in the user file
1563    */
1564 }
1565 
1566 /**
1567   * @brief  I2S error callbacks
1568   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1569   *         the configuration information for I2S module
1570   * @retval None
1571   */
HAL_I2S_ErrorCallback(I2S_HandleTypeDef * hi2s)1572 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
1573 {
1574   /* Prevent unused argument(s) compilation warning */
1575   UNUSED(hi2s);
1576 
1577   /* NOTE : This function Should not be modified, when the callback is needed,
1578             the HAL_I2S_ErrorCallback could be implemented in the user file
1579    */
1580 }
1581 
1582 /**
1583   * @}
1584   */
1585 
1586 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1587   *  @brief   Peripheral State functions
1588   *
1589 @verbatim
1590  ===============================================================================
1591                       ##### Peripheral State and Errors functions #####
1592  ===============================================================================
1593     [..]
1594     This subsection permits to get in run-time the status of the peripheral
1595     and the data flow.
1596 
1597 @endverbatim
1598   * @{
1599   */
1600 
1601 /**
1602   * @brief  Return the I2S state
1603   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1604   *         the configuration information for I2S module
1605   * @retval HAL state
1606   */
HAL_I2S_GetState(I2S_HandleTypeDef * hi2s)1607 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1608 {
1609   return hi2s->State;
1610 }
1611 
1612 /**
1613   * @brief  Return the I2S error code
1614   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1615   *         the configuration information for I2S module
1616   * @retval I2S Error Code
1617   */
HAL_I2S_GetError(I2S_HandleTypeDef * hi2s)1618 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1619 {
1620   return hi2s->ErrorCode;
1621 }
1622 /**
1623   * @}
1624   */
1625 
1626 /**
1627   * @}
1628   */
1629 
1630 /** @addtogroup I2S_Private_Functions I2S Private Functions
1631   * @{
1632   */
1633 /**
1634   * @brief  DMA I2S transmit process complete callback
1635   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1636   *                the configuration information for the specified DMA module.
1637   * @retval None
1638   */
I2S_DMATxCplt(DMA_HandleTypeDef * hdma)1639 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1640 {
1641   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1642 
1643   /* if DMA is configured in DMA_NORMAL Mode */
1644   if (hdma->Init.Mode == DMA_NORMAL)
1645   {
1646     /* Disable Tx DMA Request */
1647     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1648 
1649     hi2s->TxXferCount = 0U;
1650     hi2s->State = HAL_I2S_STATE_READY;
1651   }
1652   /* Call user Tx complete callback */
1653 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1654   hi2s->TxCpltCallback(hi2s);
1655 #else
1656   HAL_I2S_TxCpltCallback(hi2s);
1657 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1658 }
1659 
1660 /**
1661   * @brief  DMA I2S transmit process half complete callback
1662   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1663   *                the configuration information for the specified DMA module.
1664   * @retval None
1665   */
I2S_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1666 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1667 {
1668   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1669 
1670   /* Call user Tx half complete callback */
1671 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1672   hi2s->TxHalfCpltCallback(hi2s);
1673 #else
1674   HAL_I2S_TxHalfCpltCallback(hi2s);
1675 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1676 }
1677 
1678 /**
1679   * @brief  DMA I2S receive process complete callback
1680   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1681   *                the configuration information for the specified DMA module.
1682   * @retval None
1683   */
I2S_DMARxCplt(DMA_HandleTypeDef * hdma)1684 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1685 {
1686   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1687 
1688   /* if DMA is configured in DMA_NORMAL Mode */
1689   if (hdma->Init.Mode == DMA_NORMAL)
1690   {
1691     /* Disable Rx DMA Request */
1692     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1693     hi2s->RxXferCount = 0U;
1694     hi2s->State = HAL_I2S_STATE_READY;
1695   }
1696   /* Call user Rx complete callback */
1697 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1698   hi2s->RxCpltCallback(hi2s);
1699 #else
1700   HAL_I2S_RxCpltCallback(hi2s);
1701 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1702 }
1703 
1704 /**
1705   * @brief  DMA I2S receive process half complete callback
1706   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1707   *                the configuration information for the specified DMA module.
1708   * @retval None
1709   */
I2S_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1710 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1711 {
1712   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1713 
1714   /* Call user Rx half complete callback */
1715 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1716   hi2s->RxHalfCpltCallback(hi2s);
1717 #else
1718   HAL_I2S_RxHalfCpltCallback(hi2s);
1719 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1720 }
1721 
1722 /**
1723   * @brief  DMA I2S communication error callback
1724   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1725   *                the configuration information for the specified DMA module.
1726   * @retval None
1727   */
I2S_DMAError(DMA_HandleTypeDef * hdma)1728 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1729 {
1730   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1731 
1732   /* Disable Rx and Tx DMA Request */
1733   CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1734   hi2s->TxXferCount = 0U;
1735   hi2s->RxXferCount = 0U;
1736 
1737   hi2s->State = HAL_I2S_STATE_READY;
1738 
1739   /* Set the error code and execute error callback*/
1740   SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1741   /* Call user error callback */
1742 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1743   hi2s->ErrorCallback(hi2s);
1744 #else
1745   HAL_I2S_ErrorCallback(hi2s);
1746 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1747 }
1748 
1749 /**
1750   * @brief  Transmit an amount of data in non-blocking mode with Interrupt
1751   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1752   *         the configuration information for I2S module
1753   * @retval None
1754   */
I2S_Transmit_IT(I2S_HandleTypeDef * hi2s)1755 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
1756 {
1757   /* Transmit data */
1758   hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
1759   hi2s->pTxBuffPtr++;
1760   hi2s->TxXferCount--;
1761 
1762   if (hi2s->TxXferCount == 0U)
1763   {
1764     /* Disable TXE and ERR interrupt */
1765     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1766 
1767     hi2s->State = HAL_I2S_STATE_READY;
1768     /* Call user Tx complete callback */
1769 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1770     hi2s->TxCpltCallback(hi2s);
1771 #else
1772     HAL_I2S_TxCpltCallback(hi2s);
1773 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1774   }
1775 }
1776 
1777 /**
1778   * @brief  Receive an amount of data in non-blocking mode with Interrupt
1779   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1780   *         the configuration information for I2S module
1781   * @retval None
1782   */
I2S_Receive_IT(I2S_HandleTypeDef * hi2s)1783 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
1784 {
1785   /* Receive data */
1786   (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
1787   hi2s->pRxBuffPtr++;
1788   hi2s->RxXferCount--;
1789 
1790   if (hi2s->RxXferCount == 0U)
1791   {
1792     /* Disable RXNE and ERR interrupt */
1793     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1794 
1795     hi2s->State = HAL_I2S_STATE_READY;
1796     /* Call user Rx complete callback */
1797 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1798     hi2s->RxCpltCallback(hi2s);
1799 #else
1800     HAL_I2S_RxCpltCallback(hi2s);
1801 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1802   }
1803 }
1804 
1805 /**
1806   * @brief  This function handles I2S Communication Timeout.
1807   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1808   *         the configuration information for I2S module
1809   * @param  Flag Flag checked
1810   * @param  State Value of the flag expected
1811   * @param  Timeout Duration of the timeout
1812   * @retval HAL status
1813   */
I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,FlagStatus State,uint32_t Timeout)1814 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
1815                                                        uint32_t Timeout)
1816 {
1817   uint32_t tickstart;
1818 
1819   /* Get tick */
1820   tickstart = HAL_GetTick();
1821 
1822   /* Wait until flag is set to status*/
1823   while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1824   {
1825     if (Timeout != HAL_MAX_DELAY)
1826     {
1827       if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
1828       {
1829         /* Set the I2S State ready */
1830         hi2s->State = HAL_I2S_STATE_READY;
1831 
1832         /* Process Unlocked */
1833         __HAL_UNLOCK(hi2s);
1834 
1835         return HAL_TIMEOUT;
1836       }
1837     }
1838   }
1839   return HAL_OK;
1840 }
1841 
1842 /**
1843   * @}
1844   */
1845 
1846 /**
1847   * @}
1848   */
1849 
1850 /**
1851   * @}
1852   */
1853 #endif /* SPI_I2S_SUPPORT */
1854 
1855 #endif /* HAL_I2S_MODULE_ENABLED */
1856 
1857