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