1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_hal_i2s.c
4   * @author  MCD Application Team
5   * @brief   I2S HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Integrated Interchip Sound (I2S) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral State and Errors functions
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2023 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23  ===============================================================================
24                   ##### How to use this driver #####
25  ===============================================================================
26  [..]
27     The I2S HAL driver can be used as follow:
28 
29     (#) Declare a I2S_HandleTypeDef handle structure.
30     (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
31         (##) Enable the SPIx interface clock.
32         (##) I2S pins configuration:
33             (+++) Enable the clock for the I2S GPIOs.
34             (+++) Configure these I2S pins as alternate function pull-up.
35         (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
36              and HAL_I2S_Receive_IT() APIs).
37             (+++) Configure the I2Sx interrupt priority.
38             (+++) Enable the NVIC I2S IRQ handle.
39         (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
40              and HAL_I2S_Receive_DMA() APIs:
41             (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel.
42             (+++) Enable the DMAx interface clock.
43             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
44             (+++) Configure the DMA Tx/Rx Stream/Channel.
45             (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
46             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
47                   DMA Tx/Rx Stream/Channel.
48 
49    (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
50        using HAL_I2S_Init() function.
51 
52    -@- The specific I2S interrupts (Transmission complete interrupt,
53        RXNE interrupt and Error Interrupts) will be managed using the macros
54        __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
55 
56         (+@) External clock source is configured after setting correctly
57              the define constant EXTERNAL_CLOCK_VALUE in the stm32n6xx_hal_conf.h file.
58 
59     (#) Three mode of operations are available within this driver :
60 
61    *** Polling mode IO operation ***
62    =================================
63    [..]
64      (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
65      (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
66 
67    *** Interrupt mode IO operation ***
68    ===================================
69    [..]
70      (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
71      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
72          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
73      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
74          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
75      (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
76      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
77          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
78      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
79          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
80      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
81          add his own code by customization of function pointer HAL_I2S_ErrorCallback
82 
83    *** DMA mode IO operation ***
84    ==============================
85    [..]
86      (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
87      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
88          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
89      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
90          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
91      (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
92      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
93          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
94      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
95          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
96      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
97          add his own code by customization of function pointer HAL_I2S_ErrorCallback
98      (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
99      (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
100      (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
101 
102    *** I2S HAL driver macros list ***
103    ===================================
104    [..]
105      Below the list of most used macros in I2S HAL driver.
106 
107       (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
108       (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
109       (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
110       (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
111       (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
112 
113     [..]
114       (@) You can refer to the I2S HAL driver header file for more useful macros
115 
116    *** I2S HAL driver macros list ***
117    ===================================
118    [..]
119        Callback registration:
120 
121       (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1UL
122           allows the user to configure dynamically the driver callbacks.
123           Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
124 
125           Function HAL_I2S_RegisterCallback() allows to register following callbacks:
126             (+) TxCpltCallback        : I2S Tx Completed callback
127             (+) RxCpltCallback        : I2S Rx Completed callback
128             (+) TxRxCpltCallback      : I2S TxRx Completed callback
129             (+) TxHalfCpltCallback    : I2S Tx Half Completed callback
130             (+) RxHalfCpltCallback    : I2S Rx Half Completed callback
131             (+) TxRxHalfCpltCallback  : I2S TxRx Half Completed callback
132             (+) ErrorCallback         : I2S Error callback
133             (+) MspInitCallback       : I2S Msp Init callback
134             (+) MspDeInitCallback     : I2S Msp DeInit callback
135           This function takes as parameters the HAL peripheral handle, the Callback ID
136           and a pointer to the user callback function.
137 
138 
139       (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default
140           weak function.
141           HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
142           and the Callback ID.
143           This function allows to reset following callbacks:
144             (+) TxCpltCallback        : I2S Tx Completed callback
145             (+) RxCpltCallback        : I2S Rx Completed callback
146             (+) TxRxCpltCallback      : I2S TxRx Completed callback
147             (+) TxHalfCpltCallback    : I2S Tx Half Completed callback
148             (+) RxHalfCpltCallback    : I2S Rx Half Completed callback
149             (+) TxRxHalfCpltCallback  : I2S TxRx Half Completed callback
150             (+) ErrorCallback         : I2S Error callback
151             (+) MspInitCallback       : I2S Msp Init callback
152             (+) MspDeInitCallback     : I2S Msp DeInit callback
153 
154        By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
155        all callbacks are set to the corresponding weak functions:
156        examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
157        Exception done for MspInit and MspDeInit functions that are
158        reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
159        these callbacks are null (not registered beforehand).
160        If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
161        keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
162 
163        Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
164        Exception done MspInit/MspDeInit functions that can be registered/unregistered
165        in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state,
166        thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
167        Then, the user first registers the MspInit/MspDeInit user callbacks
168        using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
169        or HAL_I2S_Init() function.
170 
171        When The compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
172        not defined, the callback registering feature is not available
173        and weak callbacks are used.
174 
175 
176   @endverbatim
177   */
178 
179 /* Includes ------------------------------------------------------------------*/
180 #include "stm32n6xx_hal.h"
181 
182 #ifdef HAL_I2S_MODULE_ENABLED
183 
184 /** @addtogroup STM32N6xx_HAL_Driver
185   * @{
186   */
187 
188 /** @defgroup I2S I2S
189   * @brief I2S HAL module driver
190   * @{
191   */
192 
193 /* Private typedef -----------------------------------------------------------*/
194 /* Private define ------------------------------------------------------------*/
195 /** @defgroup I2S_Private_Define I2S Private Define
196   * @{
197   */
198 #define I2S_TIMEOUT 0xFFFFUL
199 /**
200   * @}
201   */
202 
203 /* Private macro -------------------------------------------------------------*/
204 /* Private variables ---------------------------------------------------------*/
205 /* Private function prototypes -----------------------------------------------*/
206 /** @defgroup I2S_Private_Functions I2S Private Functions
207   * @{
208   */
209 static void               I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
210 static void               I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
211 static void               I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
212 static void               I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
213 static void               I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma);
214 static void               I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma);
215 static void               I2S_DMAError(DMA_HandleTypeDef *hdma);
216 static void               I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s);
217 static void               I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s);
218 static void               I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s);
219 static void               I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s);
220 static HAL_StatusTypeDef  I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
221                                                         uint32_t Tickstart, uint32_t Timeout);
222 /**
223   * @}
224   */
225 
226 /* Exported functions ---------------------------------------------------------*/
227 
228 /** @defgroup I2S_Exported_Functions I2S Exported Functions
229   * @{
230   */
231 
232 /** @defgroup  I2S_Exported_Functions_Group1 Initialization and de-initialization functions
233   *  @brief    Initialization and Configuration functions
234   *
235 @verbatim
236  ===============================================================================
237               ##### Initialization and de-initialization functions #####
238  ===============================================================================
239     [..]  This subsection provides a set of functions allowing to initialize and
240           de-initialize the I2Sx peripheral in simplex mode:
241 
242       (+) User must Implement HAL_I2S_MspInit() function in which he configures
243           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
244 
245       (+) Call the function HAL_I2S_Init() to configure the selected device with
246           the selected configuration:
247         (++) Mode
248         (++) Standard
249         (++) Data Format
250         (++) MCLK Output
251         (++) Audio frequency
252         (++) Polarity
253 
254      (+) Call the function HAL_I2S_DeInit() to restore the default configuration
255           of the selected I2Sx peripheral.
256   @endverbatim
257   * @{
258   */
259 
260 /**
261   * @brief  Initializes the I2S according to the specified parameters
262   *         in the I2S_InitTypeDef and create the associated handle.
263   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
264   *         the configuration information for I2S module
265   * @retval HAL status
266   */
HAL_I2S_Init(I2S_HandleTypeDef * hi2s)267 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
268 {
269   uint32_t i2sdiv;
270   uint32_t i2sodd;
271   uint32_t packetlength;
272   uint32_t tmp;
273   uint32_t i2sclk;
274   uint32_t ispcm;
275 
276   /* Check the I2S handle allocation */
277   if (hi2s == NULL)
278   {
279     return HAL_ERROR;
280   }
281 
282   /* Check the I2S parameters */
283   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
284   assert_param(IS_I2S_MODE(hi2s->Init.Mode));
285   assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
286   assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
287   assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
288   assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
289   assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
290   assert_param(IS_I2S_FIRST_BIT(hi2s->Init.FirstBit));
291   assert_param(IS_I2S_WS_INVERSION(hi2s->Init.WSInversion));
292   assert_param(IS_I2S_DATA_24BIT_ALIGNMENT(hi2s->Init.Data24BitAlignment));
293   assert_param(IS_I2S_MASTER_KEEP_IO_STATE(hi2s->Init.MasterKeepIOState));
294 
295   if (hi2s->State == HAL_I2S_STATE_RESET)
296   {
297     /* Allocate lock resource and initialize it */
298     hi2s->Lock = HAL_UNLOCKED;
299 
300 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
301     /* Init the I2S Callback settings */
302     hi2s->TxCpltCallback       = HAL_I2S_TxCpltCallback;          /* Legacy weak TxCpltCallback       */
303     hi2s->RxCpltCallback       = HAL_I2S_RxCpltCallback;          /* Legacy weak RxCpltCallback       */
304     hi2s->TxRxCpltCallback     = HAL_I2SEx_TxRxCpltCallback;      /* Legacy weak TxRxCpltCallback     */
305     hi2s->TxHalfCpltCallback   = HAL_I2S_TxHalfCpltCallback;      /* Legacy weak TxHalfCpltCallback   */
306     hi2s->RxHalfCpltCallback   = HAL_I2S_RxHalfCpltCallback;      /* Legacy weak RxHalfCpltCallback   */
307     hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback;  /* Legacy weak TxRxHalfCpltCallback */
308     hi2s->ErrorCallback        = HAL_I2S_ErrorCallback;           /* Legacy weak ErrorCallback        */
309 
310     if (hi2s->MspInitCallback == NULL)
311     {
312       hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit  */
313     }
314 
315     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
316     hi2s->MspInitCallback(hi2s);
317 #else
318     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
319     HAL_I2S_MspInit(hi2s);
320 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
321   }
322 
323   hi2s->State = HAL_I2S_STATE_BUSY;
324 
325   /* Disable the selected I2S peripheral */
326   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE)
327   {
328     /* Disable I2S peripheral */
329     __HAL_I2S_DISABLE(hi2s);
330   }
331 
332   /* Clear I2S configuration register */
333   CLEAR_REG(hi2s->Instance->I2SCFGR);
334 
335   if (IS_I2S_MASTER(hi2s->Init.Mode))
336   {
337     /*------------------------- I2SDIV and ODD Calculation ---------------------*/
338     /* If the requested audio frequency is not the default, compute the prescaler */
339     if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
340     {
341       /* Check the frame length (For the Prescaler computing) ********************/
342       if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
343       {
344         /* Channel length is 32 bits */
345         packetlength = 2UL;
346       }
347       else
348       {
349         /* Channel length is 16 bits */
350         packetlength = 1UL;
351       }
352 
353       /* Check if PCM standard is used */
354       if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) ||
355           (hi2s->Init.Standard == I2S_STANDARD_PCM_LONG))
356       {
357         ispcm = 1UL;
358       }
359       else
360       {
361         ispcm = 0UL;
362       }
363 
364       /* Get the source clock value: based on System Clock value */
365       if (hi2s->Instance == SPI1)
366       {
367         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI1);
368       }
369       else if (hi2s->Instance == SPI2)
370       {
371         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI2);
372       }
373       else if (hi2s->Instance == SPI3)
374       {
375         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI3);
376       }
377       else /* SPI6 source clock */
378       {
379         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI6);
380       }
381 
382       /* Compute the Real divider depending on the MCLK output state, with a floating point */
383       if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
384       {
385         /* MCLK output is enabled */
386         tmp = (uint32_t)((((i2sclk / (256UL >> ispcm)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
387       }
388       else
389       {
390         /* MCLK output is disabled */
391         tmp = (uint32_t)((((i2sclk / ((32UL >> ispcm) * packetlength)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
392       }
393 
394       /* Remove the flatting point */
395       tmp = tmp / 10UL;
396 
397       /* Check the parity of the divider */
398       i2sodd = (uint32_t)(tmp & (uint32_t)1UL);
399 
400       /* Compute the i2sdiv prescaler */
401       i2sdiv = (uint32_t)((tmp - i2sodd) / 2UL);
402     }
403     else
404     {
405       /* Set the default values */
406       i2sdiv = 2UL;
407       i2sodd = 0UL;
408     }
409 
410     /* Test if the obtain values are forbidden or out of range */
411     if (((i2sodd == 1UL) && (i2sdiv == 1UL)) || (i2sdiv > 0xFFUL))
412     {
413       /* Set the error code */
414       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
415       return  HAL_ERROR;
416     }
417 
418     /* Force i2smod to 1 just to be sure that (2xi2sdiv + i2sodd) is always higher than 0 */
419     if (i2sdiv == 0UL)
420     {
421       i2sodd = 1UL;
422     }
423 
424     MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SDIV                 | SPI_I2SCFGR_ODD),
425                ((i2sdiv << SPI_I2SCFGR_I2SDIV_Pos) | (i2sodd << SPI_I2SCFGR_ODD_Pos)));
426   }
427 
428   /*-------------------------- I2Sx I2SCFGR Configuration --------------------*/
429   /* Configure I2SMOD, I2SCFG, I2SSTD, PCMSYNC, DATLEN ,CHLEN ,CKPOL, WSINV, DATAFMT, I2SDIV, ODD and MCKOE bits bits */
430   /* And configure the I2S with the I2S_InitStruct values */
431   MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SMOD   | SPI_I2SCFGR_I2SCFG     | \
432                                        SPI_I2SCFGR_I2SSTD   | SPI_I2SCFGR_PCMSYNC    | \
433                                        SPI_I2SCFGR_DATLEN   | SPI_I2SCFGR_CHLEN      | \
434                                        SPI_I2SCFGR_CKPOL    | SPI_I2SCFGR_WSINV      | \
435                                        SPI_I2SCFGR_DATFMT   | SPI_I2SCFGR_MCKOE),
436              (SPI_I2SCFGR_I2SMOD   | hi2s->Init.Mode        | \
437               hi2s->Init.Standard  | hi2s->Init.DataFormat  | \
438               hi2s->Init.CPOL      | hi2s->Init.WSInversion | \
439               hi2s->Init.Data24BitAlignment | hi2s->Init.MCLKOutput));
440   /*Clear status register*/
441   WRITE_REG(hi2s->Instance->IFCR, 0x0FF8);
442 
443   /*---------------------------- I2Sx CFG2 Configuration ----------------------*/
444 
445   /* Unlock the AF configuration to configure CFG2 register*/
446   CLEAR_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK);
447 
448   MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_LSBFRST, hi2s->Init.FirstBit);
449 
450   /* Insure that AFCNTR is managed only by Master */
451   if (IS_I2S_MASTER(hi2s->Init.Mode))
452   {
453     /* Alternate function GPIOs control */
454     MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_AFCNTR, (hi2s->Init.MasterKeepIOState));
455   }
456 
457   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
458   hi2s->State     = HAL_I2S_STATE_READY;
459 
460   return HAL_OK;
461 }
462 
463 /**
464   * @brief DeInitializes the I2S peripheral
465   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
466   *         the configuration information for I2S module
467   * @retval HAL status
468   */
HAL_I2S_DeInit(I2S_HandleTypeDef * hi2s)469 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
470 {
471   /* Check the I2S handle allocation */
472   if (hi2s == NULL)
473   {
474     return HAL_ERROR;
475   }
476 
477   /* Check the parameters */
478   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
479 
480   hi2s->State = HAL_I2S_STATE_BUSY;
481 
482   /* Disable the I2S Peripheral Clock */
483   __HAL_I2S_DISABLE(hi2s);
484 
485 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
486   if (hi2s->MspDeInitCallback == NULL)
487   {
488     hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit  */
489   }
490 
491   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
492   hi2s->MspDeInitCallback(hi2s);
493 #else
494   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
495   HAL_I2S_MspDeInit(hi2s);
496 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
497 
498   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
499   hi2s->State     = HAL_I2S_STATE_RESET;
500 
501   /* Release Lock */
502   __HAL_UNLOCK(hi2s);
503 
504   return HAL_OK;
505 }
506 
507 /**
508   * @brief I2S MSP Init
509   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
510   *         the configuration information for I2S module
511   * @retval None
512   */
HAL_I2S_MspInit(I2S_HandleTypeDef * hi2s)513 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
514 {
515   /* Prevent unused argument(s) compilation warning */
516   UNUSED(hi2s);
517 
518   /* NOTE : This function Should not be modified, when the callback is needed,
519             the HAL_I2S_MspInit could be implemented in the user file
520    */
521 }
522 
523 /**
524   * @brief I2S MSP DeInit
525   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
526   *         the configuration information for I2S module
527   * @retval None
528   */
HAL_I2S_MspDeInit(I2S_HandleTypeDef * hi2s)529 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
530 {
531   /* Prevent unused argument(s) compilation warning */
532   UNUSED(hi2s);
533 
534   /* NOTE : This function Should not be modified, when the callback is needed,
535             the HAL_I2S_MspDeInit could be implemented in the user file
536    */
537 }
538 
539 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
540 /**
541   * @brief  Register a User I2S Callback
542   *         To be used instead of the weak predefined callback
543   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
544   *                the configuration information for the specified I2S.
545   * @param  CallbackID ID of the callback to be registered
546   * @param  pCallback pointer to the Callback function
547   * @note   The HAL_I2S_RegisterCallback() may be called before HAL_I2S_Init() in HAL_I2S_STATE_RESET
548   *         to register callbacks for HAL_I2S_MSPINIT_CB_ID and HAL_I2S_MSPDEINIT_CB_ID
549   * @retval HAL status
550   */
HAL_I2S_RegisterCallback(I2S_HandleTypeDef * hi2s,HAL_I2S_CallbackIDTypeDef CallbackID,pI2S_CallbackTypeDef pCallback)551 HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID,
552                                            pI2S_CallbackTypeDef pCallback)
553 {
554   HAL_StatusTypeDef status = HAL_OK;
555 
556   if (pCallback == NULL)
557   {
558     /* Update the error code */
559     hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
560 
561     return HAL_ERROR;
562   }
563 
564   if (HAL_I2S_STATE_READY == hi2s->State)
565   {
566     switch (CallbackID)
567     {
568       case HAL_I2S_TX_COMPLETE_CB_ID :
569         hi2s->TxCpltCallback = pCallback;
570         break;
571 
572       case HAL_I2S_RX_COMPLETE_CB_ID :
573         hi2s->RxCpltCallback = pCallback;
574         break;
575 
576       case HAL_I2S_TX_RX_COMPLETE_CB_ID :
577         hi2s->TxRxCpltCallback = pCallback;
578         break;
579 
580       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
581         hi2s->TxHalfCpltCallback = pCallback;
582         break;
583 
584       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
585         hi2s->RxHalfCpltCallback = pCallback;
586         break;
587 
588 
589       case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
590         hi2s->TxRxHalfCpltCallback = pCallback;
591         break;
592 
593       case HAL_I2S_ERROR_CB_ID :
594         hi2s->ErrorCallback = pCallback;
595         break;
596 
597       case HAL_I2S_MSPINIT_CB_ID :
598         hi2s->MspInitCallback = pCallback;
599         break;
600 
601       case HAL_I2S_MSPDEINIT_CB_ID :
602         hi2s->MspDeInitCallback = pCallback;
603         break;
604 
605       default :
606         /* Update the error code */
607         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
608 
609         /* Return error status */
610         status =  HAL_ERROR;
611         break;
612     }
613   }
614   else if (HAL_I2S_STATE_RESET == hi2s->State)
615   {
616     switch (CallbackID)
617     {
618       case HAL_I2S_MSPINIT_CB_ID :
619         hi2s->MspInitCallback = pCallback;
620         break;
621 
622       case HAL_I2S_MSPDEINIT_CB_ID :
623         hi2s->MspDeInitCallback = pCallback;
624         break;
625 
626       default :
627         /* Update the error code */
628         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
629 
630         /* Return error status */
631         status =  HAL_ERROR;
632         break;
633     }
634   }
635   else
636   {
637     /* Update the error code */
638     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
639 
640     /* Return error status */
641     status =  HAL_ERROR;
642   }
643 
644   return status;
645 }
646 
647 /**
648   * @brief  Unregister an I2S Callback
649   *         I2S callback is redirected to the weak predefined callback
650   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
651   *                the configuration information for the specified I2S.
652   * @param  CallbackID ID of the callback to be unregistered
653   * @note   The HAL_I2S_UnRegisterCallback() may be called before HAL_I2S_Init() in HAL_I2S_STATE_RESET
654   *         to un-register callbacks for HAL_I2S_MSPINIT_CB_ID and HAL_I2S_MSPDEINIT_CB_ID
655   * @retval HAL status
656   */
HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef * hi2s,HAL_I2S_CallbackIDTypeDef CallbackID)657 HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
658 {
659   HAL_StatusTypeDef status = HAL_OK;
660 
661   if (HAL_I2S_STATE_READY == hi2s->State)
662   {
663     switch (CallbackID)
664     {
665       case HAL_I2S_TX_COMPLETE_CB_ID :
666         hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback;                /* Legacy weak TxCpltCallback       */
667         break;
668 
669       case HAL_I2S_RX_COMPLETE_CB_ID :
670         hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback;                /* Legacy weak RxCpltCallback       */
671         break;
672 
673       case HAL_I2S_TX_RX_COMPLETE_CB_ID :
674         hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback;          /* Legacy weak TxRxCpltCallback     */
675         break;
676 
677       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
678         hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback   */
679         break;
680 
681       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
682         hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback   */
683         break;
684 
685       case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
686         hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback;  /* Legacy weak TxRxHalfCpltCallback */
687         break;
688 
689       case HAL_I2S_ERROR_CB_ID :
690         hi2s->ErrorCallback = HAL_I2S_ErrorCallback;                  /* Legacy weak ErrorCallback        */
691         break;
692 
693       case HAL_I2S_MSPINIT_CB_ID :
694         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
695         break;
696 
697       case HAL_I2S_MSPDEINIT_CB_ID :
698         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
699         break;
700 
701       default :
702         /* Update the error code */
703         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
704 
705         /* Return error status */
706         status =  HAL_ERROR;
707         break;
708     }
709   }
710   else if (HAL_I2S_STATE_RESET == hi2s->State)
711   {
712     switch (CallbackID)
713     {
714       case HAL_I2S_MSPINIT_CB_ID :
715         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
716         break;
717 
718       case HAL_I2S_MSPDEINIT_CB_ID :
719         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
720         break;
721 
722       default :
723         /* Update the error code */
724         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
725 
726         /* Return error status */
727         status =  HAL_ERROR;
728         break;
729     }
730   }
731   else
732   {
733     /* Update the error code */
734     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
735 
736     /* Return error status */
737     status =  HAL_ERROR;
738   }
739 
740   return status;
741 }
742 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
743 /**
744   * @}
745   */
746 
747 /** @defgroup I2S_Exported_Functions_Group2 IO operation functions
748   *  @brief Data transfers functions
749   *
750 @verbatim
751  ===============================================================================
752                       ##### IO operation functions #####
753  ===============================================================================
754     [..]
755     This subsection provides a set of functions allowing to manage the I2S data
756     transfers.
757 
758     (#) There are two modes of transfer:
759        (++) Blocking mode : The communication is performed in the polling mode.
760             The status of all data processing is returned by the same function
761             after finishing transfer.
762        (++) No-Blocking mode : The communication is performed using Interrupts
763             or DMA. These functions return the status of the transfer startup.
764             The end of the data processing will be indicated through the
765             dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
766             using DMA mode.
767 
768     (#) Blocking mode functions are :
769         (++) HAL_I2S_Transmit()
770         (++) HAL_I2S_Receive()
771         (++) HAL_I2SEx_TransmitReceive()
772 
773     (#) No-Blocking mode functions with Interrupt are :
774         (++) HAL_I2S_Transmit_IT()
775         (++) HAL_I2S_Receive_IT()
776         (++) HAL_I2SEx_TransmitReceive_IT()
777 
778     (#) No-Blocking mode functions with DMA are :
779         (++) HAL_I2S_Transmit_DMA()
780         (++) HAL_I2S_Receive_DMA()
781         (++) HAL_I2SEx_TransmitReceive_DMA()
782 
783     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
784         (++) HAL_I2S_TxCpltCallback()
785         (++) HAL_I2S_RxCpltCallback()
786         (++) HAL_I2SEx_TxRxCpltCallback()
787         (++) HAL_I2S_ErrorCallback()
788 
789 @endverbatim
790   * @{
791   */
792 
793 /**
794   * @brief  Transmit an amount of data in blocking mode
795   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
796   *         the configuration information for I2S module
797   * @param  pData a 16-bit pointer to data buffer.
798   * @param  Size number of data sample to be sent:
799   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
800   *         configuration phase, the Size parameter means the number of 16-bit data length
801   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
802   *         the Size parameter means the number of 16-bit data length.
803   * @param  Timeout Timeout duration
804   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
805   *         between Master and Slave(example: audio streaming).
806   * @retval HAL status
807   */
HAL_I2S_Transmit(I2S_HandleTypeDef * hi2s,const uint16_t * pData,uint16_t Size,uint32_t Timeout)808 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size, uint32_t Timeout)
809 {
810 #if defined (__GNUC__)
811   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
812 #endif /* __GNUC__ */
813   uint32_t tickstart;
814 
815   if ((pData == NULL) || (Size == 0UL))
816   {
817     return  HAL_ERROR;
818   }
819 
820   if (hi2s->State != HAL_I2S_STATE_READY)
821   {
822     return HAL_BUSY;
823   }
824 
825   /* Process Locked */
826   __HAL_LOCK(hi2s);
827 
828   /* Init tickstart for timeout management*/
829   tickstart = HAL_GetTick();
830 
831   /* Set state and reset error code */
832   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
833   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
834   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
835   hi2s->TxXferSize  = Size;
836   hi2s->TxXferCount = Size;
837 
838   /* Initialize fields not used in handle to zero */
839   hi2s->pRxBuffPtr  = NULL;
840   hi2s->RxXferSize  = (uint16_t) 0UL;
841   hi2s->RxXferCount = (uint16_t) 0UL;
842 
843   /* Check if the I2S is already enabled */
844   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
845   {
846     /* Enable I2S peripheral */
847     __HAL_I2S_ENABLE(hi2s);
848   }
849 
850   /* Start the transfer */
851   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
852 
853 
854   /* Wait until TXP flag is set */
855   if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, tickstart, Timeout) != HAL_OK)
856   {
857     /* Set the error code */
858     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
859     hi2s->State = HAL_I2S_STATE_READY;
860     __HAL_UNLOCK(hi2s);
861     return HAL_TIMEOUT;
862   }
863 
864   while (hi2s->TxXferCount > 0UL)
865   {
866     if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
867     {
868       /* Transmit data in 32 Bit mode */
869       hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
870       hi2s->pTxBuffPtr += 2;
871       hi2s->TxXferCount--;
872     }
873     else
874     {
875       /* Transmit data in 16 Bit mode */
876 #if defined (__GNUC__)
877       *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
878 #else
879       *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
880 #endif /* __GNUC__ */
881 
882       hi2s->pTxBuffPtr++;
883       hi2s->TxXferCount--;
884     }
885 
886     /* Wait until TXP flag is set */
887     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, tickstart, Timeout) != HAL_OK)
888     {
889       /* Set the error code */
890       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
891       hi2s->State = HAL_I2S_STATE_READY;
892       __HAL_UNLOCK(hi2s);
893       return HAL_TIMEOUT;
894     }
895   }
896 
897   hi2s->State = HAL_I2S_STATE_READY;
898   __HAL_UNLOCK(hi2s);
899   return HAL_OK;
900 }
901 
902 /**
903   * @brief  Receive an amount of data in blocking mode
904   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
905   *         the configuration information for I2S module
906   * @param  pData a 16-bit pointer to data buffer.
907   * @param  Size number of data sample to be sent:
908   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
909   *         configuration phase, the Size parameter means the number of 16-bit data length
910   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
911   *         the Size parameter means the number of 16-bit data length.
912   * @param  Timeout Timeout duration
913   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
914   *         between Master and Slave(example: audio streaming).
915   * @note   In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
916   *         in continuous way and as the I2S is not disabled at the end of the I2S transaction.
917   * @retval HAL status
918   */
HAL_I2S_Receive(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)919 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
920 {
921 #if defined (__GNUC__)
922   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
923 #endif /* __GNUC__ */
924   uint32_t tickstart;
925 
926   if ((pData == NULL) || (Size == 0UL))
927   {
928     return  HAL_ERROR;
929   }
930 
931   if (hi2s->State != HAL_I2S_STATE_READY)
932   {
933     return HAL_BUSY;
934   }
935 
936   /* Process Locked */
937   __HAL_LOCK(hi2s);
938 
939   /* Init tickstart for timeout management*/
940   tickstart = HAL_GetTick();
941 
942   /* Set state and reset error code */
943   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
944   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
945   hi2s->pRxBuffPtr  = pData;
946   hi2s->RxXferSize  = Size;
947   hi2s->RxXferCount = Size;
948 
949   /* Initialize fields not used in handle to zero */
950   hi2s->pTxBuffPtr  = NULL;
951   hi2s->TxXferSize  = (uint16_t) 0UL;
952   hi2s->TxXferCount = (uint16_t) 0UL;
953 
954   /* Check if the I2S is already enabled */
955   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
956   {
957     /* Enable I2S peripheral */
958     __HAL_I2S_ENABLE(hi2s);
959   }
960 
961   /* Start the transfer */
962   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
963 
964   /* Receive data */
965   while (hi2s->RxXferCount > 0UL)
966   {
967     /* Wait until RXP flag is set */
968     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXP, SET, tickstart, Timeout) != HAL_OK)
969     {
970       /* Set the error code */
971       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
972       hi2s->State = HAL_I2S_STATE_READY;
973       __HAL_UNLOCK(hi2s);
974       return HAL_TIMEOUT;
975     }
976 
977     if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
978     {
979       /* Receive data in 32 Bit mode */
980       *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
981       hi2s->pRxBuffPtr += 2;
982       hi2s->RxXferCount--;
983     }
984     else
985     {
986       /* Receive data in 16 Bit mode */
987 #if defined (__GNUC__)
988       *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
989 #else
990       *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
991 #endif /* __GNUC__ */
992       hi2s->pRxBuffPtr++;
993       hi2s->RxXferCount--;
994     }
995   }
996 
997   hi2s->State = HAL_I2S_STATE_READY;
998   __HAL_UNLOCK(hi2s);
999   return HAL_OK;
1000 }
1001 
1002 /**
1003   * @brief  Full-Duplex Transmit/Receive data in blocking mode.
1004   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1005   *         the configuration information for I2S module
1006   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1007   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1008   * @param  Size number of data sample to be sent:
1009   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1010   *         configuration phase, the Size parameter means the number of 16-bit data length
1011   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1012   *         the Size parameter means the number of 16-bit data length.
1013   * @param  Timeout Timeout duration
1014   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1015   *         between Master and Slave(example: audio streaming).
1016   * @retval HAL status
1017   */
1018 
HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef * hi2s,const uint16_t * pTxData,uint16_t * pRxData,uint16_t Size,uint32_t Timeout)1019 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1020                                             uint16_t Size, uint32_t Timeout)
1021 {
1022   uint32_t tmp_TxXferCount;
1023   uint32_t tmp_RxXferCount;
1024   uint32_t tickstart;
1025 
1026 #if defined (__GNUC__)
1027   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
1028   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
1029 #endif /* __GNUC__ */
1030 
1031   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1032   {
1033     return  HAL_ERROR;
1034   }
1035 
1036   if (hi2s->State != HAL_I2S_STATE_READY)
1037   {
1038     return HAL_BUSY;
1039   }
1040 
1041   /* Process Locked */
1042   __HAL_LOCK(hi2s);
1043 
1044   /* Init tickstart for timeout management*/
1045   tickstart = HAL_GetTick();
1046 
1047   hi2s->TxXferSize  = Size;
1048   hi2s->TxXferCount = Size;
1049   hi2s->pTxBuffPtr  = (const uint16_t *)pTxData;
1050   hi2s->RxXferSize  = Size;
1051   hi2s->RxXferCount = Size;
1052   hi2s->pRxBuffPtr  = pRxData;
1053 
1054   tmp_TxXferCount = hi2s->TxXferCount;
1055   tmp_RxXferCount = hi2s->RxXferCount;
1056 
1057   /* Set state and reset error code */
1058   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1059   hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
1060 
1061   /* Check if the I2S is already enabled */
1062   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1063   {
1064     /* Enable I2S peripheral */
1065     __HAL_I2S_ENABLE(hi2s);
1066   }
1067 
1068   /* Start the transfer */
1069   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1070 
1071   while ((tmp_TxXferCount > 0UL) || (tmp_RxXferCount > 0UL))
1072   {
1073     if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXP) == SET) && (tmp_TxXferCount != 0UL))
1074     {
1075       if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1076       {
1077         /* Transmit data in 32 Bit mode */
1078         hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
1079         hi2s->pTxBuffPtr += 2;
1080         tmp_TxXferCount--;
1081       }
1082       else
1083       {
1084         /* Transmit data in 16 Bit mode */
1085 #if defined (__GNUC__)
1086         *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
1087 #else
1088         *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
1089 #endif /* __GNUC__ */
1090 
1091         hi2s->pTxBuffPtr++;
1092         tmp_TxXferCount--;
1093       }
1094     }
1095 
1096     if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXP) == SET) && (tmp_RxXferCount != 0UL))
1097     {
1098       if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1099       {
1100         /* Receive data in 32 Bit mode */
1101         *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
1102         hi2s->pRxBuffPtr += 2;
1103         tmp_RxXferCount--;
1104       }
1105       else
1106       {
1107         /* Receive data in 16 Bit mode */
1108 #if defined (__GNUC__)
1109         *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
1110 #else
1111         *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
1112 #endif /* __GNUC__ */
1113         hi2s->pRxBuffPtr++;
1114         tmp_RxXferCount--;
1115       }
1116     }
1117 
1118     /* Timeout management */
1119     if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1120     {
1121       /* Set the error code */
1122       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1123       hi2s->State = HAL_I2S_STATE_READY;
1124       __HAL_UNLOCK(hi2s);
1125       return HAL_TIMEOUT;
1126     }
1127   }
1128 
1129   hi2s->State = HAL_I2S_STATE_READY;
1130   __HAL_UNLOCK(hi2s);
1131   return HAL_OK;
1132 }
1133 
1134 /**
1135   * @brief  Transmit an amount of data in non-blocking mode with Interrupt
1136   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1137   *         the configuration information for I2S module
1138   * @param  pData a 16-bit pointer to data buffer.
1139   * @param  Size number of data sample to be sent:
1140   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1141   *         configuration phase, the Size parameter means the number of 16-bit data length
1142   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1143   *         the Size parameter means the number of 16-bit data length.
1144   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1145   *         between Master and Slave(example: audio streaming).
1146   * @retval HAL status
1147   */
HAL_I2S_Transmit_IT(I2S_HandleTypeDef * hi2s,const uint16_t * pData,uint16_t Size)1148 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size)
1149 {
1150   if ((pData == NULL) || (Size == 0UL))
1151   {
1152     return  HAL_ERROR;
1153   }
1154 
1155   if (hi2s->State != HAL_I2S_STATE_READY)
1156   {
1157     return HAL_BUSY;
1158   }
1159 
1160   /* Process Locked */
1161   __HAL_LOCK(hi2s);
1162 
1163   /* Set state and reset error code */
1164   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
1165   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1166   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
1167   hi2s->TxXferSize  = Size;
1168   hi2s->TxXferCount = Size;
1169 
1170   /* Initialize fields not used in handle to zero */
1171   hi2s->pRxBuffPtr  = NULL;
1172   hi2s->RxXferSize  = (uint16_t) 0UL;
1173   hi2s->RxXferCount = (uint16_t) 0UL;
1174 
1175   /* Set the function for IT treatment */
1176   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1177   {
1178     hi2s->TxISR = I2S_Transmit_32Bit_IT;
1179   }
1180   else
1181   {
1182     hi2s->TxISR = I2S_Transmit_16Bit_IT;
1183   }
1184 
1185   /* Check if the I2S is already enabled */
1186   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1187   {
1188     /* Enable I2S peripheral */
1189     __HAL_I2S_ENABLE(hi2s);
1190   }
1191 
1192   /* Enable TXP interrupt */
1193   __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_TXP);
1194 
1195 #if (USE_I2S_OVR_UDR_ERRORS != 0UL)
1196   /* Enable UDR interrupt */
1197   __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_UDR);
1198 #endif /* USE_I2S_OVR_UDR_ERRORS */
1199 
1200   /* Enable TIFRE interrupt if the mode is Slave  */
1201   if (hi2s->Init.Mode == I2S_MODE_SLAVE_TX)
1202   {
1203     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1204   }
1205 
1206   /* Start the transfer */
1207   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1208 
1209   __HAL_UNLOCK(hi2s);
1210   return HAL_OK;
1211 }
1212 
1213 /**
1214   * @brief  Receive an amount of data in non-blocking mode with Interrupt
1215   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1216   *         the configuration information for I2S module
1217   * @param  pData a 16-bit pointer to the Receive data buffer.
1218   * @param  Size number of data sample to be sent:
1219   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1220   *         configuration phase, the Size parameter means the number of 16-bit data length
1221   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1222   *         the Size parameter means the number of 16-bit data length.
1223   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1224   *         between Master and Slave(example: audio streaming).
1225   * @note   It is recommended to use DMA for the I2S receiver to avoid de-synchronization
1226   * between Master and Slave otherwise the I2S interrupt should be optimized.
1227   * @retval HAL status
1228   */
HAL_I2S_Receive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1229 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1230 {
1231   if ((pData == NULL) || (Size == 0UL))
1232   {
1233     return  HAL_ERROR;
1234   }
1235 
1236   if (hi2s->State != HAL_I2S_STATE_READY)
1237   {
1238     return HAL_BUSY;
1239   }
1240 
1241   /* Process Locked */
1242   __HAL_LOCK(hi2s);
1243 
1244   /* Set state and reset error code */
1245   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
1246   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1247   hi2s->pRxBuffPtr  = pData;
1248   hi2s->RxXferSize  = Size;
1249   hi2s->RxXferCount = Size;
1250 
1251   /* Initialize fields not used in handle to zero */
1252   hi2s->pTxBuffPtr  = NULL;
1253   hi2s->TxXferSize  = (uint16_t) 0UL;
1254   hi2s->TxXferCount = (uint16_t) 0UL;
1255 
1256   /* Set the function for IT treatment */
1257   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1258   {
1259     hi2s->RxISR = I2S_Receive_32Bit_IT;
1260   }
1261   else
1262   {
1263     hi2s->RxISR = I2S_Receive_16Bit_IT;
1264   }
1265 
1266   /* Check if the I2S is already enabled */
1267   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1268   {
1269     /* Enable I2S peripheral */
1270     __HAL_I2S_ENABLE(hi2s);
1271   }
1272   /* Enable RXP interrupt */
1273   __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_RXP);
1274 
1275 #if (USE_I2S_OVR_UDR_ERRORS != 0UL)
1276   /* Enable OVR interrupt */
1277   __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_OVR);
1278 #endif /* USE_I2S_OVR_UDR_ERRORS */
1279 
1280   /* Enable TIFRE interrupt if the mode is Slave  */
1281   if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
1282   {
1283     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1284   }
1285 
1286   /* Start the transfer */
1287   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1288 
1289   __HAL_UNLOCK(hi2s);
1290   return HAL_OK;
1291 }
1292 
1293 /**
1294   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
1295   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1296   *         the configuration information for I2S module
1297   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1298   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1299   * @param  Size number of data sample to be sent:
1300   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1301   *         configuration phase, the Size parameter means the number of 16-bit data length
1302   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1303   *         the Size parameter means the number of 16-bit data length.
1304   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1305   *         between Master and Slave(example: audio streaming).
1306   * @retval HAL status
1307   */
HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef * hi2s,const uint16_t * pTxData,uint16_t * pRxData,uint16_t Size)1308 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1309                                                uint16_t Size)
1310 {
1311   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1312   {
1313     return  HAL_ERROR;
1314   }
1315 
1316   if (hi2s->State != HAL_I2S_STATE_READY)
1317   {
1318     return HAL_BUSY;
1319   }
1320 
1321   /* Process Locked */
1322   __HAL_LOCK(hi2s);
1323 
1324   hi2s->pTxBuffPtr  = (const uint16_t *)pTxData;
1325   hi2s->pRxBuffPtr  = pRxData;
1326 
1327   hi2s->TxXferSize  = Size;
1328   hi2s->TxXferCount = Size;
1329   hi2s->RxXferSize  = Size;
1330   hi2s->RxXferCount = Size;
1331 
1332   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1333   hi2s->State     = HAL_I2S_STATE_BUSY_TX_RX;
1334 
1335 
1336   /* Set the function for IT treatment */
1337   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1338   {
1339     hi2s->TxISR = I2S_Transmit_32Bit_IT;
1340     hi2s->RxISR = I2S_Receive_32Bit_IT;
1341   }
1342   else
1343   {
1344     hi2s->TxISR = I2S_Transmit_16Bit_IT;
1345     hi2s->RxISR = I2S_Receive_16Bit_IT;
1346   }
1347 
1348   /* Check if the I2S is already enabled */
1349   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1350   {
1351     /* Enable I2S peripheral */
1352     __HAL_I2S_ENABLE(hi2s);
1353   }
1354 
1355   /* Enable TXP, RXP, DXP interrupts */
1356   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP));
1357 
1358 #if (USE_I2S_OVR_UDR_ERRORS != 0UL)
1359   /* Enable UDR, OVR interrupts */
1360   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_UDR | I2S_IT_OVR));
1361 #endif /* USE_I2S_OVR_UDR_ERRORS */
1362 
1363   /* Enable TIFRE interrupt if the mode is Slave  */
1364   if (hi2s->Init.Mode == I2S_MODE_SLAVE_FULLDUPLEX)
1365   {
1366     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1367   }
1368 
1369   /* Start the transfer */
1370   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1371 
1372   __HAL_UNLOCK(hi2s);
1373   return HAL_OK;
1374 
1375 }
1376 
1377 /**
1378   * @brief  Transmit an amount of data in non-blocking mode with DMA
1379   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1380   *         the configuration information for I2S module
1381   * @param  pData a 16-bit pointer to the Transmit data buffer.
1382   * @param  Size number of data sample to be sent:
1383   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1384   *         configuration phase, the Size parameter means the number of 16-bit data length
1385   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1386   *         the Size parameter means the number of 16-bit data length.
1387   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1388   *         between Master and Slave(example: audio streaming).
1389   * @retval HAL status
1390   */
HAL_I2S_Transmit_DMA(I2S_HandleTypeDef * hi2s,const uint16_t * pData,uint16_t Size)1391 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size)
1392 {
1393   HAL_StatusTypeDef errorcode;
1394 
1395   if ((pData == NULL) || (Size == 0UL))
1396   {
1397     return  HAL_ERROR;
1398   }
1399 
1400   if (hi2s->State != HAL_I2S_STATE_READY)
1401   {
1402     return HAL_BUSY;
1403   }
1404 
1405   /* Process Locked */
1406   __HAL_LOCK(hi2s);
1407 
1408   /* Set state and reset error code */
1409   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
1410   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1411   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
1412   hi2s->TxXferSize  = Size;
1413   hi2s->TxXferCount = Size;
1414 
1415   /* Init field not used in handle to zero */
1416   hi2s->pRxBuffPtr  = NULL;
1417   hi2s->RxXferSize  = (uint16_t)0UL;
1418   hi2s->RxXferCount = (uint16_t)0UL;
1419 
1420   /* Set the I2S Tx DMA Half transfer complete callback */
1421   hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
1422 
1423   /* Set the I2S Tx DMA transfer complete callback */
1424   hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
1425 
1426   /* Set the DMA error callback */
1427   hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
1428 
1429   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B_EXTENDED))
1430   {
1431     hi2s->TxXferCount = Size * 2U;
1432   }
1433   else
1434   {
1435     hi2s->TxXferCount = Size * 4U;
1436   }
1437 
1438   /* Enable the Tx DMA Stream/Channel */
1439   if ((hi2s->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1440   {
1441     if (hi2s->hdmatx->LinkedListQueue != NULL)
1442     {
1443       /* Set DMA data size */
1444       hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2s->TxXferCount;
1445 
1446       /* Set DMA source address */
1447       hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hi2s->pTxBuffPtr;
1448 
1449       /* Set DMA destination address */
1450       hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hi2s->Instance->TXDR;
1451 
1452       errorcode = HAL_DMAEx_List_Start_IT(hi2s->hdmatx);
1453     }
1454     else
1455     {
1456       /* Update SPI error code */
1457       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1458 
1459       /* Unlock the process */
1460       __HAL_UNLOCK(hi2s);
1461 
1462       hi2s->State = HAL_I2S_STATE_READY;
1463       errorcode = HAL_ERROR;
1464       return errorcode;
1465     }
1466   }
1467   else
1468   {
1469     errorcode = HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR,
1470                                  hi2s->TxXferCount);
1471   }
1472 
1473   /* Check status */
1474   if (errorcode != HAL_OK)
1475   {
1476     /* Update I2S error code */
1477     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1478     hi2s->State = HAL_I2S_STATE_READY;
1479 
1480     __HAL_UNLOCK(hi2s);
1481     errorcode = HAL_ERROR;
1482     return errorcode;
1483   }
1484 
1485 #if (USE_I2S_OVR_UDR_ERRORS != 0UL)
1486   /* Enable UDR interrupt */
1487   __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_UDR);
1488 #endif /* USE_I2S_OVR_UDR_ERRORS */
1489 
1490   /* Check if the I2S Tx request is already enabled */
1491   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
1492   {
1493     /* Enable Tx DMA Request */
1494     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1495   }
1496 
1497   /* Check if the I2S is already enabled */
1498   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1499   {
1500     /* Enable I2S peripheral */
1501     __HAL_I2S_ENABLE(hi2s);
1502   }
1503 
1504   /* Start the transfer */
1505   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1506 
1507   __HAL_UNLOCK(hi2s);
1508   return errorcode;
1509 }
1510 
1511 /**
1512   * @brief  Receive an amount of data in non-blocking mode with DMA
1513   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1514   *         the configuration information for I2S module
1515   * @param  pData a 16-bit pointer to the Receive data buffer.
1516   * @param  Size number of data sample to be sent:
1517   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1518   *         configuration phase, the Size parameter means the number of 16-bit data length
1519   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1520   *         the Size parameter means the number of 16-bit data length.
1521   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1522   *         between Master and Slave(example: audio streaming).
1523   * @retval HAL status
1524   */
HAL_I2S_Receive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1525 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1526 {
1527   HAL_StatusTypeDef errorcode;
1528 
1529   if ((pData == NULL) || (Size == 0UL))
1530   {
1531     return HAL_ERROR;
1532   }
1533 
1534   if (hi2s->State != HAL_I2S_STATE_READY)
1535   {
1536     return HAL_BUSY;
1537   }
1538 
1539   /* Process Locked */
1540   __HAL_LOCK(hi2s);
1541 
1542   /* Set state and reset error code */
1543   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
1544   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1545   hi2s->pRxBuffPtr  = pData;
1546   hi2s->RxXferSize  = Size;
1547   hi2s->RxXferCount = Size;
1548 
1549   /* Init field not used in handle to zero */
1550   hi2s->pTxBuffPtr  = NULL;
1551   hi2s->TxXferSize  = (uint16_t)0UL;
1552   hi2s->TxXferCount = (uint16_t)0UL;
1553 
1554 
1555   /* Set the I2S Rx DMA Half transfer complete callback */
1556   hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
1557 
1558   /* Set the I2S Rx DMA transfer complete callback */
1559   hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
1560 
1561   /* Set the DMA error callback */
1562   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1563 
1564   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B_EXTENDED))
1565   {
1566     hi2s->RxXferCount = Size * 2U;
1567   }
1568   else
1569   {
1570     hi2s->RxXferCount = Size * 4U;
1571   }
1572 
1573   /* Enable the Rx DMA Stream/Channel */
1574   if ((hi2s->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1575   {
1576     if (hi2s->hdmarx->LinkedListQueue != NULL)
1577     {
1578       /* Set DMA data size */
1579       hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2s->RxXferCount;
1580 
1581       /* Set DMA source address */
1582       hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hi2s->Instance->RXDR;
1583 
1584       /* Set DMA destination address */
1585       hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hi2s->pRxBuffPtr;
1586 
1587       errorcode = HAL_DMAEx_List_Start_IT(hi2s->hdmarx);
1588     }
1589     else
1590     {
1591       /* Update SPI error code */
1592       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1593 
1594       /* Unlock the process */
1595       __HAL_UNLOCK(hi2s);
1596 
1597       hi2s->State = HAL_I2S_STATE_READY;
1598       errorcode = HAL_ERROR;
1599       return errorcode;
1600     }
1601   }
1602   else
1603   {
1604     errorcode = HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr,
1605                                  hi2s->RxXferCount);
1606   }
1607 
1608   /* Check status */
1609   if (errorcode != HAL_OK)
1610   {
1611     /* Update I2S error code */
1612     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1613     hi2s->State = HAL_I2S_STATE_READY;
1614     errorcode = HAL_ERROR;
1615     __HAL_UNLOCK(hi2s);
1616     return errorcode;
1617   }
1618 
1619 #if (USE_I2S_OVR_UDR_ERRORS != 0UL)
1620   /* Enable OVR interrupts */
1621   __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_OVR);
1622 #endif /* USE_I2S_OVR_UDR_ERRORS */
1623 
1624   /* Check if the I2S Rx request is already enabled */
1625   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
1626   {
1627     /* Enable Rx DMA Request */
1628     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1629   }
1630 
1631   /* Check if the I2S is already enabled */
1632   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1633   {
1634     /* Enable I2S peripheral */
1635     __HAL_I2S_ENABLE(hi2s);
1636   }
1637 
1638   /* Start the transfer */
1639   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1640 
1641   __HAL_UNLOCK(hi2s);
1642   return errorcode;
1643 }
1644 
1645 /**
1646   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using DMA
1647   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1648   *         the configuration information for I2S module
1649   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1650   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1651   * @param  Size number of data sample to be sent:
1652   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1653   *         configuration phase, the Size parameter means the number of 16-bit data length
1654   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1655   *         the Size parameter means the number of 16-bit data length.
1656   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1657   *         between Master and Slave(example: audio streaming).
1658   * @retval HAL status
1659   */
HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef * hi2s,const uint16_t * pTxData,uint16_t * pRxData,uint16_t Size)1660 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1661                                                 uint16_t Size)
1662 {
1663   HAL_StatusTypeDef errorcode;
1664 
1665 
1666   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1667   {
1668     return  HAL_ERROR;
1669   }
1670 
1671   if (hi2s->State != HAL_I2S_STATE_READY)
1672   {
1673     return HAL_BUSY;
1674   }
1675 
1676   /* Process Locked */
1677   __HAL_LOCK(hi2s);
1678 
1679   hi2s->pTxBuffPtr = (const uint16_t *)pTxData;
1680   hi2s->pRxBuffPtr = pRxData;
1681 
1682   hi2s->TxXferSize  = Size;
1683   hi2s->TxXferCount = Size;
1684   hi2s->RxXferSize  = Size;
1685   hi2s->RxXferCount = Size;
1686 
1687   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1688   hi2s->State       = HAL_I2S_STATE_BUSY_TX_RX;
1689 
1690   /* Reset the Tx/Rx DMA bits */
1691   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
1692 
1693   /* Set the I2S Rx DMA Half transfer complete callback */
1694   hi2s->hdmarx->XferHalfCpltCallback = I2SEx_DMATxRxHalfCplt;
1695 
1696   /* Set the I2S Rx DMA transfer complete callback */
1697   hi2s->hdmarx->XferCpltCallback  = I2SEx_DMATxRxCplt;
1698 
1699   /* Set the I2S Rx DMA error callback */
1700   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1701   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B_EXTENDED))
1702   {
1703     hi2s->TxXferCount = Size * 2U;
1704   }
1705   else
1706   {
1707     hi2s->TxXferCount = Size * 4U;
1708   }
1709 
1710   /* Enable the Tx DMA Stream/Channel */
1711   if ((hi2s->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1712   {
1713     if (hi2s->hdmatx->LinkedListQueue != NULL)
1714     {
1715       /* Set DMA data size */
1716       hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2s->TxXferCount;
1717 
1718       /* Set DMA source address */
1719       hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hi2s->pTxBuffPtr;
1720 
1721       /* Set DMA destination address */
1722       hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hi2s->Instance->TXDR;
1723 
1724       errorcode = HAL_DMAEx_List_Start_IT(hi2s->hdmatx);
1725     }
1726     else
1727     {
1728       /* Update SPI error code */
1729       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1730 
1731       /* Unlock the process */
1732       __HAL_UNLOCK(hi2s);
1733 
1734       hi2s->State = HAL_I2S_STATE_READY;
1735       errorcode = HAL_ERROR;
1736       return errorcode;
1737     }
1738   }
1739   else
1740   {
1741     errorcode = HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR,
1742                                  hi2s->TxXferCount);
1743   }
1744 
1745   /* Check status */
1746   if (errorcode != HAL_OK)
1747   {
1748     /* Update I2S error code */
1749     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1750     hi2s->State = HAL_I2S_STATE_READY;
1751 
1752     __HAL_UNLOCK(hi2s);
1753     errorcode = HAL_ERROR;
1754     return errorcode;
1755   }
1756 
1757   /* Check if the I2S Tx request is already enabled */
1758   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
1759   {
1760     /* Enable Tx DMA Request */
1761     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1762   }
1763 
1764   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B_EXTENDED))
1765   {
1766     hi2s->RxXferCount = Size * 2U;
1767   }
1768   else
1769   {
1770     hi2s->RxXferCount = Size * 4U;
1771   }
1772 
1773   /* Enable the Rx DMA Stream/Channel */
1774   if ((hi2s->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1775   {
1776     if (hi2s->hdmarx->LinkedListQueue != NULL)
1777     {
1778       /* Set DMA data size */
1779       hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2s->RxXferCount;
1780 
1781       /* Set DMA source address */
1782       hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hi2s->Instance->RXDR;
1783 
1784       /* Set DMA destination address */
1785       hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hi2s->pRxBuffPtr;
1786 
1787       errorcode = HAL_DMAEx_List_Start_IT(hi2s->hdmarx);
1788     }
1789     else
1790     {
1791       /* Update SPI error code */
1792       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1793 
1794       /* Unlock the process */
1795       __HAL_UNLOCK(hi2s);
1796 
1797       hi2s->State = HAL_I2S_STATE_READY;
1798       errorcode = HAL_ERROR;
1799       return errorcode;
1800     }
1801   }
1802   else
1803   {
1804     errorcode = HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr,
1805                                  hi2s->RxXferCount);
1806   }
1807 
1808   /* Check status */
1809   if (errorcode != HAL_OK)
1810   {
1811     /* Update I2S error code */
1812     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1813     hi2s->State = HAL_I2S_STATE_READY;
1814     errorcode = HAL_ERROR;
1815     __HAL_UNLOCK(hi2s);
1816     return errorcode;
1817   }
1818 
1819 #if (USE_I2S_OVR_UDR_ERRORS != 0UL)
1820   /* Enable UDR, OVR interrupts */
1821   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_UDR | I2S_IT_OVR));
1822 #endif /* USE_I2S_OVR_UDR_ERRORS */
1823 
1824   /* Check if the I2S Rx request is already enabled */
1825   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
1826   {
1827     /* Enable Rx DMA Request */
1828     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1829   }
1830 
1831   /* Check if the I2S is already enabled */
1832   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1833   {
1834     /* Enable I2S peripheral */
1835     __HAL_I2S_ENABLE(hi2s);
1836   }
1837 
1838   /* Start the transfer */
1839   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1840 
1841   __HAL_UNLOCK(hi2s);
1842   return errorcode;
1843 }
1844 
1845 /**
1846   * @brief  Pauses the audio DMA Stream/Channel playing from the Media.
1847   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1848   *         the configuration information for I2S module
1849   * @retval HAL status
1850   */
HAL_I2S_DMAPause(I2S_HandleTypeDef * hi2s)1851 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1852 {
1853   /* Process Locked */
1854   __HAL_LOCK(hi2s);
1855 
1856   uint32_t tickstart;
1857 
1858   /* Get tick */
1859   tickstart = HAL_GetTick();
1860 
1861 
1862   /* Check if the I2S peripheral is in master mode */
1863   if (IS_I2S_MASTER(hi2s->Init.Mode))
1864   {
1865     /* Check if there is a transfer on-going */
1866     if (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) == 0UL)
1867     {
1868       /* Set error code to no on going transfer */
1869       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NO_OGT);
1870       hi2s->State = HAL_I2S_STATE_READY;
1871 
1872       __HAL_UNLOCK(hi2s);
1873       return HAL_ERROR;
1874     }
1875 
1876     SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSUSP);
1877 
1878     while (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) != 0UL)
1879     {
1880       if ((((HAL_GetTick() - tickstart) >=  I2S_TIMEOUT) && (I2S_TIMEOUT != HAL_MAX_DELAY)) || (I2S_TIMEOUT == 0U))
1881       {
1882         /* Set the I2S State ready */
1883         hi2s->State = HAL_I2S_STATE_READY;
1884 
1885         /* Process Unlocked */
1886         __HAL_UNLOCK(hi2s);
1887 
1888         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1889         hi2s->State = HAL_I2S_STATE_READY;
1890         return HAL_TIMEOUT;
1891       }
1892     }
1893 
1894     /* Disable I2S peripheral */
1895     __HAL_I2S_DISABLE(hi2s);
1896 
1897     hi2s->State = HAL_I2S_STATE_READY;
1898 
1899     /* Process Unlocked */
1900     __HAL_UNLOCK(hi2s);
1901 
1902     return HAL_OK;
1903   }
1904   else
1905   {
1906     /* Set error code to not supported */
1907     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NOT_SUPPORTED);
1908     hi2s->State = HAL_I2S_STATE_READY;
1909 
1910     /* Process Unlocked */
1911     __HAL_UNLOCK(hi2s);
1912 
1913     return HAL_ERROR;
1914   }
1915 }
1916 
1917 /**
1918   * @brief  Resumes the audio DMA Stream/Channel playing from the Media.
1919   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1920   *         the configuration information for I2S module
1921   * @retval HAL status
1922   */
HAL_I2S_DMAResume(I2S_HandleTypeDef * hi2s)1923 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1924 {
1925   /* Process Locked */
1926   __HAL_LOCK(hi2s);
1927 
1928   if (hi2s->State != HAL_I2S_STATE_READY)
1929   {
1930     hi2s->State = HAL_I2S_STATE_READY;
1931 
1932     __HAL_UNLOCK(hi2s);
1933     return HAL_ERROR;
1934   }
1935 
1936   /* Set state and reset error code */
1937   hi2s->State       = HAL_I2S_STATE_BUSY;
1938   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1939 
1940   /* Enable I2S peripheral */
1941   __HAL_I2S_ENABLE(hi2s);
1942 
1943   /* Start the transfer */
1944   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1945 
1946   /* Process Unlocked */
1947   __HAL_UNLOCK(hi2s);
1948 
1949   return HAL_OK;
1950 }
1951 
1952 /**
1953   * @brief  Stops the audio DMA Stream/Channel playing from the Media.
1954   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1955   *         the configuration information for I2S module
1956   * @retval HAL status
1957   */
HAL_I2S_DMAStop(I2S_HandleTypeDef * hi2s)1958 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1959 {
1960   HAL_StatusTypeDef errorcode = HAL_OK;
1961   /* The Lock is not implemented on this API to allow the user application
1962      to call the HAL I2S API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1963      when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1964      and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1965      */
1966 
1967   /* Disable the I2S Tx/Rx DMA requests */
1968   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1969   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1970 
1971   /* Abort the I2S DMA tx Stream/Channel */
1972   if (hi2s->hdmatx != NULL)
1973   {
1974     /* Disable the I2S DMA tx Stream/Channel */
1975     if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1976     {
1977       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1978       errorcode = HAL_ERROR;
1979     }
1980   }
1981 
1982   /* Abort the I2S DMA rx Stream/Channel */
1983   if (hi2s->hdmarx != NULL)
1984   {
1985     /* Disable the I2S DMA rx Stream/Channel */
1986     if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1987     {
1988       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1989       errorcode = HAL_ERROR;
1990     }
1991   }
1992 
1993   /* Disable I2S peripheral */
1994   __HAL_I2S_DISABLE(hi2s);
1995 
1996   hi2s->State = HAL_I2S_STATE_READY;
1997 
1998   return errorcode;
1999 }
2000 
2001 /**
2002   * @brief  This function handles I2S interrupt request.
2003   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2004   *         the configuration information for I2S module
2005   * @retval None
2006   */
HAL_I2S_IRQHandler(I2S_HandleTypeDef * hi2s)2007 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
2008 {
2009   uint32_t i2sier   = hi2s->Instance->IER;
2010   uint32_t i2ssr    = hi2s->Instance->SR;
2011   uint32_t trigger  = i2sier & i2ssr;
2012 
2013   /* I2S in mode Transmitter -----------------------------------------------*/
2014   if (HAL_IS_BIT_SET(trigger, I2S_FLAG_DXP))
2015   {
2016     hi2s->TxISR(hi2s);
2017     hi2s->RxISR(hi2s);
2018   }
2019   /* I2S in mode Receiver ------------------------------------------------*/
2020   if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP))
2021   {
2022     hi2s->RxISR(hi2s);
2023   }
2024   /* I2S in mode Transmitter -----------------------------------------------*/
2025   if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP))
2026   {
2027     hi2s->TxISR(hi2s);
2028   }
2029 #if (USE_I2S_OVR_UDR_ERRORS != 0UL)
2030   /* I2S Underrun error interrupt occurred --------------------------------*/
2031   if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR))
2032   {
2033     /* Disable TXP, RXP and ERR interrupt */
2034     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_ERR));
2035 
2036     /* Clear Underrun flag */
2037     __HAL_I2S_CLEAR_UDRFLAG(hi2s);
2038 
2039     /* Set the I2S State ready */
2040     hi2s->State = HAL_I2S_STATE_READY;
2041 
2042     /* Set the error code and execute error callback*/
2043     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
2044     /* Call user error callback */
2045 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2046     hi2s->ErrorCallback(hi2s);
2047 #else
2048     HAL_I2S_ErrorCallback(hi2s);
2049 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2050   }
2051 
2052   /* I2S Overrun error interrupt occurred -------------------------------------*/
2053   if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR))
2054   {
2055     /* Disable TXP, RXP and ERR interrupt */
2056     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_ERR));
2057 
2058     /* Clear Overrun flag */
2059     __HAL_I2S_CLEAR_OVRFLAG(hi2s);
2060 
2061     /* Set the I2S State ready */
2062     hi2s->State = HAL_I2S_STATE_READY;
2063 
2064 
2065     /* Set the error code and execute error callback*/
2066     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
2067 
2068     /* Call user error callback */
2069 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2070     hi2s->ErrorCallback(hi2s);
2071 #else
2072     HAL_I2S_ErrorCallback(hi2s);
2073 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2074   }
2075 #endif /* USE_I2S_OVR_UDR_ERRORS */
2076 }
2077 
2078 /**
2079   * @brief  Tx Transfer Half completed callbacks
2080   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2081   *         the configuration information for I2S module
2082   * @retval None
2083   */
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef * hi2s)2084 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2085 {
2086   /* Prevent unused argument(s) compilation warning */
2087   UNUSED(hi2s);
2088 
2089   /* NOTE : This function Should not be modified, when the callback is needed,
2090             the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
2091    */
2092 }
2093 
2094 /**
2095   * @brief  Tx Transfer completed callbacks
2096   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2097   *         the configuration information for I2S module
2098   * @retval None
2099   */
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef * hi2s)2100 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
2101 {
2102   /* Prevent unused argument(s) compilation warning */
2103   UNUSED(hi2s);
2104 
2105   /* NOTE : This function Should not be modified, when the callback is needed,
2106             the HAL_I2S_TxCpltCallback could be implemented in the user file
2107    */
2108 }
2109 
2110 /**
2111   * @brief  Rx Transfer half completed callbacks
2112   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2113   *         the configuration information for I2S module
2114   * @retval None
2115   */
HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef * hi2s)2116 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2117 {
2118   /* Prevent unused argument(s) compilation warning */
2119   UNUSED(hi2s);
2120 
2121   /* NOTE : This function Should not be modified, when the callback is needed,
2122             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
2123    */
2124 }
2125 
2126 /**
2127   * @brief  Rx Transfer completed callbacks
2128   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2129   *         the configuration information for I2S module
2130   * @retval None
2131   */
HAL_I2S_RxCpltCallback(I2S_HandleTypeDef * hi2s)2132 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
2133 {
2134   /* Prevent unused argument(s) compilation warning */
2135   UNUSED(hi2s);
2136 
2137   /* NOTE : This function Should not be modified, when the callback is needed,
2138             the HAL_I2S_RxCpltCallback could be implemented in the user file
2139    */
2140 }
2141 
2142 /**
2143   * @brief  Rx Transfer half completed callbacks
2144   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2145   *         the configuration information for I2S module
2146   * @retval None
2147   */
HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef * hi2s)2148 __weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2149 {
2150   /* Prevent unused argument(s) compilation warning */
2151   UNUSED(hi2s);
2152 
2153   /* NOTE : This function Should not be modified, when the callback is needed,
2154             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
2155    */
2156 }
2157 
2158 /**
2159   * @brief  Rx Transfer completed callbacks
2160   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2161   *         the configuration information for I2S module
2162   * @retval None
2163   */
HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef * hi2s)2164 __weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
2165 {
2166   /* Prevent unused argument(s) compilation warning */
2167   UNUSED(hi2s);
2168 
2169   /* NOTE : This function Should not be modified, when the callback is needed,
2170             the HAL_I2S_RxCpltCallback could be implemented in the user file
2171    */
2172 }
2173 
2174 /**
2175   * @brief  I2S error callbacks
2176   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2177   *         the configuration information for I2S module
2178   * @retval None
2179   */
HAL_I2S_ErrorCallback(I2S_HandleTypeDef * hi2s)2180 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
2181 {
2182   /* Prevent unused argument(s) compilation warning */
2183   UNUSED(hi2s);
2184 
2185   /* NOTE : This function Should not be modified, when the callback is needed,
2186             the HAL_I2S_ErrorCallback could be implemented in the user file
2187    */
2188 }
2189 
2190 /**
2191   * @}
2192   */
2193 
2194 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
2195   *  @brief   Peripheral State functions
2196   *
2197 @verbatim
2198  ===============================================================================
2199                       ##### Peripheral State and Errors functions #####
2200  ===============================================================================
2201     [..]
2202     This subsection permits to get in run-time the status of the peripheral
2203     and the data flow.
2204 
2205 @endverbatim
2206   * @{
2207   */
2208 
2209 /**
2210   * @brief  Return the I2S state
2211   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2212   *         the configuration information for I2S module
2213   * @retval HAL state
2214   */
HAL_I2S_GetState(const I2S_HandleTypeDef * hi2s)2215 HAL_I2S_StateTypeDef HAL_I2S_GetState(const I2S_HandleTypeDef *hi2s)
2216 {
2217   return hi2s->State;
2218 }
2219 
2220 /**
2221   * @brief  Return the I2S error code
2222   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2223   *         the configuration information for I2S module
2224   * @retval I2S Error Code
2225   */
HAL_I2S_GetError(const I2S_HandleTypeDef * hi2s)2226 uint32_t HAL_I2S_GetError(const I2S_HandleTypeDef *hi2s)
2227 {
2228   return hi2s->ErrorCode;
2229 }
2230 /**
2231   * @}
2232   */
2233 
2234 /**
2235   * @}
2236   */
2237 
2238 /** @addtogroup I2S_Private_Functions
2239   * @{
2240   */
2241 /**
2242   * @brief  DMA I2S transmit process complete callback
2243   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2244   *                the configuration information for the specified DMA module.
2245   * @retval None
2246   */
I2S_DMATxCplt(DMA_HandleTypeDef * hdma)2247 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
2248 {
2249   /* Derogation MISRAC2012-Rule-11.5 */
2250   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2251 
2252   /* if DMA is configured in DMA_NORMAL Mode */
2253   if (hdma->Init.Mode == DMA_NORMAL)
2254   {
2255     /* Disable Tx DMA Request */
2256     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
2257 
2258     hi2s->TxXferCount = (uint16_t) 0UL;
2259     hi2s->State = HAL_I2S_STATE_READY;
2260   }
2261   /* Call user Tx complete callback */
2262 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2263   hi2s->TxCpltCallback(hi2s);
2264 #else
2265   HAL_I2S_TxCpltCallback(hi2s);
2266 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2267 }
2268 
2269 /**
2270   * @brief  DMA I2S transmit process half complete callback
2271   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2272   *         the configuration information for the specified DMA module.
2273   * @retval None
2274   */
I2S_DMATxHalfCplt(DMA_HandleTypeDef * hdma)2275 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2276 {
2277   /* Derogation MISRAC2012-Rule-11.5 */
2278   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2279 
2280   /* Call user Tx half complete callback */
2281 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2282   hi2s->TxHalfCpltCallback(hi2s);
2283 #else
2284   HAL_I2S_TxHalfCpltCallback(hi2s);
2285 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2286 }
2287 
2288 /**
2289   * @brief  DMA I2S receive process complete callback
2290   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2291   *         the configuration information for the specified DMA module.
2292   * @retval None
2293   */
I2S_DMARxCplt(DMA_HandleTypeDef * hdma)2294 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
2295 {
2296   /* Derogation MISRAC2012-Rule-11.5 */
2297   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2298 
2299   /* if DMA is configured in DMA_NORMAL Mode */
2300   if (hdma->Init.Mode == DMA_NORMAL)
2301   {
2302     /* Disable Rx DMA Request */
2303     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
2304     hi2s->RxXferCount = (uint16_t)0UL;
2305     hi2s->State = HAL_I2S_STATE_READY;
2306   }
2307   /* Call user Rx complete callback */
2308 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2309   hi2s->RxCpltCallback(hi2s);
2310 #else
2311   HAL_I2S_RxCpltCallback(hi2s);
2312 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2313 }
2314 
2315 /**
2316   * @brief  DMA I2S receive process half complete callback
2317   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2318   *         the configuration information for the specified DMA module.
2319   * @retval None
2320   */
I2S_DMARxHalfCplt(DMA_HandleTypeDef * hdma)2321 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2322 {
2323   /* Derogation MISRAC2012-Rule-11.5 */
2324   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2325 
2326   /* Call user Rx half complete callback */
2327 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2328   hi2s->RxHalfCpltCallback(hi2s);
2329 #else
2330   HAL_I2S_RxHalfCpltCallback(hi2s);
2331 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2332 }
2333 
2334 /**
2335   * @brief  DMA I2S transmit receive process complete callback
2336   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2337   *               the configuration information for the specified DMA module.
2338   * @retval None
2339   */
I2SEx_DMATxRxCplt(DMA_HandleTypeDef * hdma)2340 static void I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma)
2341 {
2342   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2343 
2344   /* if DMA is configured in DMA_NORMAL Mode */
2345   if (hdma->Init.Mode == DMA_NORMAL)
2346   {
2347     /* Disable Tx DMA Request */
2348     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
2349     hi2s->TxXferCount = (uint16_t) 0UL;
2350 
2351     /* Disable Rx DMA Request */
2352     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
2353     hi2s->RxXferCount = (uint16_t)0UL;
2354 
2355     /* Updated HAL State */
2356     hi2s->State = HAL_I2S_STATE_READY;
2357   }
2358 
2359   /* Call user TxRx complete callback */
2360 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
2361   hi2s->TxRxCpltCallback(hi2s);
2362 #else
2363   HAL_I2SEx_TxRxCpltCallback(hi2s);
2364 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2365 }
2366 
2367 /**
2368   * @brief  DMA I2S transmit receive process half complete callback
2369   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2370   *               the configuration information for the specified DMA module.
2371   * @retval None
2372   */
I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef * hdma)2373 static void I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma)
2374 {
2375   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2376 
2377   /* Call user TxRx Half complete callback */
2378 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
2379   hi2s->TxRxHalfCpltCallback(hi2s);
2380 #else
2381   HAL_I2SEx_TxRxHalfCpltCallback(hi2s);
2382 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2383 }
2384 
2385 /**
2386   * @brief  DMA I2S communication error callback
2387   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2388   *         the configuration information for the specified DMA module.
2389   * @retval None
2390   */
I2S_DMAError(DMA_HandleTypeDef * hdma)2391 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
2392 {
2393   /* Derogation MISRAC2012-Rule-11.5 */
2394   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2395 
2396   /* Disable Rx and Tx DMA Request */
2397   CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN));
2398   hi2s->TxXferCount = (uint16_t) 0UL;
2399   hi2s->RxXferCount = (uint16_t) 0UL;
2400 
2401   hi2s->State = HAL_I2S_STATE_READY;
2402 
2403   /* Set the error code and execute error callback*/
2404   SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
2405   /* Call user error callback */
2406 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2407   hi2s->ErrorCallback(hi2s);
2408 #else
2409   HAL_I2S_ErrorCallback(hi2s);
2410 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2411 }
2412 
2413 /**
2414   * @brief  Manage the transmission 16-bit in Interrupt context
2415   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2416   *         the configuration information for I2S module
2417   * @retval None
2418   */
I2S_Transmit_16Bit_IT(I2S_HandleTypeDef * hi2s)2419 static void I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s)
2420 {
2421   /* Transmit data */
2422 #if defined (__GNUC__)
2423   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
2424 
2425   *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
2426 #else
2427   *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
2428 #endif /* __GNUC__ */
2429   hi2s->pTxBuffPtr++;
2430   hi2s->TxXferCount--;
2431 
2432   if (hi2s->TxXferCount == 0UL)
2433   {
2434     /* Disable TXP and ERR interrupt */
2435     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
2436 
2437     if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX))
2438     {
2439       hi2s->State = HAL_I2S_STATE_READY;
2440 
2441       /* Call user Tx complete callback */
2442 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2443       hi2s->TxCpltCallback(hi2s);
2444 #else
2445       HAL_I2S_TxCpltCallback(hi2s);
2446 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2447     }
2448   }
2449 }
2450 
2451 /**
2452   * @brief  Manage the transmission 32-bit in Interrupt context
2453   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2454   *         the configuration information for I2S module
2455   * @retval None
2456   */
I2S_Transmit_32Bit_IT(I2S_HandleTypeDef * hi2s)2457 static void I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s)
2458 {
2459   /* Transmit data */
2460   hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
2461   hi2s->pTxBuffPtr += 2;
2462   hi2s->TxXferCount--;
2463 
2464   if (hi2s->TxXferCount == 0UL)
2465   {
2466     /* Disable TXP and ERR interrupt */
2467     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
2468 
2469     if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX))
2470     {
2471       hi2s->State = HAL_I2S_STATE_READY;
2472 
2473       /* Call user Tx complete callback */
2474 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2475       hi2s->TxCpltCallback(hi2s);
2476 #else
2477       HAL_I2S_TxCpltCallback(hi2s);
2478 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2479     }
2480   }
2481 }
2482 
2483 /**
2484   * @brief  Manage the reception 16-bit in Interrupt context
2485   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2486   *         the configuration information for I2S module
2487   * @retval None
2488   */
I2S_Receive_16Bit_IT(I2S_HandleTypeDef * hi2s)2489 static void I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s)
2490 {
2491   /* Receive data */
2492 #if defined (__GNUC__)
2493   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
2494 
2495   *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
2496 #else
2497   *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
2498 #endif /* __GNUC__ */
2499   hi2s->pRxBuffPtr++;
2500   hi2s->RxXferCount--;
2501 
2502   if (hi2s->RxXferCount == 0UL)
2503   {
2504     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2505     {
2506       /* Disable TXP, RXP, DXP, ERR interrupts */
2507       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR));
2508     }
2509     else
2510     {
2511       /* Disable RXP and ERR interrupt */
2512       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
2513     }
2514 
2515     hi2s->State = HAL_I2S_STATE_READY;
2516     /* Call user Rx complete callback */
2517 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2518     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2519     {
2520       hi2s->TxRxCpltCallback(hi2s);
2521     }
2522     else
2523     {
2524       hi2s->RxCpltCallback(hi2s);
2525     }
2526 #else
2527     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2528     {
2529       HAL_I2SEx_TxRxCpltCallback(hi2s);
2530     }
2531     else
2532     {
2533       HAL_I2S_RxCpltCallback(hi2s);
2534     }
2535 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2536   }
2537 }
2538 
2539 /**
2540   * @brief  Manage the reception 32-bit in Interrupt context
2541   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2542   *         the configuration information for I2S module
2543   * @retval None
2544   */
I2S_Receive_32Bit_IT(I2S_HandleTypeDef * hi2s)2545 static void I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s)
2546 {
2547   /* Receive data */
2548   *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
2549   hi2s->pRxBuffPtr += 2;
2550   hi2s->RxXferCount--;
2551 
2552   if (hi2s->RxXferCount == 0UL)
2553   {
2554     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2555     {
2556       /* Disable TXP, RXP, DXP, ERR interrupts */
2557       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR));
2558     }
2559     else
2560     {
2561       /* Disable RXP and ERR interrupt */
2562       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
2563     }
2564 
2565     hi2s->State = HAL_I2S_STATE_READY;
2566     /* Call user Rx complete callback */
2567 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2568     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2569     {
2570       hi2s->TxRxCpltCallback(hi2s);
2571     }
2572     else
2573     {
2574       hi2s->RxCpltCallback(hi2s);
2575     }
2576 #else
2577     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2578     {
2579       HAL_I2SEx_TxRxCpltCallback(hi2s);
2580     }
2581     else
2582     {
2583       HAL_I2S_RxCpltCallback(hi2s);
2584     }
2585 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2586   }
2587 }
2588 
2589 /**
2590   * @brief  This function handles I2S Communication Timeout.
2591   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2592   *         the configuration information for I2S module
2593   * @param  Flag Flag checked
2594   * @param  State Value of the flag expected
2595   * @param  Tickstart Tick start value
2596   * @param  Timeout Duration of the timeout
2597   * @retval HAL status
2598   */
I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,FlagStatus State,uint32_t Tickstart,uint32_t Timeout)2599 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
2600                                                        uint32_t Tickstart, uint32_t Timeout)
2601 {
2602   /* Wait until flag is set to status*/
2603   while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
2604   {
2605     if (Timeout != HAL_MAX_DELAY)
2606     {
2607       if (((HAL_GetTick() - Tickstart) >= Timeout) || (Timeout == 0UL))
2608       {
2609         /* Set the I2S State ready */
2610         hi2s->State = HAL_I2S_STATE_READY;
2611 
2612         /* Process Unlocked */
2613         __HAL_UNLOCK(hi2s);
2614 
2615         return HAL_TIMEOUT;
2616       }
2617     }
2618   }
2619   return HAL_OK;
2620 }
2621 
2622 /**
2623   * @}
2624   */
2625 
2626 /**
2627   * @}
2628   */
2629 
2630 /**
2631   * @}
2632   */
2633 
2634 #endif /* HAL_I2S_MODULE_ENABLED */
2635 
2636