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