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