1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_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 HSE_VALUE in the stm32l0xx_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 "stm32l0xx_hal.h"
185 
186 #ifdef HAL_I2S_MODULE_ENABLED
187 
188 #if defined(SPI_I2S_SUPPORT)
189 /** @addtogroup STM32L0xx_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   * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
748   * @retval HAL status
749   */
HAL_I2S_Transmit(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)750 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
751 {
752   uint32_t tmpreg_cfgr;
753 
754   if ((pData == NULL) || (Size == 0U))
755   {
756     return  HAL_ERROR;
757   }
758 
759   /* Process Locked */
760   __HAL_LOCK(hi2s);
761 
762   if (hi2s->State != HAL_I2S_STATE_READY)
763   {
764     __HAL_UNLOCK(hi2s);
765     return HAL_BUSY;
766   }
767 
768   /* Set state and reset error code */
769   hi2s->State = HAL_I2S_STATE_BUSY_TX;
770   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
771   hi2s->pTxBuffPtr = pData;
772 
773   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
774 
775   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
776   {
777     hi2s->TxXferSize = (Size << 1U);
778     hi2s->TxXferCount = (Size << 1U);
779   }
780   else
781   {
782     hi2s->TxXferSize = Size;
783     hi2s->TxXferCount = Size;
784   }
785 
786   tmpreg_cfgr = hi2s->Instance->I2SCFGR;
787 
788   /* Check if the I2S is already enabled */
789   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
790   {
791     /* Enable I2S peripheral */
792     __HAL_I2S_ENABLE(hi2s);
793   }
794 
795   /* Wait until TXE flag is set */
796   if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
797   {
798     /* Set the error code */
799     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
800     hi2s->State = HAL_I2S_STATE_READY;
801     __HAL_UNLOCK(hi2s);
802     return HAL_ERROR;
803   }
804 
805   while (hi2s->TxXferCount > 0U)
806   {
807     hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
808     hi2s->pTxBuffPtr++;
809     hi2s->TxXferCount--;
810 
811     /* Wait until TXE flag is set */
812     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
813     {
814       /* Set the error code */
815       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
816       hi2s->State = HAL_I2S_STATE_READY;
817       __HAL_UNLOCK(hi2s);
818       return HAL_ERROR;
819     }
820 
821     /* Check if an underrun occurs */
822     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
823     {
824       /* Clear underrun flag */
825       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
826 
827       /* Set the error code */
828       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
829     }
830   }
831 
832   /* Check if Slave mode is selected */
833   if (((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)
834       || ((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX))
835   {
836     /* Wait until Busy flag is reset */
837     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK)
838     {
839       /* Set the error code */
840       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
841       hi2s->State = HAL_I2S_STATE_READY;
842       __HAL_UNLOCK(hi2s);
843       return HAL_ERROR;
844     }
845   }
846 
847   hi2s->State = HAL_I2S_STATE_READY;
848   __HAL_UNLOCK(hi2s);
849   return HAL_OK;
850 }
851 
852 /**
853   * @brief  Receive an amount of data in blocking mode
854   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
855   *         the configuration information for I2S module
856   * @param  pData a 16-bit pointer to data buffer.
857   * @param  Size number of data sample to be sent:
858   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
859   *         configuration phase, the Size parameter means the number of 16-bit data length
860   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
861   *         the Size parameter means the number of 24-bit or 32-bit data length.
862   * @param  Timeout Timeout duration
863   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
864   *         between Master and Slave(example: audio streaming).
865   * @note   In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
866   *         in continuous way and as the I2S is not disabled at the end of the I2S transaction.
867   * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
868   * @retval HAL status
869   */
HAL_I2S_Receive(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)870 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
871 {
872   uint32_t tmpreg_cfgr;
873 
874   if ((pData == NULL) || (Size == 0U))
875   {
876     return  HAL_ERROR;
877   }
878 
879   /* Process Locked */
880   __HAL_LOCK(hi2s);
881 
882   if (hi2s->State != HAL_I2S_STATE_READY)
883   {
884     __HAL_UNLOCK(hi2s);
885     return HAL_BUSY;
886   }
887 
888   /* Set state and reset error code */
889   hi2s->State = HAL_I2S_STATE_BUSY_RX;
890   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
891   hi2s->pRxBuffPtr = pData;
892 
893   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
894 
895   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
896   {
897     hi2s->RxXferSize = (Size << 1U);
898     hi2s->RxXferCount = (Size << 1U);
899   }
900   else
901   {
902     hi2s->RxXferSize = Size;
903     hi2s->RxXferCount = Size;
904   }
905 
906   /* Check if the I2S is already enabled */
907   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
908   {
909     /* Enable I2S peripheral */
910     __HAL_I2S_ENABLE(hi2s);
911   }
912 
913   /* Check if Master Receiver mode is selected */
914   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
915   {
916     /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
917     access to the SPI_SR register. */
918     __HAL_I2S_CLEAR_OVRFLAG(hi2s);
919   }
920 
921   /* Receive data */
922   while (hi2s->RxXferCount > 0U)
923   {
924     /* Wait until RXNE flag is set */
925     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
926     {
927       /* Set the error code */
928       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
929       hi2s->State = HAL_I2S_STATE_READY;
930       __HAL_UNLOCK(hi2s);
931       return HAL_ERROR;
932     }
933 
934     (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
935     hi2s->pRxBuffPtr++;
936     hi2s->RxXferCount--;
937 
938     /* Check if an overrun occurs */
939     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
940     {
941       /* Clear overrun flag */
942       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
943 
944       /* Set the error code */
945       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
946     }
947   }
948 
949   hi2s->State = HAL_I2S_STATE_READY;
950   __HAL_UNLOCK(hi2s);
951   return HAL_OK;
952 }
953 
954 /**
955   * @brief  Transmit an amount of data in non-blocking mode with Interrupt
956   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
957   *         the configuration information for I2S module
958   * @param  pData a 16-bit pointer to data buffer.
959   * @param  Size number of data sample to be sent:
960   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
961   *         configuration phase, the Size parameter means the number of 16-bit data length
962   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
963   *         the Size parameter means the number of 24-bit or 32-bit data length.
964   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
965   *         between Master and Slave(example: audio streaming).
966   * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
967   * @retval HAL status
968   */
HAL_I2S_Transmit_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)969 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
970 {
971   uint32_t tmpreg_cfgr;
972 
973   if ((pData == NULL) || (Size == 0U))
974   {
975     return  HAL_ERROR;
976   }
977 
978   /* Process Locked */
979   __HAL_LOCK(hi2s);
980 
981   if (hi2s->State != HAL_I2S_STATE_READY)
982   {
983     __HAL_UNLOCK(hi2s);
984     return HAL_BUSY;
985   }
986 
987   /* Set state and reset error code */
988   hi2s->State = HAL_I2S_STATE_BUSY_TX;
989   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
990   hi2s->pTxBuffPtr = pData;
991 
992   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
993 
994   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
995   {
996     hi2s->TxXferSize = (Size << 1U);
997     hi2s->TxXferCount = (Size << 1U);
998   }
999   else
1000   {
1001     hi2s->TxXferSize = Size;
1002     hi2s->TxXferCount = Size;
1003   }
1004 
1005   /* Enable TXE and ERR interrupt */
1006   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1007 
1008   /* Check if the I2S is already enabled */
1009   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1010   {
1011     /* Enable I2S peripheral */
1012     __HAL_I2S_ENABLE(hi2s);
1013   }
1014 
1015   __HAL_UNLOCK(hi2s);
1016   return HAL_OK;
1017 }
1018 
1019 /**
1020   * @brief  Receive an amount of data in non-blocking mode with Interrupt
1021   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1022   *         the configuration information for I2S module
1023   * @param  pData a 16-bit pointer to the Receive data buffer.
1024   * @param  Size number of data sample to be sent:
1025   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1026   *         configuration phase, the Size parameter means the number of 16-bit data length
1027   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1028   *         the Size parameter means the number of 24-bit or 32-bit data length.
1029   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1030   *         between Master and Slave(example: audio streaming).
1031   * @note   It is recommended to use DMA for the I2S receiver to avoid de-synchronization
1032   * between Master and Slave otherwise the I2S interrupt should be optimized.
1033   * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
1034   * @retval HAL status
1035   */
HAL_I2S_Receive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1036 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1037 {
1038   uint32_t tmpreg_cfgr;
1039 
1040   if ((pData == NULL) || (Size == 0U))
1041   {
1042     return  HAL_ERROR;
1043   }
1044 
1045   /* Process Locked */
1046   __HAL_LOCK(hi2s);
1047 
1048   if (hi2s->State != HAL_I2S_STATE_READY)
1049   {
1050     __HAL_UNLOCK(hi2s);
1051     return HAL_BUSY;
1052   }
1053 
1054   /* Set state and reset error code */
1055   hi2s->State = HAL_I2S_STATE_BUSY_RX;
1056   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1057   hi2s->pRxBuffPtr = pData;
1058 
1059   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1060 
1061   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1062   {
1063     hi2s->RxXferSize = (Size << 1U);
1064     hi2s->RxXferCount = (Size << 1U);
1065   }
1066   else
1067   {
1068     hi2s->RxXferSize = Size;
1069     hi2s->RxXferCount = Size;
1070   }
1071 
1072   /* Enable RXNE and ERR interrupt */
1073   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1074 
1075   /* Check if the I2S is already enabled */
1076   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1077   {
1078     /* Enable I2S peripheral */
1079     __HAL_I2S_ENABLE(hi2s);
1080   }
1081 
1082   __HAL_UNLOCK(hi2s);
1083   return HAL_OK;
1084 }
1085 
1086 /**
1087   * @brief  Transmit an amount of data in non-blocking mode with DMA
1088   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1089   *         the configuration information for I2S module
1090   * @param  pData a 16-bit pointer to the Transmit data buffer.
1091   * @param  Size number of data sample to be sent:
1092   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1093   *         configuration phase, the Size parameter means the number of 16-bit data length
1094   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1095   *         the Size parameter means the number of 24-bit or 32-bit data length.
1096   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1097   *         between Master and Slave(example: audio streaming).
1098   * @retval HAL status
1099   */
HAL_I2S_Transmit_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1100 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1101 {
1102   uint32_t tmpreg_cfgr;
1103 
1104   if ((pData == NULL) || (Size == 0U))
1105   {
1106     return  HAL_ERROR;
1107   }
1108 
1109   /* Process Locked */
1110   __HAL_LOCK(hi2s);
1111 
1112   if (hi2s->State != HAL_I2S_STATE_READY)
1113   {
1114     __HAL_UNLOCK(hi2s);
1115     return HAL_BUSY;
1116   }
1117 
1118   /* Set state and reset error code */
1119   hi2s->State = HAL_I2S_STATE_BUSY_TX;
1120   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1121   hi2s->pTxBuffPtr = pData;
1122 
1123   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1124 
1125   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1126   {
1127     hi2s->TxXferSize = (Size << 1U);
1128     hi2s->TxXferCount = (Size << 1U);
1129   }
1130   else
1131   {
1132     hi2s->TxXferSize = Size;
1133     hi2s->TxXferCount = Size;
1134   }
1135 
1136   /* Set the I2S Tx DMA Half transfer complete callback */
1137   hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
1138 
1139   /* Set the I2S Tx DMA transfer complete callback */
1140   hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
1141 
1142   /* Set the DMA error callback */
1143   hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
1144 
1145   /* Enable the Tx DMA Stream/Channel */
1146   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx,
1147                                  (uint32_t)hi2s->pTxBuffPtr,
1148                                  (uint32_t)&hi2s->Instance->DR,
1149                                  hi2s->TxXferSize))
1150   {
1151     /* Update SPI error code */
1152     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1153     hi2s->State = HAL_I2S_STATE_READY;
1154 
1155     __HAL_UNLOCK(hi2s);
1156     return HAL_ERROR;
1157   }
1158 
1159   /* Check if the I2S is already enabled */
1160   if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1161   {
1162     /* Enable I2S peripheral */
1163     __HAL_I2S_ENABLE(hi2s);
1164   }
1165 
1166   /* Check if the I2S Tx request is already enabled */
1167   if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN))
1168   {
1169     /* Enable Tx DMA Request */
1170     SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1171   }
1172 
1173   __HAL_UNLOCK(hi2s);
1174   return HAL_OK;
1175 }
1176 
1177 /**
1178   * @brief  Receive an amount of data in non-blocking mode with DMA
1179   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1180   *         the configuration information for I2S module
1181   * @param  pData a 16-bit pointer to the Receive data buffer.
1182   * @param  Size number of data sample to be sent:
1183   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1184   *         configuration phase, the Size parameter means the number of 16-bit data length
1185   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1186   *         the Size parameter means the number of 24-bit or 32-bit data length.
1187   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1188   *         between Master and Slave(example: audio streaming).
1189   * @retval HAL status
1190   */
HAL_I2S_Receive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1191 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1192 {
1193   uint32_t tmpreg_cfgr;
1194 
1195   if ((pData == NULL) || (Size == 0U))
1196   {
1197     return  HAL_ERROR;
1198   }
1199 
1200   /* Process Locked */
1201   __HAL_LOCK(hi2s);
1202 
1203   if (hi2s->State != HAL_I2S_STATE_READY)
1204   {
1205     __HAL_UNLOCK(hi2s);
1206     return HAL_BUSY;
1207   }
1208 
1209   /* Set state and reset error code */
1210   hi2s->State = HAL_I2S_STATE_BUSY_RX;
1211   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1212   hi2s->pRxBuffPtr = pData;
1213 
1214   tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1215 
1216   if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1217   {
1218     hi2s->RxXferSize = (Size << 1U);
1219     hi2s->RxXferCount = (Size << 1U);
1220   }
1221   else
1222   {
1223     hi2s->RxXferSize = Size;
1224     hi2s->RxXferCount = Size;
1225   }
1226 
1227   /* Set the I2S Rx DMA Half transfer complete callback */
1228   hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
1229 
1230   /* Set the I2S Rx DMA transfer complete callback */
1231   hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
1232 
1233   /* Set the DMA error callback */
1234   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1235 
1236   /* Check if Master Receiver mode is selected */
1237   if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
1238   {
1239     /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
1240     access to the SPI_SR register. */
1241     __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1242   }
1243 
1244   /* Enable the Rx DMA Stream/Channel */
1245   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr,
1246                                  hi2s->RxXferSize))
1247   {
1248     /* Update SPI error code */
1249     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1250     hi2s->State = HAL_I2S_STATE_READY;
1251 
1252     __HAL_UNLOCK(hi2s);
1253     return HAL_ERROR;
1254   }
1255 
1256   /* Check if the I2S is already enabled */
1257   if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1258   {
1259     /* Enable I2S peripheral */
1260     __HAL_I2S_ENABLE(hi2s);
1261   }
1262 
1263   /* Check if the I2S Rx request is already enabled */
1264   if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN))
1265   {
1266     /* Enable Rx DMA Request */
1267     SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1268   }
1269 
1270   __HAL_UNLOCK(hi2s);
1271   return HAL_OK;
1272 }
1273 
1274 /**
1275   * @brief  Pauses the audio DMA Stream/Channel playing from the Media.
1276   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1277   *         the configuration information for I2S module
1278   * @retval HAL status
1279   */
HAL_I2S_DMAPause(I2S_HandleTypeDef * hi2s)1280 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1281 {
1282   /* Process Locked */
1283   __HAL_LOCK(hi2s);
1284 
1285   if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1286   {
1287     /* Disable the I2S DMA Tx request */
1288     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1289   }
1290   else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1291   {
1292     /* Disable the I2S DMA Rx request */
1293     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1294   }
1295   else
1296   {
1297     /* nothing to do */
1298   }
1299 
1300   /* Process Unlocked */
1301   __HAL_UNLOCK(hi2s);
1302 
1303   return HAL_OK;
1304 }
1305 
1306 /**
1307   * @brief  Resumes the audio DMA Stream/Channel playing from the Media.
1308   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1309   *         the configuration information for I2S module
1310   * @retval HAL status
1311   */
HAL_I2S_DMAResume(I2S_HandleTypeDef * hi2s)1312 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1313 {
1314   /* Process Locked */
1315   __HAL_LOCK(hi2s);
1316 
1317   if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1318   {
1319     /* Enable the I2S DMA Tx request */
1320     SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1321   }
1322   else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1323   {
1324     /* Enable the I2S DMA Rx request */
1325     SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1326   }
1327   else
1328   {
1329     /* nothing to do */
1330   }
1331 
1332   /* If the I2S peripheral is still not enabled, enable it */
1333   if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1334   {
1335     /* Enable I2S peripheral */
1336     __HAL_I2S_ENABLE(hi2s);
1337   }
1338 
1339   /* Process Unlocked */
1340   __HAL_UNLOCK(hi2s);
1341 
1342   return HAL_OK;
1343 }
1344 
1345 /**
1346   * @brief  Stops the audio DMA Stream/Channel playing from the Media.
1347   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1348   *         the configuration information for I2S module
1349   * @retval HAL status
1350   */
HAL_I2S_DMAStop(I2S_HandleTypeDef * hi2s)1351 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1352 {
1353   HAL_StatusTypeDef errorcode = HAL_OK;
1354   /* The Lock is not implemented on this API to allow the user application
1355      to call the HAL SPI API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1356      when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1357      and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1358      */
1359 
1360   if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
1361   {
1362     /* Abort the I2S DMA tx Stream/Channel */
1363     if (hi2s->hdmatx != NULL)
1364     {
1365       /* Disable the I2S DMA tx Stream/Channel */
1366       if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1367       {
1368         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1369         errorcode = HAL_ERROR;
1370       }
1371     }
1372 
1373     /* Wait until TXE flag is set */
1374     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, I2S_TIMEOUT_FLAG) != HAL_OK)
1375     {
1376       /* Set the error code */
1377       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1378       hi2s->State = HAL_I2S_STATE_READY;
1379       errorcode   = HAL_ERROR;
1380     }
1381 
1382     /* Wait until BSY flag is Reset */
1383     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, I2S_TIMEOUT_FLAG) != HAL_OK)
1384     {
1385       /* Set the error code */
1386       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1387       hi2s->State = HAL_I2S_STATE_READY;
1388       errorcode   = HAL_ERROR;
1389     }
1390 
1391     /* Disable I2S peripheral */
1392     __HAL_I2S_DISABLE(hi2s);
1393 
1394     /* Clear UDR flag */
1395     __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1396 
1397     /* Disable the I2S Tx DMA requests */
1398     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1399 
1400   }
1401 
1402   else if ((hi2s->Init.Mode == I2S_MODE_MASTER_RX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_RX))
1403   {
1404     /* Abort the I2S DMA rx Stream/Channel */
1405     if (hi2s->hdmarx != NULL)
1406     {
1407       /* Disable the I2S DMA rx Stream/Channel */
1408       if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1409       {
1410         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1411         errorcode = HAL_ERROR;
1412       }
1413     }
1414 
1415     /* Disable I2S peripheral */
1416     __HAL_I2S_DISABLE(hi2s);
1417 
1418     /* Clear OVR flag */
1419     __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1420 
1421     /* Disable the I2S Rx DMA request */
1422     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1423 
1424     if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
1425     {
1426       /* Set the error code */
1427       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_BUSY_LINE_RX);
1428 
1429       /* Set the I2S State ready */
1430       hi2s->State = HAL_I2S_STATE_READY;
1431       errorcode = HAL_ERROR;
1432     }
1433     else
1434     {
1435       /* Read DR to Flush RX Data */
1436       READ_REG((hi2s->Instance)->DR);
1437     }
1438   }
1439 
1440   hi2s->State = HAL_I2S_STATE_READY;
1441 
1442   return errorcode;
1443 }
1444 
1445 /**
1446   * @brief  This function handles I2S interrupt request.
1447   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1448   *         the configuration information for I2S module
1449   * @retval None
1450   */
HAL_I2S_IRQHandler(I2S_HandleTypeDef * hi2s)1451 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1452 {
1453   uint32_t itsource = hi2s->Instance->CR2;
1454   uint32_t itflag   = hi2s->Instance->SR;
1455 
1456   /* I2S in mode Receiver ------------------------------------------------*/
1457   if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) == RESET) &&
1458       (I2S_CHECK_FLAG(itflag, I2S_FLAG_RXNE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_RXNE) != RESET))
1459   {
1460     I2S_Receive_IT(hi2s);
1461     return;
1462   }
1463 
1464   /* I2S in mode Tramitter -----------------------------------------------*/
1465   if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_TXE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_TXE) != RESET))
1466   {
1467     I2S_Transmit_IT(hi2s);
1468     return;
1469   }
1470 
1471   /* I2S interrupt error -------------------------------------------------*/
1472   if (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_ERR) != RESET)
1473   {
1474     /* I2S Overrun error interrupt occurred ---------------------------------*/
1475     if (I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) != RESET)
1476     {
1477       /* Disable RXNE and ERR interrupt */
1478       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1479 
1480       /* Set the error code and execute error callback*/
1481       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1482     }
1483 
1484     /* I2S Underrun error interrupt occurred --------------------------------*/
1485     if (I2S_CHECK_FLAG(itflag, I2S_FLAG_UDR) != RESET)
1486     {
1487       /* Disable TXE and ERR interrupt */
1488       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1489 
1490       /* Set the error code and execute error callback*/
1491       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1492     }
1493 
1494     /* Set the I2S State ready */
1495     hi2s->State = HAL_I2S_STATE_READY;
1496 
1497     /* Call user error callback */
1498 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1499     hi2s->ErrorCallback(hi2s);
1500 #else
1501     HAL_I2S_ErrorCallback(hi2s);
1502 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1503   }
1504 }
1505 
1506 /**
1507   * @brief  Tx Transfer Half completed callbacks
1508   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1509   *         the configuration information for I2S module
1510   * @retval None
1511   */
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1512 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1513 {
1514   /* Prevent unused argument(s) compilation warning */
1515   UNUSED(hi2s);
1516 
1517   /* NOTE : This function Should not be modified, when the callback is needed,
1518             the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1519    */
1520 }
1521 
1522 /**
1523   * @brief  Tx Transfer completed callbacks
1524   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1525   *         the configuration information for I2S module
1526   * @retval None
1527   */
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef * hi2s)1528 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
1529 {
1530   /* Prevent unused argument(s) compilation warning */
1531   UNUSED(hi2s);
1532 
1533   /* NOTE : This function Should not be modified, when the callback is needed,
1534             the HAL_I2S_TxCpltCallback could be implemented in the user file
1535    */
1536 }
1537 
1538 /**
1539   * @brief  Rx Transfer half completed callbacks
1540   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1541   *         the configuration information for I2S module
1542   * @retval None
1543   */
HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1544 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1545 {
1546   /* Prevent unused argument(s) compilation warning */
1547   UNUSED(hi2s);
1548 
1549   /* NOTE : This function Should not be modified, when the callback is needed,
1550             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
1551    */
1552 }
1553 
1554 /**
1555   * @brief  Rx Transfer completed callbacks
1556   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1557   *         the configuration information for I2S module
1558   * @retval None
1559   */
HAL_I2S_RxCpltCallback(I2S_HandleTypeDef * hi2s)1560 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1561 {
1562   /* Prevent unused argument(s) compilation warning */
1563   UNUSED(hi2s);
1564 
1565   /* NOTE : This function Should not be modified, when the callback is needed,
1566             the HAL_I2S_RxCpltCallback could be implemented in the user file
1567    */
1568 }
1569 
1570 /**
1571   * @brief  I2S error callbacks
1572   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1573   *         the configuration information for I2S module
1574   * @retval None
1575   */
HAL_I2S_ErrorCallback(I2S_HandleTypeDef * hi2s)1576 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
1577 {
1578   /* Prevent unused argument(s) compilation warning */
1579   UNUSED(hi2s);
1580 
1581   /* NOTE : This function Should not be modified, when the callback is needed,
1582             the HAL_I2S_ErrorCallback could be implemented in the user file
1583    */
1584 }
1585 
1586 /**
1587   * @}
1588   */
1589 
1590 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1591   *  @brief   Peripheral State functions
1592   *
1593 @verbatim
1594  ===============================================================================
1595                       ##### Peripheral State and Errors functions #####
1596  ===============================================================================
1597     [..]
1598     This subsection permits to get in run-time the status of the peripheral
1599     and the data flow.
1600 
1601 @endverbatim
1602   * @{
1603   */
1604 
1605 /**
1606   * @brief  Return the I2S state
1607   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1608   *         the configuration information for I2S module
1609   * @retval HAL state
1610   */
HAL_I2S_GetState(I2S_HandleTypeDef * hi2s)1611 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1612 {
1613   return hi2s->State;
1614 }
1615 
1616 /**
1617   * @brief  Return the I2S error code
1618   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1619   *         the configuration information for I2S module
1620   * @retval I2S Error Code
1621   */
HAL_I2S_GetError(I2S_HandleTypeDef * hi2s)1622 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1623 {
1624   return hi2s->ErrorCode;
1625 }
1626 /**
1627   * @}
1628   */
1629 
1630 /**
1631   * @}
1632   */
1633 
1634 /** @addtogroup I2S_Private_Functions I2S Private Functions
1635   * @{
1636   */
1637 /**
1638   * @brief  DMA I2S transmit process complete callback
1639   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1640   *                the configuration information for the specified DMA module.
1641   * @retval None
1642   */
I2S_DMATxCplt(DMA_HandleTypeDef * hdma)1643 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1644 {
1645   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1646 
1647   /* if DMA is configured in DMA_NORMAL Mode */
1648   if (hdma->Init.Mode == DMA_NORMAL)
1649   {
1650     /* Disable Tx DMA Request */
1651     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1652 
1653     hi2s->TxXferCount = 0U;
1654     hi2s->State = HAL_I2S_STATE_READY;
1655   }
1656   /* Call user Tx complete callback */
1657 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1658   hi2s->TxCpltCallback(hi2s);
1659 #else
1660   HAL_I2S_TxCpltCallback(hi2s);
1661 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1662 }
1663 
1664 /**
1665   * @brief  DMA I2S transmit process half complete callback
1666   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1667   *                the configuration information for the specified DMA module.
1668   * @retval None
1669   */
I2S_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1670 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1671 {
1672   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1673 
1674   /* Call user Tx half complete callback */
1675 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1676   hi2s->TxHalfCpltCallback(hi2s);
1677 #else
1678   HAL_I2S_TxHalfCpltCallback(hi2s);
1679 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1680 }
1681 
1682 /**
1683   * @brief  DMA I2S receive process complete callback
1684   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1685   *                the configuration information for the specified DMA module.
1686   * @retval None
1687   */
I2S_DMARxCplt(DMA_HandleTypeDef * hdma)1688 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1689 {
1690   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1691 
1692   /* if DMA is configured in DMA_NORMAL Mode */
1693   if (hdma->Init.Mode == DMA_NORMAL)
1694   {
1695     /* Disable Rx DMA Request */
1696     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1697     hi2s->RxXferCount = 0U;
1698     hi2s->State = HAL_I2S_STATE_READY;
1699   }
1700   /* Call user Rx complete callback */
1701 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1702   hi2s->RxCpltCallback(hi2s);
1703 #else
1704   HAL_I2S_RxCpltCallback(hi2s);
1705 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1706 }
1707 
1708 /**
1709   * @brief  DMA I2S receive process half complete callback
1710   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1711   *                the configuration information for the specified DMA module.
1712   * @retval None
1713   */
I2S_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1714 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1715 {
1716   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1717 
1718   /* Call user Rx half complete callback */
1719 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1720   hi2s->RxHalfCpltCallback(hi2s);
1721 #else
1722   HAL_I2S_RxHalfCpltCallback(hi2s);
1723 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1724 }
1725 
1726 /**
1727   * @brief  DMA I2S communication error callback
1728   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1729   *                the configuration information for the specified DMA module.
1730   * @retval None
1731   */
I2S_DMAError(DMA_HandleTypeDef * hdma)1732 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1733 {
1734   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1735 
1736   /* Disable Rx and Tx DMA Request */
1737   CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1738   hi2s->TxXferCount = 0U;
1739   hi2s->RxXferCount = 0U;
1740 
1741   hi2s->State = HAL_I2S_STATE_READY;
1742 
1743   /* Set the error code and execute error callback*/
1744   SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1745   /* Call user error callback */
1746 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1747   hi2s->ErrorCallback(hi2s);
1748 #else
1749   HAL_I2S_ErrorCallback(hi2s);
1750 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1751 }
1752 
1753 /**
1754   * @brief  Transmit an amount of data in non-blocking mode with Interrupt
1755   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1756   *         the configuration information for I2S module
1757   * @retval None
1758   */
I2S_Transmit_IT(I2S_HandleTypeDef * hi2s)1759 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
1760 {
1761   /* Transmit data */
1762   hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
1763   hi2s->pTxBuffPtr++;
1764   hi2s->TxXferCount--;
1765 
1766   if (hi2s->TxXferCount == 0U)
1767   {
1768     /* Disable TXE and ERR interrupt */
1769     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1770 
1771     hi2s->State = HAL_I2S_STATE_READY;
1772     /* Call user Tx complete callback */
1773 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1774     hi2s->TxCpltCallback(hi2s);
1775 #else
1776     HAL_I2S_TxCpltCallback(hi2s);
1777 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1778   }
1779 }
1780 
1781 /**
1782   * @brief  Receive an amount of data in non-blocking mode with Interrupt
1783   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1784   *         the configuration information for I2S module
1785   * @retval None
1786   */
I2S_Receive_IT(I2S_HandleTypeDef * hi2s)1787 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
1788 {
1789   /* Receive data */
1790   (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
1791   hi2s->pRxBuffPtr++;
1792   hi2s->RxXferCount--;
1793 
1794   if (hi2s->RxXferCount == 0U)
1795   {
1796     /* Disable RXNE and ERR interrupt */
1797     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1798 
1799     hi2s->State = HAL_I2S_STATE_READY;
1800     /* Call user Rx complete callback */
1801 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1802     hi2s->RxCpltCallback(hi2s);
1803 #else
1804     HAL_I2S_RxCpltCallback(hi2s);
1805 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1806   }
1807 }
1808 
1809 /**
1810   * @brief  This function handles I2S Communication Timeout.
1811   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1812   *         the configuration information for I2S module
1813   * @param  Flag Flag checked
1814   * @param  State Value of the flag expected
1815   * @param  Timeout Duration of the timeout
1816   * @retval HAL status
1817   */
I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,FlagStatus State,uint32_t Timeout)1818 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
1819                                                        uint32_t Timeout)
1820 {
1821   uint32_t tickstart;
1822 
1823   /* Get tick */
1824   tickstart = HAL_GetTick();
1825 
1826   /* Wait until flag is set to status*/
1827   while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1828   {
1829     if (Timeout != HAL_MAX_DELAY)
1830     {
1831       if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
1832       {
1833         /* Set the I2S State ready */
1834         hi2s->State = HAL_I2S_STATE_READY;
1835 
1836         /* Process Unlocked */
1837         __HAL_UNLOCK(hi2s);
1838 
1839         return HAL_TIMEOUT;
1840       }
1841     }
1842   }
1843   return HAL_OK;
1844 }
1845 
1846 /**
1847   * @}
1848   */
1849 
1850 /**
1851   * @}
1852   */
1853 
1854 /**
1855   * @}
1856   */
1857 #endif /* SPI_I2S_SUPPORT */
1858 
1859 #endif /* HAL_I2S_MODULE_ENABLED */
1860 
1861