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