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