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