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