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