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