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