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