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