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 @verbatim
12 ===============================================================================
13 ##### How to use this driver #####
14 ===============================================================================
15 [..]
16 The I2S HAL driver can be used as follow:
17
18 (#) Declare a I2S_HandleTypeDef handle structure.
19 (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
20 (##) Enable the SPIx interface clock.
21 (##) I2S pins configuration:
22 (+++) Enable the clock for the I2S GPIOs.
23 (+++) Configure these I2S pins as alternate function pull-up.
24 (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
25 and HAL_I2S_Receive_IT() APIs).
26 (+++) Configure the I2Sx interrupt priority.
27 (+++) Enable the NVIC I2S IRQ handle.
28 (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
29 and HAL_I2S_Receive_DMA() APIs:
30 (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel.
31 (+++) Enable the DMAx interface clock.
32 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
33 (+++) Configure the DMA Tx/Rx Stream/Channel.
34 (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
35 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
36 DMA Tx/Rx Stream/Channel.
37
38 (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
39 using HAL_I2S_Init() function.
40
41 -@- The specific I2S interrupts (Transmission complete interrupt,
42 RXNE interrupt and Error Interrupts) will be managed using the macros
43 __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
44
45 (+@) External clock source is configured after setting correctly
46 the define constant EXTERNAL_CLOCK_VALUE in the stm32h7xx_hal_conf.h file.
47
48 (#) Three mode of operations are available within this driver :
49
50 *** Polling mode IO operation ***
51 =================================
52 [..]
53 (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
54 (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
55
56 *** Interrupt mode IO operation ***
57 ===================================
58 [..]
59 (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
60 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
61 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
62 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
63 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
64 (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
65 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
66 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
67 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
68 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
69 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
70 add his own code by customization of function pointer HAL_I2S_ErrorCallback
71
72 *** DMA mode IO operation ***
73 ==============================
74 [..]
75 (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
76 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
77 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
78 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
79 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
80 (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
81 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
82 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
83 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
84 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
85 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
86 add his own code by customization of function pointer HAL_I2S_ErrorCallback
87 (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
88 (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
89 (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
90
91 *** I2S HAL driver macros list ***
92 ===================================
93 [..]
94 Below the list of most used macros in I2S HAL driver.
95
96 (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
97 (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
98 (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
99 (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
100 (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
101
102 [..]
103 (@) You can refer to the I2S HAL driver header file for more useful macros
104
105 *** I2S HAL driver macros list ***
106 ===================================
107 [..]
108 Callback registration:
109
110 (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1UL
111 allows the user to configure dynamically the driver callbacks.
112 Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
113
114 Function HAL_I2S_RegisterCallback() allows to register following callbacks:
115 (+) TxCpltCallback : I2S Tx Completed callback
116 (+) RxCpltCallback : I2S Rx Completed callback
117 (+) TxHalfCpltCallback : I2S Tx Half Completed callback
118 (+) RxHalfCpltCallback : I2S Rx Half Completed callback
119 (+) ErrorCallback : I2S Error callback
120 (+) MspInitCallback : I2S Msp Init callback
121 (+) MspDeInitCallback : I2S Msp DeInit callback
122 This function takes as parameters the HAL peripheral handle, the Callback ID
123 and a pointer to the user callback function.
124
125
126 (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default
127 weak function.
128 HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
129 and the Callback ID.
130 This function allows to reset following callbacks:
131 (+) TxCpltCallback : I2S Tx Completed callback
132 (+) RxCpltCallback : I2S Rx Completed callback
133 (+) TxHalfCpltCallback : I2S Tx Half Completed callback
134 (+) RxHalfCpltCallback : I2S Rx Half Completed callback
135 (+) ErrorCallback : I2S Error callback
136 (+) MspInitCallback : I2S Msp Init callback
137 (+) MspDeInitCallback : I2S Msp DeInit callback
138
139 By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
140 all callbacks are set to the corresponding weak functions:
141 examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
142 Exception done for MspInit and MspDeInit functions that are
143 reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
144 these callbacks are null (not registered beforehand).
145 If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
146 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
147
148 Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
149 Exception done MspInit/MspDeInit functions that can be registered/unregistered
150 in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state,
151 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
152 Then, the user first registers the MspInit/MspDeInit user callbacks
153 using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
154 or HAL_I2S_Init() function.
155
156 When The compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
157 not defined, the callback registering feature is not available
158 and weak (surcharged) callbacks are used.
159
160
161 @endverbatim
162 ******************************************************************************
163 * @attention
164 *
165 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
166 * All rights reserved.</center></h2>
167 *
168 * This software component is licensed by ST under BSD 3-Clause license,
169 * the "License"; You may not use this file except in compliance with the
170 * License. You may obtain a copy of the License at:
171 * opensource.org/licenses/BSD-3-Clause
172 *
173 ******************************************************************************
174 */
175
176 /* Includes ------------------------------------------------------------------*/
177 #include "stm32h7xx_hal.h"
178
179 #ifdef HAL_I2S_MODULE_ENABLED
180
181 /** @addtogroup STM32H7xx_HAL_Driver
182 * @{
183 */
184
185 /** @defgroup I2S I2S
186 * @brief I2S HAL module driver
187 * @{
188 */
189
190 /* Private typedef -----------------------------------------------------------*/
191 /* Private define ------------------------------------------------------------*/
192 /* Private macro -------------------------------------------------------------*/
193 /* Private variables ---------------------------------------------------------*/
194 /* Private function prototypes -----------------------------------------------*/
195 /** @defgroup I2S_Private_Functions I2S Private Functions
196 * @{
197 */
198 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
199 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
200 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
201 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
202 static void I2S_DMAError(DMA_HandleTypeDef *hdma);
203 static void I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s);
204 static void I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s);
205 static void I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s);
206 static void I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s);
207 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
208 uint32_t Timeout);
209 /**
210 * @}
211 */
212
213 /* Exported functions ---------------------------------------------------------*/
214
215 /** @defgroup I2S_Exported_Functions I2S Exported Functions
216 * @{
217 */
218
219 /** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions
220 * @brief Initialization and Configuration functions
221 *
222 @verbatim
223 ===============================================================================
224 ##### Initialization and de-initialization functions #####
225 ===============================================================================
226 [..] This subsection provides a set of functions allowing to initialize and
227 de-initialize the I2Sx peripheral in simplex mode:
228
229 (+) User must Implement HAL_I2S_MspInit() function in which he configures
230 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
231
232 (+) Call the function HAL_I2S_Init() to configure the selected device with
233 the selected configuration:
234 (++) Mode
235 (++) Standard
236 (++) Data Format
237 (++) MCLK Output
238 (++) Audio frequency
239 (++) Polarity
240
241 (+) Call the function HAL_I2S_DeInit() to restore the default configuration
242 of the selected I2Sx peripheral.
243 @endverbatim
244 * @{
245 */
246
247 /**
248 * @brief Initializes the I2S according to the specified parameters
249 * in the I2S_InitTypeDef and create the associated handle.
250 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
251 * the configuration information for I2S module
252 * @retval HAL status
253 */
HAL_I2S_Init(I2S_HandleTypeDef * hi2s)254 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
255 {
256 uint32_t i2sdiv;
257 uint32_t i2sodd;
258 uint32_t packetlength;
259 uint32_t tmp;
260 uint32_t i2sclk;
261 uint32_t ispcm;
262
263 /* Check the I2S handle allocation */
264 if (hi2s == NULL)
265 {
266 return HAL_ERROR;
267 }
268
269 /* Check the I2S parameters */
270 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
271 assert_param(IS_I2S_MODE(hi2s->Init.Mode));
272 assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
273 assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
274 assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
275 assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
276 assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
277 assert_param(IS_I2S_FIRST_BIT(hi2s->Init.FirstBit));
278 assert_param(IS_I2S_WS_INVERSION(hi2s->Init.WSInversion));
279 assert_param(IS_I2S_DATA_24BIT_ALIGNMENT(hi2s->Init.Data24BitAlignment));
280 assert_param(IS_I2S_MASTER_KEEP_IO_STATE(hi2s->Init.MasterKeepIOState));
281
282 if (hi2s->State == HAL_I2S_STATE_RESET)
283 {
284 /* Allocate lock resource and initialize it */
285 hi2s->Lock = HAL_UNLOCKED;
286
287 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
288 /* Init the I2S Callback settings */
289 hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */
290 hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */
291 hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
292 hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
293 hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */
294
295 if (hi2s->MspInitCallback == NULL)
296 {
297 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
298 }
299
300 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
301 hi2s->MspInitCallback(hi2s);
302 #else
303 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
304 HAL_I2S_MspInit(hi2s);
305 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
306 }
307
308 hi2s->State = HAL_I2S_STATE_BUSY;
309
310 /* Disable the selected I2S peripheral */
311 if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE)
312 {
313 /* Disable I2S peripheral */
314 __HAL_I2S_DISABLE(hi2s);
315 }
316
317 /* Clear I2S configuration register */
318 CLEAR_REG(hi2s->Instance->I2SCFGR);
319
320 if (IS_I2S_MASTER(hi2s->Init.Mode))
321 {
322 /*------------------------- I2SDIV and ODD Calculation ---------------------*/
323 /* If the requested audio frequency is not the default, compute the prescaler */
324 if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
325 {
326 /* Check the frame length (For the Prescaler computing) ********************/
327 if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
328 {
329 /* Channel length is 32 bits */
330 packetlength = 2UL;
331 }
332 else
333 {
334 /* Channel length is 16 bits */
335 packetlength = 1UL;
336 }
337
338 /* Check if PCM standard is used */
339 if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) ||
340 (hi2s->Init.Standard == I2S_STANDARD_PCM_LONG))
341 {
342 ispcm = 1UL;
343 }
344 else
345 {
346 ispcm = 0UL;
347 }
348
349 /* Get the source clock value: based on System Clock value */
350 /* SPI1,SPI2 and SPI3 share the same source clock */
351 i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI123);
352
353 /* Compute the Real divider depending on the MCLK output state, with a floating point */
354 if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
355 {
356 /* MCLK output is enabled */
357 tmp = (uint32_t)((((i2sclk / (256UL >> ispcm)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
358 }
359 else
360 {
361 /* MCLK output is disabled */
362 tmp = (uint32_t)((((i2sclk / ((32UL >> ispcm) * packetlength)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
363 }
364
365 /* Remove the flatting point */
366 tmp = tmp / 10UL;
367
368 /* Check the parity of the divider */
369 i2sodd = (uint32_t)(tmp & (uint32_t)1UL);
370
371 /* Compute the i2sdiv prescaler */
372 i2sdiv = (uint32_t)((tmp - i2sodd) / 2UL);
373 }
374 else
375 {
376 /* Set the default values */
377 i2sdiv = 2UL;
378 i2sodd = 0UL;
379 }
380
381 /* Test if the obtain values are forbidden or out of range */
382 if (((i2sodd == 1UL) && (i2sdiv == 1UL)) || (i2sdiv > 0xFFUL))
383 {
384 /* Set the error code */
385 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
386 return HAL_ERROR;
387 }
388
389 /* Force i2smod to 1 just to be sure that (2xi2sdiv + i2sodd) is always higher than 0 */
390 if (i2sdiv == 0UL)
391 {
392 i2sodd = 1UL;
393 }
394
395 MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SDIV | SPI_I2SCFGR_ODD),
396 ((i2sdiv << SPI_I2SCFGR_I2SDIV_Pos) | (i2sodd << SPI_I2SCFGR_ODD_Pos)));
397 }
398
399 /*-------------------------- I2Sx I2SCFGR Configuration --------------------*/
400 /* Configure I2SMOD, I2SCFG, I2SSTD, PCMSYNC, DATLEN ,CHLEN ,CKPOL, WSINV, DATAFMT, I2SDIV, ODD and MCKOE bits bits */
401 /* And configure the I2S with the I2S_InitStruct values */
402 MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG | \
403 SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | \
404 SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN | \
405 SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_WSINV | \
406 SPI_I2SCFGR_DATFMT | SPI_I2SCFGR_MCKOE),
407 (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | \
408 hi2s->Init.Standard | hi2s->Init.DataFormat | \
409 hi2s->Init.CPOL | hi2s->Init.WSInversion | \
410 hi2s->Init.Data24BitAlignment | hi2s->Init.MCLKOutput));
411 /*Clear status register*/
412 WRITE_REG(hi2s->Instance->IFCR, 0x0FF8);
413
414 /*---------------------------- I2Sx CFG2 Configuration ----------------------*/
415
416 /* Unlock the AF configuration to configure CFG2 register*/
417 CLEAR_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK);
418
419 MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_LSBFRST, hi2s->Init.FirstBit);
420
421 /* Insure that AFCNTR is managed only by Master */
422 if (IS_I2S_MASTER(hi2s->Init.Mode))
423 {
424 /* Alternate function GPIOs control */
425 MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_AFCNTR, (hi2s->Init.MasterKeepIOState));
426 }
427
428 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
429 hi2s->State = HAL_I2S_STATE_READY;
430
431 return HAL_OK;
432 }
433
434 /**
435 * @brief DeInitializes the I2S peripheral
436 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
437 * the configuration information for I2S module
438 * @retval HAL status
439 */
HAL_I2S_DeInit(I2S_HandleTypeDef * hi2s)440 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
441 {
442 /* Check the I2S handle allocation */
443 if (hi2s == NULL)
444 {
445 return HAL_ERROR;
446 }
447
448 /* Check the parameters */
449 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
450
451 hi2s->State = HAL_I2S_STATE_BUSY;
452
453 /* Disable the I2S Peripheral Clock */
454 __HAL_I2S_DISABLE(hi2s);
455
456 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
457 if (hi2s->MspDeInitCallback == NULL)
458 {
459 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
460 }
461
462 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
463 hi2s->MspDeInitCallback(hi2s);
464 #else
465 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
466 HAL_I2S_MspDeInit(hi2s);
467 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
468
469 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
470 hi2s->State = HAL_I2S_STATE_RESET;
471
472 /* Release Lock */
473 __HAL_UNLOCK(hi2s);
474
475 return HAL_OK;
476 }
477
478 /**
479 * @brief I2S MSP Init
480 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
481 * the configuration information for I2S module
482 * @retval None
483 */
HAL_I2S_MspInit(I2S_HandleTypeDef * hi2s)484 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
485 {
486 /* Prevent unused argument(s) compilation warning */
487 UNUSED(hi2s);
488
489 /* NOTE : This function Should not be modified, when the callback is needed,
490 the HAL_I2S_MspInit could be implemented in the user file
491 */
492 }
493
494 /**
495 * @brief I2S MSP DeInit
496 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
497 * the configuration information for I2S module
498 * @retval None
499 */
HAL_I2S_MspDeInit(I2S_HandleTypeDef * hi2s)500 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
501 {
502 /* Prevent unused argument(s) compilation warning */
503 UNUSED(hi2s);
504
505 /* NOTE : This function Should not be modified, when the callback is needed,
506 the HAL_I2S_MspDeInit could be implemented in the user file
507 */
508 }
509
510 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
511 /**
512 * @brief Register a User I2S Callback
513 * To be used instead of the weak predefined callback
514 * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains
515 * the configuration information for the specified I2S.
516 * @param CallbackID ID of the callback to be registered
517 * @param pCallback pointer to the Callback function
518 * @retval HAL status
519 */
HAL_I2S_RegisterCallback(I2S_HandleTypeDef * hi2s,HAL_I2S_CallbackIDTypeDef CallbackID,pI2S_CallbackTypeDef pCallback)520 HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID, pI2S_CallbackTypeDef pCallback)
521 {
522 HAL_StatusTypeDef status = HAL_OK;
523
524 if (pCallback == NULL)
525 {
526 /* Update the error code */
527 hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
528
529 return HAL_ERROR;
530 }
531 /* Process locked */
532 __HAL_LOCK(hi2s);
533
534 if (HAL_I2S_STATE_READY == hi2s->State)
535 {
536 switch (CallbackID)
537 {
538 case HAL_I2S_TX_COMPLETE_CB_ID :
539 hi2s->TxCpltCallback = pCallback;
540 break;
541
542 case HAL_I2S_RX_COMPLETE_CB_ID :
543 hi2s->RxCpltCallback = pCallback;
544 break;
545
546 case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
547 hi2s->TxHalfCpltCallback = pCallback;
548 break;
549
550 case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
551 hi2s->RxHalfCpltCallback = pCallback;
552 break;
553
554 case HAL_I2S_ERROR_CB_ID :
555 hi2s->ErrorCallback = pCallback;
556 break;
557
558 case HAL_I2S_MSPINIT_CB_ID :
559 hi2s->MspInitCallback = pCallback;
560 break;
561
562 case HAL_I2S_MSPDEINIT_CB_ID :
563 hi2s->MspDeInitCallback = pCallback;
564 break;
565
566 default :
567 /* Update the error code */
568 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
569
570 /* Return error status */
571 status = HAL_ERROR;
572 break;
573 }
574 }
575 else if (HAL_I2S_STATE_RESET == hi2s->State)
576 {
577 switch (CallbackID)
578 {
579 case HAL_I2S_MSPINIT_CB_ID :
580 hi2s->MspInitCallback = pCallback;
581 break;
582
583 case HAL_I2S_MSPDEINIT_CB_ID :
584 hi2s->MspDeInitCallback = pCallback;
585 break;
586
587 default :
588 /* Update the error code */
589 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
590
591 /* Return error status */
592 status = HAL_ERROR;
593 break;
594 }
595 }
596 else
597 {
598 /* Update the error code */
599 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
600
601 /* Return error status */
602 status = HAL_ERROR;
603 }
604
605 /* Release Lock */
606 __HAL_UNLOCK(hi2s);
607 return status;
608 }
609
610 /**
611 * @brief Unregister an I2S Callback
612 * I2S callback is redirected to the weak predefined callback
613 * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains
614 * the configuration information for the specified I2S.
615 * @param CallbackID ID of the callback to be unregistered
616 * @retval HAL status
617 */
HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef * hi2s,HAL_I2S_CallbackIDTypeDef CallbackID)618 HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
619 {
620 HAL_StatusTypeDef status = HAL_OK;
621
622 /* Process locked */
623 __HAL_LOCK(hi2s);
624
625 if (HAL_I2S_STATE_READY == hi2s->State)
626 {
627 switch (CallbackID)
628 {
629 case HAL_I2S_TX_COMPLETE_CB_ID :
630 hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */
631 break;
632
633 case HAL_I2S_RX_COMPLETE_CB_ID :
634 hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */
635 break;
636
637 case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
638 hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
639 break;
640
641 case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
642 hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
643 break;
644
645 case HAL_I2S_ERROR_CB_ID :
646 hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */
647 break;
648
649 case HAL_I2S_MSPINIT_CB_ID :
650 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
651 break;
652
653 case HAL_I2S_MSPDEINIT_CB_ID :
654 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
655 break;
656
657 default :
658 /* Update the error code */
659 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
660
661 /* Return error status */
662 status = HAL_ERROR;
663 break;
664 }
665 }
666 else if (HAL_I2S_STATE_RESET == hi2s->State)
667 {
668 switch (CallbackID)
669 {
670 case HAL_I2S_MSPINIT_CB_ID :
671 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
672 break;
673
674 case HAL_I2S_MSPDEINIT_CB_ID :
675 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
676 break;
677
678 default :
679 /* Update the error code */
680 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
681
682 /* Return error status */
683 status = HAL_ERROR;
684 break;
685 }
686 }
687 else
688 {
689 /* Update the error code */
690 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
691
692 /* Return error status */
693 status = HAL_ERROR;
694 }
695
696 /* Release Lock */
697 __HAL_UNLOCK(hi2s);
698 return status;
699 }
700 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
701 /**
702 * @}
703 */
704
705 /** @defgroup I2S_Exported_Functions_Group2 IO operation functions
706 * @brief Data transfers functions
707 *
708 @verbatim
709 ===============================================================================
710 ##### IO operation functions #####
711 ===============================================================================
712 [..]
713 This subsection provides a set of functions allowing to manage the I2S data
714 transfers.
715
716 (#) There are two modes of transfer:
717 (++) Blocking mode : The communication is performed in the polling mode.
718 The status of all data processing is returned by the same function
719 after finishing transfer.
720 (++) No-Blocking mode : The communication is performed using Interrupts
721 or DMA. These functions return the status of the transfer startup.
722 The end of the data processing will be indicated through the
723 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
724 using DMA mode.
725
726 (#) Blocking mode functions are :
727 (++) HAL_I2S_Transmit()
728 (++) HAL_I2S_Receive()
729
730 (#) No-Blocking mode functions with Interrupt are :
731 (++) HAL_I2S_Transmit_IT()
732 (++) HAL_I2S_Receive_IT()
733
734 (#) No-Blocking mode functions with DMA are :
735 (++) HAL_I2S_Transmit_DMA()
736 (++) HAL_I2S_Receive_DMA()
737
738 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
739 (++) HAL_I2S_TxCpltCallback()
740 (++) HAL_I2S_RxCpltCallback()
741 (++) HAL_I2S_ErrorCallback()
742
743 @endverbatim
744 * @{
745 */
746
747 /**
748 * @brief Transmit an amount of data in blocking mode
749 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
750 * the configuration information for I2S module
751 * @param pData a 16-bit pointer to data buffer.
752 * @param Size number of data sample to be sent:
753 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
754 * configuration phase, the Size parameter means the number of 16-bit data length
755 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
756 * the Size parameter means the number of 16-bit data length.
757 * @param Timeout Timeout duration
758 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
759 * between Master and Slave(example: audio streaming).
760 * @retval HAL status
761 */
HAL_I2S_Transmit(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)762 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
763 {
764 if ((pData == NULL) || (Size == 0UL))
765 {
766 return HAL_ERROR;
767 }
768
769 /* Process Locked */
770 __HAL_LOCK(hi2s);
771
772 if (hi2s->State != HAL_I2S_STATE_READY)
773 {
774 __HAL_UNLOCK(hi2s);
775 return HAL_BUSY;
776 }
777
778 /* Set state and reset error code */
779 hi2s->State = HAL_I2S_STATE_BUSY_TX;
780 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
781 hi2s->pTxBuffPtr = pData;
782 hi2s->TxXferSize = Size;
783 hi2s->TxXferCount = Size;
784
785 /* Initialize fields not used in handle to zero */
786 hi2s->pRxBuffPtr = NULL;
787 hi2s->RxXferSize = (uint16_t) 0UL;
788 hi2s->RxXferCount = (uint16_t) 0UL;
789
790 /* Check if the I2S is already enabled */
791 if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
792 {
793 /* Enable I2S peripheral */
794 __HAL_I2S_ENABLE(hi2s);
795 }
796
797 /* Start the transfer */
798 SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
799
800
801 /* Wait until TXP flag is set */
802 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, Timeout) != HAL_OK)
803 {
804 /* Set the error code */
805 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
806 hi2s->State = HAL_I2S_STATE_READY;
807 __HAL_UNLOCK(hi2s);
808 return HAL_ERROR;
809 }
810
811 while (hi2s->TxXferCount > 0UL)
812 {
813 if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
814 {
815 /* Transmit data in 32 Bit mode */
816 hi2s->Instance->TXDR = *((uint32_t *)hi2s->pTxBuffPtr);
817 hi2s->pTxBuffPtr += 2;
818 hi2s->TxXferCount--;
819 }
820 else
821 {
822 /* Transmit data in 16 Bit mode */
823 *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((uint16_t *)hi2s->pTxBuffPtr);
824 hi2s->pTxBuffPtr++;
825 hi2s->TxXferCount--;
826 }
827
828 /* Wait until TXP flag is set */
829 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, Timeout) != HAL_OK)
830 {
831 /* Set the error code */
832 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
833 hi2s->State = HAL_I2S_STATE_READY;
834 __HAL_UNLOCK(hi2s);
835 return HAL_ERROR;
836 }
837
838 /* Check if an underrun occurs */
839 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
840 {
841 /* Clear underrun flag */
842 __HAL_I2S_CLEAR_UDRFLAG(hi2s);
843
844 /* Set the error code */
845 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
846 }
847 }
848
849 hi2s->State = HAL_I2S_STATE_READY;
850 __HAL_UNLOCK(hi2s);
851 return HAL_OK;
852 }
853
854 /**
855 * @brief Receive an amount of data in blocking mode
856 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
857 * the configuration information for I2S module
858 * @param pData a 16-bit pointer to data buffer.
859 * @param Size number of data sample to be sent:
860 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
861 * configuration phase, the Size parameter means the number of 16-bit data length
862 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
863 * the Size parameter means the number of 16-bit data length.
864 * @param Timeout Timeout duration
865 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
866 * between Master and Slave(example: audio streaming).
867 * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
868 * in continuous way and as the I2S is not disabled at the end of the I2S transaction.
869 * @retval HAL status
870 */
HAL_I2S_Receive(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)871 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
872 {
873 if ((pData == NULL) || (Size == 0UL))
874 {
875 return HAL_ERROR;
876 }
877
878 /* Process Locked */
879 __HAL_LOCK(hi2s);
880
881 if (hi2s->State != HAL_I2S_STATE_READY)
882 {
883 __HAL_UNLOCK(hi2s);
884 return HAL_BUSY;
885 }
886
887 /* Set state and reset error code */
888 hi2s->State = HAL_I2S_STATE_BUSY_RX;
889 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
890 hi2s->pRxBuffPtr = pData;
891 hi2s->RxXferSize = Size;
892 hi2s->RxXferCount = Size;
893
894 /* Initialize fields not used in handle to zero */
895 hi2s->pTxBuffPtr = NULL;
896 hi2s->TxXferSize = (uint16_t) 0UL;
897 hi2s->TxXferCount = (uint16_t) 0UL;
898
899 /* Check if the I2S is already enabled */
900 if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
901 {
902 /* Enable I2S peripheral */
903 __HAL_I2S_ENABLE(hi2s);
904 }
905
906 /* Start the transfer */
907 SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
908
909 /* Receive data */
910 while (hi2s->RxXferCount > 0UL)
911 {
912 /* Wait until RXNE flag is set */
913 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXP, SET, Timeout) != HAL_OK)
914 {
915 /* Set the error code */
916 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
917 hi2s->State = HAL_I2S_STATE_READY;
918 __HAL_UNLOCK(hi2s);
919 return HAL_ERROR;
920 }
921
922 if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
923 {
924 /* Receive data in 32 Bit mode */
925 *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
926 hi2s->pRxBuffPtr += 2;
927 hi2s->RxXferCount--;
928 }
929 else
930 {
931 /* Receive data in 16 Bit mode */
932 *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
933 hi2s->pRxBuffPtr++;
934 hi2s->RxXferCount--;
935 }
936
937 /* Check if an overrun occurs */
938 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
939 {
940 /* Clear overrun flag */
941 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
942
943 /* Set the error code */
944 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
945 }
946 }
947
948 hi2s->State = HAL_I2S_STATE_READY;
949 __HAL_UNLOCK(hi2s);
950 return HAL_OK;
951 }
952
953 /**
954 * @brief Transmit an amount of data in non-blocking mode with Interrupt
955 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
956 * the configuration information for I2S module
957 * @param pData a 16-bit pointer to data buffer.
958 * @param Size number of data sample to be sent:
959 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
960 * configuration phase, the Size parameter means the number of 16-bit data length
961 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
962 * the Size parameter means the number of 16-bit data length.
963 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
964 * between Master and Slave(example: audio streaming).
965 * @retval HAL status
966 */
HAL_I2S_Transmit_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)967 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
968 {
969 if ((pData == NULL) || (Size == 0UL))
970 {
971 return HAL_ERROR;
972 }
973
974 /* Process Locked */
975 __HAL_LOCK(hi2s);
976
977 if (hi2s->State != HAL_I2S_STATE_READY)
978 {
979 __HAL_UNLOCK(hi2s);
980 return HAL_BUSY;
981 }
982
983 /* Set state and reset error code */
984 hi2s->State = HAL_I2S_STATE_BUSY_TX;
985 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
986 hi2s->pTxBuffPtr = (uint16_t *)pData;
987 hi2s->TxXferSize = Size;
988 hi2s->TxXferCount = Size;
989
990 /* Initialize fields not used in handle to zero */
991 hi2s->pRxBuffPtr = NULL;
992 hi2s->RxXferSize = (uint16_t) 0UL;
993 hi2s->RxXferCount = (uint16_t) 0UL;
994
995 /* Set the function for IT treatment */
996 if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
997 {
998 hi2s->TxISR = I2S_Transmit_32Bit_IT;
999 }
1000 else
1001 {
1002 hi2s->TxISR = I2S_Transmit_16Bit_IT;
1003 }
1004
1005 /* Check if the I2S is already enabled */
1006 if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1007 {
1008 /* Enable I2S peripheral */
1009 __HAL_I2S_ENABLE(hi2s);
1010 }
1011
1012 /* Enable TXP and UDR interrupt */
1013 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_UDR));
1014
1015 /* Enable TIFRE interrupt if the mode is Slave */
1016 if (hi2s->Init.Mode == I2S_MODE_SLAVE_TX)
1017 {
1018 __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1019 }
1020
1021 /* Start the transfer */
1022 SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1023
1024 __HAL_UNLOCK(hi2s);
1025 return HAL_OK;
1026 }
1027
1028 /**
1029 * @brief Receive an amount of data in non-blocking mode with Interrupt
1030 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1031 * the configuration information for I2S module
1032 * @param pData a 16-bit pointer to the Receive data buffer.
1033 * @param Size number of data sample to be sent:
1034 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1035 * configuration phase, the Size parameter means the number of 16-bit data length
1036 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1037 * the Size parameter means the number of 16-bit data length.
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 * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronization
1041 * between Master and Slave otherwise the I2S interrupt should be optimized.
1042 * @retval HAL status
1043 */
HAL_I2S_Receive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1044 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1045 {
1046 if ((pData == NULL) || (Size == 0UL))
1047 {
1048 return HAL_ERROR;
1049 }
1050
1051 /* Process Locked */
1052 __HAL_LOCK(hi2s);
1053
1054 if (hi2s->State != HAL_I2S_STATE_READY)
1055 {
1056 __HAL_UNLOCK(hi2s);
1057 return HAL_BUSY;
1058 }
1059
1060 /* Set state and reset error code */
1061 hi2s->State = HAL_I2S_STATE_BUSY_RX;
1062 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1063 hi2s->pRxBuffPtr = pData;
1064 hi2s->RxXferSize = Size;
1065 hi2s->RxXferCount = Size;
1066
1067 /* Initialize fields not used in handle to zero */
1068 hi2s->pTxBuffPtr = NULL;
1069 hi2s->TxXferSize = (uint16_t) 0UL;
1070 hi2s->TxXferCount = (uint16_t) 0UL;
1071
1072 /* Set the function for IT treatment */
1073 if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1074 {
1075 hi2s->RxISR = I2S_Receive_32Bit_IT;
1076 }
1077 else
1078 {
1079 hi2s->RxISR = I2S_Receive_16Bit_IT;
1080 }
1081
1082 /* Check if the I2S is already enabled */
1083 if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1084 {
1085 /* Enable I2S peripheral */
1086 __HAL_I2S_ENABLE(hi2s);
1087 }
1088 /* Enable RXNE and ERR interrupt */
1089 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_OVR));
1090
1091 /* Enable TIFRE interrupt if the mode is Slave */
1092 if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
1093 {
1094 __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1095 }
1096
1097 /* Start the transfer */
1098 SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1099
1100 __HAL_UNLOCK(hi2s);
1101 return HAL_OK;
1102 }
1103
1104 /**
1105 * @brief Transmit an amount of data in non-blocking mode with DMA
1106 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1107 * the configuration information for I2S module
1108 * @param pData a 16-bit pointer to the Transmit data buffer.
1109 * @param Size number of data sample to be sent:
1110 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1111 * configuration phase, the Size parameter means the number of 16-bit data length
1112 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1113 * the Size parameter means the number of 16-bit data length.
1114 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1115 * between Master and Slave(example: audio streaming).
1116 * @retval HAL status
1117 */
HAL_I2S_Transmit_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1118 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1119 {
1120 if ((pData == NULL) || (Size == 0UL))
1121 {
1122 return HAL_ERROR;
1123 }
1124
1125 /* Process Locked */
1126 __HAL_LOCK(hi2s);
1127
1128 if (hi2s->State != HAL_I2S_STATE_READY)
1129 {
1130 __HAL_UNLOCK(hi2s);
1131 return HAL_BUSY;
1132 }
1133
1134 /* Set state and reset error code */
1135 hi2s->State = HAL_I2S_STATE_BUSY_TX;
1136 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1137 hi2s->pTxBuffPtr = pData;
1138 hi2s->TxXferSize = Size;
1139 hi2s->TxXferCount = Size;
1140
1141 /* Init field not used in handle to zero */
1142 hi2s->pRxBuffPtr = NULL;
1143 hi2s->RxXferSize = (uint16_t)0UL;
1144 hi2s->RxXferCount = (uint16_t)0UL;
1145
1146 /* Set the I2S Tx DMA Half transfer complete callback */
1147 hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
1148
1149 /* Set the I2S Tx DMA transfer complete callback */
1150 hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
1151
1152 /* Set the DMA error callback */
1153 hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
1154
1155 /* Enable the Tx DMA Stream/Channel */
1156 if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR, hi2s->TxXferSize))
1157 {
1158 /* Update SPI error code */
1159 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1160 hi2s->State = HAL_I2S_STATE_READY;
1161
1162 __HAL_UNLOCK(hi2s);
1163 return HAL_ERROR;
1164 }
1165
1166 /* Check if the I2S Tx request is already enabled */
1167 if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
1168 {
1169 /* Enable Tx DMA Request */
1170 SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1171 }
1172
1173 /* Check if the I2S is already enabled */
1174 if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1175 {
1176 /* Enable I2S peripheral */
1177 __HAL_I2S_ENABLE(hi2s);
1178 }
1179
1180 /* Start the transfer */
1181 SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1182
1183 __HAL_UNLOCK(hi2s);
1184 return HAL_OK;
1185 }
1186
1187 /**
1188 * @brief Receive an amount of data in non-blocking mode with DMA
1189 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1190 * the configuration information for I2S module
1191 * @param pData a 16-bit pointer to the Receive data buffer.
1192 * @param Size number of data sample to be sent:
1193 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1194 * configuration phase, the Size parameter means the number of 16-bit data length
1195 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1196 * the Size parameter means the number of 16-bit data length.
1197 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1198 * between Master and Slave(example: audio streaming).
1199 * @retval HAL status
1200 */
HAL_I2S_Receive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1201 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1202 {
1203 if ((pData == NULL) || (Size == 0UL))
1204 {
1205 return HAL_ERROR;
1206 }
1207
1208 /* Process Locked */
1209 __HAL_LOCK(hi2s);
1210
1211 if (hi2s->State != HAL_I2S_STATE_READY)
1212 {
1213 __HAL_UNLOCK(hi2s);
1214 return HAL_BUSY;
1215 }
1216
1217 /* Set state and reset error code */
1218 hi2s->State = HAL_I2S_STATE_BUSY_RX;
1219 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1220 hi2s->pRxBuffPtr = pData;
1221 hi2s->RxXferSize = Size;
1222 hi2s->RxXferCount = Size;
1223
1224 /* Init field not used in handle to zero */
1225 hi2s->pTxBuffPtr = NULL;
1226 hi2s->TxXferSize = (uint16_t)0UL;
1227 hi2s->TxXferCount = (uint16_t)0UL;
1228
1229
1230 /* Set the I2S Rx DMA Half transfer complete callback */
1231 hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
1232
1233 /* Set the I2S Rx DMA transfer complete callback */
1234 hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
1235
1236 /* Set the DMA error callback */
1237 hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1238
1239 /* Enable the Rx DMA Stream/Channel */
1240 if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr, hi2s->RxXferSize))
1241 {
1242 /* Update SPI error code */
1243 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1244 hi2s->State = HAL_I2S_STATE_READY;
1245
1246 __HAL_UNLOCK(hi2s);
1247 return HAL_ERROR;
1248 }
1249
1250 /* Check if the I2S Rx request is already enabled */
1251 if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
1252 {
1253 /* Enable Rx DMA Request */
1254 SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1255 }
1256
1257 /* Check if the I2S is already enabled */
1258 if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1259 {
1260 /* Enable I2S peripheral */
1261 __HAL_I2S_ENABLE(hi2s);
1262 }
1263
1264 /* Start the transfer */
1265 SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1266
1267 __HAL_UNLOCK(hi2s);
1268 return HAL_OK;
1269 }
1270
1271 /**
1272 * @brief Pauses the audio DMA Stream/Channel playing from the Media.
1273 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1274 * the configuration information for I2S module
1275 * @retval HAL status
1276 */
HAL_I2S_DMAPause(I2S_HandleTypeDef * hi2s)1277 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1278 {
1279 /* Process Locked */
1280 __HAL_LOCK(hi2s);
1281
1282 if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1283 {
1284 /* Disable the I2S DMA Tx request */
1285 CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1286 }
1287 else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1288 {
1289 /* Disable the I2S DMA Rx request */
1290 CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1291 }
1292 else
1293 {
1294 /* nothing to do */
1295 }
1296
1297 /* Process Unlocked */
1298 __HAL_UNLOCK(hi2s);
1299
1300 return HAL_OK;
1301 }
1302
1303 /**
1304 * @brief Resumes the audio DMA Stream/Channel playing from the Media.
1305 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1306 * the configuration information for I2S module
1307 * @retval HAL status
1308 */
HAL_I2S_DMAResume(I2S_HandleTypeDef * hi2s)1309 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1310 {
1311 /* Process Locked */
1312 __HAL_LOCK(hi2s);
1313
1314 if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1315 {
1316 /* Enable the I2S DMA Tx request */
1317 SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1318 }
1319 else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1320 {
1321 /* Enable the I2S DMA Rx request */
1322 SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1323 }
1324 else
1325 {
1326 /* nothing to do */
1327 }
1328
1329 /* If the I2S peripheral is still not enabled, enable it */
1330 if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1331 {
1332 /* Enable I2S peripheral */
1333 __HAL_I2S_ENABLE(hi2s);
1334 }
1335
1336 /* Process Unlocked */
1337 __HAL_UNLOCK(hi2s);
1338
1339 return HAL_OK;
1340 }
1341
1342 /**
1343 * @brief Stops the audio DMA Stream/Channel playing from the Media.
1344 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1345 * the configuration information for I2S module
1346 * @retval HAL status
1347 */
HAL_I2S_DMAStop(I2S_HandleTypeDef * hi2s)1348 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1349 {
1350 HAL_StatusTypeDef errorcode = HAL_OK;
1351 /* The Lock is not implemented on this API to allow the user application
1352 to call the HAL SPI API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1353 when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1354 and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1355 */
1356
1357 /* Disable the I2S Tx/Rx DMA requests */
1358 CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1359 CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1360
1361 /* Abort the I2S DMA tx Stream/Channel */
1362 if (hi2s->hdmatx != NULL)
1363 {
1364 /* Disable the I2S DMA tx Stream/Channel */
1365 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1366 {
1367 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1368 errorcode = HAL_ERROR;
1369 }
1370 }
1371
1372 /* Abort the I2S DMA rx Stream/Channel */
1373 if (hi2s->hdmarx != NULL)
1374 {
1375 /* Disable the I2S DMA rx Stream/Channel */
1376 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1377 {
1378 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1379 errorcode = HAL_ERROR;
1380 }
1381 }
1382
1383 /* Disable I2S peripheral */
1384 __HAL_I2S_DISABLE(hi2s);
1385
1386 hi2s->State = HAL_I2S_STATE_READY;
1387
1388 return errorcode;
1389 }
1390
1391 /**
1392 * @brief This function handles I2S interrupt request.
1393 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1394 * the configuration information for I2S module
1395 * @retval None
1396 */
HAL_I2S_IRQHandler(I2S_HandleTypeDef * hi2s)1397 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1398 {
1399 uint32_t itsource = hi2s->Instance->IER;
1400 uint32_t itflag = hi2s->Instance->SR;
1401 uint32_t trigger = itsource & itflag;
1402
1403 /* I2S in mode Receiver ------------------------------------------------*/
1404 if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) == RESET) && HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP))
1405 {
1406 hi2s->RxISR(hi2s);
1407 }
1408
1409 /* I2S in mode Transmitter -----------------------------------------------*/
1410 if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_UDR) == RESET) && HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP))
1411 {
1412 hi2s->TxISR(hi2s);
1413 }
1414
1415 /* I2S interrupt error ----------------------------------------------------*/
1416 if (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_ERR) != RESET)
1417 {
1418 /* I2S Overrun error interrupt occurred ---------------------------------*/
1419 if (I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) != RESET)
1420 {
1421 /* Disable RXNE and ERR interrupt */
1422 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
1423
1424 /* Set the error code and execute error callback*/
1425 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1426 }
1427
1428 /* I2S Underrun error interrupt occurred --------------------------------*/
1429 if (I2S_CHECK_FLAG(itflag, I2S_FLAG_UDR) != RESET)
1430 {
1431 /* Disable TXE and ERR interrupt */
1432 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
1433
1434 /* Set the error code and execute error callback*/
1435 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1436 }
1437
1438 /* I2S Frame error interrupt occurred -----------------------------------*/
1439 if (I2S_CHECK_FLAG(itflag, I2S_FLAG_FRE) != RESET)
1440 {
1441 /* Disable FRE and ERR interrupt */
1442 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_FRE | I2S_IT_ERR));
1443
1444 /* Set the error code and execute error callback*/
1445 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_FRE);
1446 }
1447
1448 /* Set the I2S State ready */
1449 hi2s->State = HAL_I2S_STATE_READY;
1450
1451 /* Call user error callback */
1452 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1453 hi2s->ErrorCallback(hi2s);
1454 #else
1455 HAL_I2S_ErrorCallback(hi2s);
1456 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1457 }
1458 }
1459
1460 /**
1461 * @brief Tx Transfer Half completed callbacks
1462 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1463 * the configuration information for I2S module
1464 * @retval None
1465 */
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1466 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1467 {
1468 /* Prevent unused argument(s) compilation warning */
1469 UNUSED(hi2s);
1470
1471 /* NOTE : This function Should not be modified, when the callback is needed,
1472 the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1473 */
1474 }
1475
1476 /**
1477 * @brief Tx Transfer completed callbacks
1478 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1479 * the configuration information for I2S module
1480 * @retval None
1481 */
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef * hi2s)1482 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
1483 {
1484 /* Prevent unused argument(s) compilation warning */
1485 UNUSED(hi2s);
1486
1487 /* NOTE : This function Should not be modified, when the callback is needed,
1488 the HAL_I2S_TxCpltCallback could be implemented in the user file
1489 */
1490 }
1491
1492 /**
1493 * @brief Rx Transfer half completed callbacks
1494 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1495 * the configuration information for I2S module
1496 * @retval None
1497 */
HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1498 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1499 {
1500 /* Prevent unused argument(s) compilation warning */
1501 UNUSED(hi2s);
1502
1503 /* NOTE : This function Should not be modified, when the callback is needed,
1504 the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
1505 */
1506 }
1507
1508 /**
1509 * @brief Rx Transfer completed callbacks
1510 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1511 * the configuration information for I2S module
1512 * @retval None
1513 */
HAL_I2S_RxCpltCallback(I2S_HandleTypeDef * hi2s)1514 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1515 {
1516 /* Prevent unused argument(s) compilation warning */
1517 UNUSED(hi2s);
1518
1519 /* NOTE : This function Should not be modified, when the callback is needed,
1520 the HAL_I2S_RxCpltCallback could be implemented in the user file
1521 */
1522 }
1523
1524 /**
1525 * @brief I2S error callbacks
1526 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1527 * the configuration information for I2S module
1528 * @retval None
1529 */
HAL_I2S_ErrorCallback(I2S_HandleTypeDef * hi2s)1530 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
1531 {
1532 /* Prevent unused argument(s) compilation warning */
1533 UNUSED(hi2s);
1534
1535 /* NOTE : This function Should not be modified, when the callback is needed,
1536 the HAL_I2S_ErrorCallback could be implemented in the user file
1537 */
1538 }
1539
1540 /**
1541 * @}
1542 */
1543
1544 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1545 * @brief Peripheral State functions
1546 *
1547 @verbatim
1548 ===============================================================================
1549 ##### Peripheral State and Errors functions #####
1550 ===============================================================================
1551 [..]
1552 This subsection permits to get in run-time the status of the peripheral
1553 and the data flow.
1554
1555 @endverbatim
1556 * @{
1557 */
1558
1559 /**
1560 * @brief Return the I2S state
1561 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1562 * the configuration information for I2S module
1563 * @retval HAL state
1564 */
HAL_I2S_GetState(I2S_HandleTypeDef * hi2s)1565 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1566 {
1567 return hi2s->State;
1568 }
1569
1570 /**
1571 * @brief Return the I2S error code
1572 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1573 * the configuration information for I2S module
1574 * @retval I2S Error Code
1575 */
HAL_I2S_GetError(I2S_HandleTypeDef * hi2s)1576 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1577 {
1578 return hi2s->ErrorCode;
1579 }
1580 /**
1581 * @}
1582 */
1583
1584
1585 /**
1586 * @brief DMA I2S transmit process complete callback
1587 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1588 * the configuration information for the specified DMA module.
1589 * @retval None
1590 */
I2S_DMATxCplt(DMA_HandleTypeDef * hdma)1591 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1592 {
1593 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1594
1595 /* if DMA is configured in DMA_NORMAL Mode */
1596 if (hdma->Init.Mode == DMA_NORMAL)
1597 {
1598 /* Disable Tx DMA Request */
1599 CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1600
1601 hi2s->TxXferCount = (uint16_t) 0UL;
1602 hi2s->State = HAL_I2S_STATE_READY;
1603 }
1604 /* Call user Tx complete callback */
1605 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1606 hi2s->TxCpltCallback(hi2s);
1607 #else
1608 HAL_I2S_TxCpltCallback(hi2s);
1609 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1610 }
1611
1612 /**
1613 * @brief DMA I2S transmit process half complete callback
1614 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1615 * the configuration information for the specified DMA module.
1616 * @retval None
1617 */
I2S_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1618 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1619 {
1620 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1621
1622 /* Call user Tx half complete callback */
1623 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1624 hi2s->TxHalfCpltCallback(hi2s);
1625 #else
1626 HAL_I2S_TxHalfCpltCallback(hi2s);
1627 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1628 }
1629
1630 /**
1631 * @brief DMA I2S receive process complete callback
1632 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1633 * the configuration information for the specified DMA module.
1634 * @retval None
1635 */
I2S_DMARxCplt(DMA_HandleTypeDef * hdma)1636 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1637 {
1638 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1639
1640 /* if DMA is configured in DMA_NORMAL Mode */
1641 if (hdma->Init.Mode == DMA_NORMAL)
1642 {
1643 /* Disable Rx DMA Request */
1644 CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1645 hi2s->RxXferCount = (uint16_t)0UL;
1646 hi2s->State = HAL_I2S_STATE_READY;
1647 }
1648 /* Call user Rx complete callback */
1649 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1650 hi2s->RxCpltCallback(hi2s);
1651 #else
1652 HAL_I2S_RxCpltCallback(hi2s);
1653 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1654 }
1655
1656 /**
1657 * @brief DMA I2S receive process half complete callback
1658 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1659 * the configuration information for the specified DMA module.
1660 * @retval None
1661 */
I2S_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1662 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1663 {
1664 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1665
1666 /* Call user Rx half complete callback */
1667 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1668 hi2s->RxHalfCpltCallback(hi2s);
1669 #else
1670 HAL_I2S_RxHalfCpltCallback(hi2s);
1671 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1672 }
1673
1674 /**
1675 * @brief DMA I2S communication error callback
1676 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1677 * the configuration information for the specified DMA module.
1678 * @retval None
1679 */
I2S_DMAError(DMA_HandleTypeDef * hdma)1680 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1681 {
1682 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1683
1684 /* Disable Rx and Tx DMA Request */
1685 CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN));
1686 hi2s->TxXferCount = (uint16_t) 0UL;
1687 hi2s->RxXferCount = (uint16_t) 0UL;
1688
1689 hi2s->State = HAL_I2S_STATE_READY;
1690
1691 /* Set the error code and execute error callback*/
1692 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1693 /* Call user error callback */
1694 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1695 hi2s->ErrorCallback(hi2s);
1696 #else
1697 HAL_I2S_ErrorCallback(hi2s);
1698 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1699 }
1700
1701 /**
1702 * @brief Manage the transmission 16-bit in Interrupt context
1703 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1704 * the configuration information for I2S module
1705 * @retval None
1706 */
I2S_Transmit_16Bit_IT(I2S_HandleTypeDef * hi2s)1707 static void I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s)
1708 {
1709 /* Transmit data */
1710 *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((uint16_t *)hi2s->pTxBuffPtr);
1711 hi2s->pTxBuffPtr++;
1712 hi2s->TxXferCount--;
1713
1714 if (hi2s->TxXferCount == 0UL)
1715 {
1716 /* Disable TXE and ERR interrupt */
1717 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
1718
1719 hi2s->State = HAL_I2S_STATE_READY;
1720 /* Call user Tx complete callback */
1721 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1722 hi2s->TxCpltCallback(hi2s);
1723 #else
1724 HAL_I2S_TxCpltCallback(hi2s);
1725 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1726 }
1727 }
1728
1729 /**
1730 * @brief Manage the transmission 32-bit in Interrupt context
1731 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1732 * the configuration information for I2S module
1733 * @retval None
1734 */
I2S_Transmit_32Bit_IT(I2S_HandleTypeDef * hi2s)1735 static void I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s)
1736 {
1737 /* Transmit data */
1738 hi2s->Instance->TXDR = *((uint32_t *)hi2s->pTxBuffPtr);
1739 hi2s->pTxBuffPtr += 2;
1740 hi2s->TxXferCount--;
1741
1742 if (hi2s->TxXferCount == 0UL)
1743 {
1744 /* Disable TXE and ERR interrupt */
1745 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
1746
1747 hi2s->State = HAL_I2S_STATE_READY;
1748 /* Call user Tx complete callback */
1749 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1750 hi2s->TxCpltCallback(hi2s);
1751 #else
1752 HAL_I2S_TxCpltCallback(hi2s);
1753 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1754 }
1755 }
1756
1757 /**
1758 * @brief Manage the reception 16-bit in Interrupt context
1759 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1760 * the configuration information for I2S module
1761 * @retval None
1762 */
I2S_Receive_16Bit_IT(I2S_HandleTypeDef * hi2s)1763 static void I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s)
1764 {
1765 /* Receive data */
1766 *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
1767 hi2s->pRxBuffPtr++;
1768 hi2s->RxXferCount--;
1769
1770 if (hi2s->RxXferCount == 0UL)
1771 {
1772 /* Disable RXNE and ERR interrupt */
1773 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
1774
1775 hi2s->State = HAL_I2S_STATE_READY;
1776 /* Call user Rx complete callback */
1777 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1778 hi2s->RxCpltCallback(hi2s);
1779 #else
1780 HAL_I2S_RxCpltCallback(hi2s);
1781 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1782 }
1783 }
1784
1785 /**
1786 * @brief Manage the reception 32-bit in Interrupt context
1787 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1788 * the configuration information for I2S module
1789 * @retval None
1790 */
I2S_Receive_32Bit_IT(I2S_HandleTypeDef * hi2s)1791 static void I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s)
1792 {
1793 /* Receive data */
1794 *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
1795 hi2s->pRxBuffPtr += 2;
1796 hi2s->RxXferCount--;
1797
1798 if (hi2s->RxXferCount == 0UL)
1799 {
1800 /* Disable RXNE and ERR interrupt */
1801 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
1802
1803 hi2s->State = HAL_I2S_STATE_READY;
1804 /* Call user Rx complete callback */
1805 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1806 hi2s->RxCpltCallback(hi2s);
1807 #else
1808 HAL_I2S_RxCpltCallback(hi2s);
1809 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1810 }
1811 }
1812
1813 /**
1814 * @brief This function handles I2S Communication Timeout.
1815 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1816 * the configuration information for I2S module
1817 * @param Flag Flag checked
1818 * @param State Value of the flag expected
1819 * @param Timeout Duration of the timeout
1820 * @retval HAL status
1821 */
I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,FlagStatus State,uint32_t Timeout)1822 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State, uint32_t Timeout)
1823 {
1824 uint32_t tickstart;
1825
1826 /* Get tick */
1827 tickstart = HAL_GetTick();
1828
1829 /* Wait until flag is set to status*/
1830 while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1831 {
1832 if (Timeout != HAL_MAX_DELAY)
1833 {
1834 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0UL))
1835 {
1836 /* Set the I2S State ready */
1837 hi2s->State = HAL_I2S_STATE_READY;
1838
1839 /* Process Unlocked */
1840 __HAL_UNLOCK(hi2s);
1841
1842 return HAL_TIMEOUT;
1843 }
1844 }
1845 }
1846 return HAL_OK;
1847 }
1848
1849 /**
1850 * @}
1851 */
1852
1853 /**
1854 * @}
1855 */
1856
1857 /**
1858 * @}
1859 */
1860
1861 #endif /* HAL_I2S_MODULE_ENABLED */
1862
1863 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1864