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