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