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