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