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