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