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