1 /**
2 ******************************************************************************
3 * @file stm32l0xx_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 HSE_VALUE in the stm32l0xx_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 "stm32l0xx_hal.h"
185
186 #ifdef HAL_I2S_MODULE_ENABLED
187
188 #if defined(SPI_I2S_SUPPORT)
189 /** @addtogroup STM32L0xx_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 * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
748 * @retval HAL status
749 */
HAL_I2S_Transmit(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)750 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
751 {
752 uint32_t tmpreg_cfgr;
753
754 if ((pData == NULL) || (Size == 0U))
755 {
756 return HAL_ERROR;
757 }
758
759 /* Process Locked */
760 __HAL_LOCK(hi2s);
761
762 if (hi2s->State != HAL_I2S_STATE_READY)
763 {
764 __HAL_UNLOCK(hi2s);
765 return HAL_BUSY;
766 }
767
768 /* Set state and reset error code */
769 hi2s->State = HAL_I2S_STATE_BUSY_TX;
770 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
771 hi2s->pTxBuffPtr = pData;
772
773 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
774
775 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
776 {
777 hi2s->TxXferSize = (Size << 1U);
778 hi2s->TxXferCount = (Size << 1U);
779 }
780 else
781 {
782 hi2s->TxXferSize = Size;
783 hi2s->TxXferCount = Size;
784 }
785
786 tmpreg_cfgr = hi2s->Instance->I2SCFGR;
787
788 /* Check if the I2S is already enabled */
789 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
790 {
791 /* Enable I2S peripheral */
792 __HAL_I2S_ENABLE(hi2s);
793 }
794
795 /* Wait until TXE flag is set */
796 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
797 {
798 /* Set the error code */
799 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
800 hi2s->State = HAL_I2S_STATE_READY;
801 __HAL_UNLOCK(hi2s);
802 return HAL_ERROR;
803 }
804
805 while (hi2s->TxXferCount > 0U)
806 {
807 hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
808 hi2s->pTxBuffPtr++;
809 hi2s->TxXferCount--;
810
811 /* Wait until TXE flag is set */
812 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
813 {
814 /* Set the error code */
815 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
816 hi2s->State = HAL_I2S_STATE_READY;
817 __HAL_UNLOCK(hi2s);
818 return HAL_ERROR;
819 }
820
821 /* Check if an underrun occurs */
822 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
823 {
824 /* Clear underrun flag */
825 __HAL_I2S_CLEAR_UDRFLAG(hi2s);
826
827 /* Set the error code */
828 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
829 }
830 }
831
832 /* Check if Slave mode is selected */
833 if (((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)
834 || ((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX))
835 {
836 /* Wait until Busy flag is reset */
837 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK)
838 {
839 /* Set the error code */
840 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
841 hi2s->State = HAL_I2S_STATE_READY;
842 __HAL_UNLOCK(hi2s);
843 return HAL_ERROR;
844 }
845 }
846
847 hi2s->State = HAL_I2S_STATE_READY;
848 __HAL_UNLOCK(hi2s);
849 return HAL_OK;
850 }
851
852 /**
853 * @brief Receive an amount of data in blocking mode
854 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
855 * the configuration information for I2S module
856 * @param pData a 16-bit pointer to data buffer.
857 * @param Size number of data sample to be sent:
858 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
859 * configuration phase, the Size parameter means the number of 16-bit data length
860 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
861 * the Size parameter means the number of 24-bit or 32-bit data length.
862 * @param Timeout Timeout duration
863 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
864 * between Master and Slave(example: audio streaming).
865 * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
866 * in continuous way and as the I2S is not disabled at the end of the I2S transaction.
867 * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
868 * @retval HAL status
869 */
HAL_I2S_Receive(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)870 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
871 {
872 uint32_t tmpreg_cfgr;
873
874 if ((pData == NULL) || (Size == 0U))
875 {
876 return HAL_ERROR;
877 }
878
879 /* Process Locked */
880 __HAL_LOCK(hi2s);
881
882 if (hi2s->State != HAL_I2S_STATE_READY)
883 {
884 __HAL_UNLOCK(hi2s);
885 return HAL_BUSY;
886 }
887
888 /* Set state and reset error code */
889 hi2s->State = HAL_I2S_STATE_BUSY_RX;
890 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
891 hi2s->pRxBuffPtr = pData;
892
893 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
894
895 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
896 {
897 hi2s->RxXferSize = (Size << 1U);
898 hi2s->RxXferCount = (Size << 1U);
899 }
900 else
901 {
902 hi2s->RxXferSize = Size;
903 hi2s->RxXferCount = Size;
904 }
905
906 /* Check if the I2S is already enabled */
907 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
908 {
909 /* Enable I2S peripheral */
910 __HAL_I2S_ENABLE(hi2s);
911 }
912
913 /* Check if Master Receiver mode is selected */
914 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
915 {
916 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
917 access to the SPI_SR register. */
918 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
919 }
920
921 /* Receive data */
922 while (hi2s->RxXferCount > 0U)
923 {
924 /* Wait until RXNE flag is set */
925 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
926 {
927 /* Set the error code */
928 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
929 hi2s->State = HAL_I2S_STATE_READY;
930 __HAL_UNLOCK(hi2s);
931 return HAL_ERROR;
932 }
933
934 (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
935 hi2s->pRxBuffPtr++;
936 hi2s->RxXferCount--;
937
938 /* Check if an overrun occurs */
939 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
940 {
941 /* Clear overrun flag */
942 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
943
944 /* Set the error code */
945 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
946 }
947 }
948
949 hi2s->State = HAL_I2S_STATE_READY;
950 __HAL_UNLOCK(hi2s);
951 return HAL_OK;
952 }
953
954 /**
955 * @brief Transmit an amount of data in non-blocking mode with Interrupt
956 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
957 * the configuration information for I2S module
958 * @param pData a 16-bit pointer to data buffer.
959 * @param Size number of data sample to be sent:
960 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
961 * configuration phase, the Size parameter means the number of 16-bit data length
962 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
963 * the Size parameter means the number of 24-bit or 32-bit data length.
964 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
965 * between Master and Slave(example: audio streaming).
966 * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
967 * @retval HAL status
968 */
HAL_I2S_Transmit_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)969 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
970 {
971 uint32_t tmpreg_cfgr;
972
973 if ((pData == NULL) || (Size == 0U))
974 {
975 return HAL_ERROR;
976 }
977
978 /* Process Locked */
979 __HAL_LOCK(hi2s);
980
981 if (hi2s->State != HAL_I2S_STATE_READY)
982 {
983 __HAL_UNLOCK(hi2s);
984 return HAL_BUSY;
985 }
986
987 /* Set state and reset error code */
988 hi2s->State = HAL_I2S_STATE_BUSY_TX;
989 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
990 hi2s->pTxBuffPtr = pData;
991
992 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
993
994 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
995 {
996 hi2s->TxXferSize = (Size << 1U);
997 hi2s->TxXferCount = (Size << 1U);
998 }
999 else
1000 {
1001 hi2s->TxXferSize = Size;
1002 hi2s->TxXferCount = Size;
1003 }
1004
1005 /* Enable TXE and ERR interrupt */
1006 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1007
1008 /* Check if the I2S is already enabled */
1009 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1010 {
1011 /* Enable I2S peripheral */
1012 __HAL_I2S_ENABLE(hi2s);
1013 }
1014
1015 __HAL_UNLOCK(hi2s);
1016 return HAL_OK;
1017 }
1018
1019 /**
1020 * @brief Receive an amount of data in non-blocking mode with Interrupt
1021 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1022 * the configuration information for I2S module
1023 * @param pData a 16-bit pointer to the Receive data buffer.
1024 * @param Size number of data sample to be sent:
1025 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1026 * configuration phase, the Size parameter means the number of 16-bit data length
1027 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1028 * the Size parameter means the number of 24-bit or 32-bit data length.
1029 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1030 * between Master and Slave(example: audio streaming).
1031 * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronization
1032 * between Master and Slave otherwise the I2S interrupt should be optimized.
1033 * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
1034 * @retval HAL status
1035 */
HAL_I2S_Receive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1036 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1037 {
1038 uint32_t tmpreg_cfgr;
1039
1040 if ((pData == NULL) || (Size == 0U))
1041 {
1042 return HAL_ERROR;
1043 }
1044
1045 /* Process Locked */
1046 __HAL_LOCK(hi2s);
1047
1048 if (hi2s->State != HAL_I2S_STATE_READY)
1049 {
1050 __HAL_UNLOCK(hi2s);
1051 return HAL_BUSY;
1052 }
1053
1054 /* Set state and reset error code */
1055 hi2s->State = HAL_I2S_STATE_BUSY_RX;
1056 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1057 hi2s->pRxBuffPtr = pData;
1058
1059 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1060
1061 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1062 {
1063 hi2s->RxXferSize = (Size << 1U);
1064 hi2s->RxXferCount = (Size << 1U);
1065 }
1066 else
1067 {
1068 hi2s->RxXferSize = Size;
1069 hi2s->RxXferCount = Size;
1070 }
1071
1072 /* Enable RXNE and ERR interrupt */
1073 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1074
1075 /* Check if the I2S is already enabled */
1076 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
1077 {
1078 /* Enable I2S peripheral */
1079 __HAL_I2S_ENABLE(hi2s);
1080 }
1081
1082 __HAL_UNLOCK(hi2s);
1083 return HAL_OK;
1084 }
1085
1086 /**
1087 * @brief Transmit an amount of data in non-blocking mode with DMA
1088 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1089 * the configuration information for I2S module
1090 * @param pData a 16-bit pointer to the Transmit data buffer.
1091 * @param Size number of data sample to be sent:
1092 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1093 * configuration phase, the Size parameter means the number of 16-bit data length
1094 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1095 * the Size parameter means the number of 24-bit or 32-bit data length.
1096 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1097 * between Master and Slave(example: audio streaming).
1098 * @retval HAL status
1099 */
HAL_I2S_Transmit_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1100 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1101 {
1102 uint32_t tmpreg_cfgr;
1103
1104 if ((pData == NULL) || (Size == 0U))
1105 {
1106 return HAL_ERROR;
1107 }
1108
1109 /* Process Locked */
1110 __HAL_LOCK(hi2s);
1111
1112 if (hi2s->State != HAL_I2S_STATE_READY)
1113 {
1114 __HAL_UNLOCK(hi2s);
1115 return HAL_BUSY;
1116 }
1117
1118 /* Set state and reset error code */
1119 hi2s->State = HAL_I2S_STATE_BUSY_TX;
1120 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1121 hi2s->pTxBuffPtr = pData;
1122
1123 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1124
1125 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1126 {
1127 hi2s->TxXferSize = (Size << 1U);
1128 hi2s->TxXferCount = (Size << 1U);
1129 }
1130 else
1131 {
1132 hi2s->TxXferSize = Size;
1133 hi2s->TxXferCount = Size;
1134 }
1135
1136 /* Set the I2S Tx DMA Half transfer complete callback */
1137 hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
1138
1139 /* Set the I2S Tx DMA transfer complete callback */
1140 hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
1141
1142 /* Set the DMA error callback */
1143 hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
1144
1145 /* Enable the Tx DMA Stream/Channel */
1146 if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx,
1147 (uint32_t)hi2s->pTxBuffPtr,
1148 (uint32_t)&hi2s->Instance->DR,
1149 hi2s->TxXferSize))
1150 {
1151 /* Update SPI error code */
1152 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1153 hi2s->State = HAL_I2S_STATE_READY;
1154
1155 __HAL_UNLOCK(hi2s);
1156 return HAL_ERROR;
1157 }
1158
1159 /* Check if the I2S is already enabled */
1160 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1161 {
1162 /* Enable I2S peripheral */
1163 __HAL_I2S_ENABLE(hi2s);
1164 }
1165
1166 /* Check if the I2S Tx request is already enabled */
1167 if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN))
1168 {
1169 /* Enable Tx DMA Request */
1170 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1171 }
1172
1173 __HAL_UNLOCK(hi2s);
1174 return HAL_OK;
1175 }
1176
1177 /**
1178 * @brief Receive an amount of data in non-blocking mode with DMA
1179 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1180 * the configuration information for I2S module
1181 * @param pData a 16-bit pointer to the Receive data buffer.
1182 * @param Size number of data sample to be sent:
1183 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1184 * configuration phase, the Size parameter means the number of 16-bit data length
1185 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1186 * the Size parameter means the number of 24-bit or 32-bit data length.
1187 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1188 * between Master and Slave(example: audio streaming).
1189 * @retval HAL status
1190 */
HAL_I2S_Receive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)1191 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1192 {
1193 uint32_t tmpreg_cfgr;
1194
1195 if ((pData == NULL) || (Size == 0U))
1196 {
1197 return HAL_ERROR;
1198 }
1199
1200 /* Process Locked */
1201 __HAL_LOCK(hi2s);
1202
1203 if (hi2s->State != HAL_I2S_STATE_READY)
1204 {
1205 __HAL_UNLOCK(hi2s);
1206 return HAL_BUSY;
1207 }
1208
1209 /* Set state and reset error code */
1210 hi2s->State = HAL_I2S_STATE_BUSY_RX;
1211 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1212 hi2s->pRxBuffPtr = pData;
1213
1214 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
1215
1216 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
1217 {
1218 hi2s->RxXferSize = (Size << 1U);
1219 hi2s->RxXferCount = (Size << 1U);
1220 }
1221 else
1222 {
1223 hi2s->RxXferSize = Size;
1224 hi2s->RxXferCount = Size;
1225 }
1226
1227 /* Set the I2S Rx DMA Half transfer complete callback */
1228 hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
1229
1230 /* Set the I2S Rx DMA transfer complete callback */
1231 hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
1232
1233 /* Set the DMA error callback */
1234 hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1235
1236 /* Check if Master Receiver mode is selected */
1237 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
1238 {
1239 /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
1240 access to the SPI_SR register. */
1241 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1242 }
1243
1244 /* Enable the Rx DMA Stream/Channel */
1245 if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr,
1246 hi2s->RxXferSize))
1247 {
1248 /* Update SPI error code */
1249 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1250 hi2s->State = HAL_I2S_STATE_READY;
1251
1252 __HAL_UNLOCK(hi2s);
1253 return HAL_ERROR;
1254 }
1255
1256 /* Check if the I2S is already enabled */
1257 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1258 {
1259 /* Enable I2S peripheral */
1260 __HAL_I2S_ENABLE(hi2s);
1261 }
1262
1263 /* Check if the I2S Rx request is already enabled */
1264 if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN))
1265 {
1266 /* Enable Rx DMA Request */
1267 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1268 }
1269
1270 __HAL_UNLOCK(hi2s);
1271 return HAL_OK;
1272 }
1273
1274 /**
1275 * @brief Pauses the audio DMA Stream/Channel playing from the Media.
1276 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1277 * the configuration information for I2S module
1278 * @retval HAL status
1279 */
HAL_I2S_DMAPause(I2S_HandleTypeDef * hi2s)1280 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1281 {
1282 /* Process Locked */
1283 __HAL_LOCK(hi2s);
1284
1285 if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1286 {
1287 /* Disable the I2S DMA Tx request */
1288 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1289 }
1290 else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1291 {
1292 /* Disable the I2S DMA Rx request */
1293 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1294 }
1295 else
1296 {
1297 /* nothing to do */
1298 }
1299
1300 /* Process Unlocked */
1301 __HAL_UNLOCK(hi2s);
1302
1303 return HAL_OK;
1304 }
1305
1306 /**
1307 * @brief Resumes the audio DMA Stream/Channel playing from the Media.
1308 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1309 * the configuration information for I2S module
1310 * @retval HAL status
1311 */
HAL_I2S_DMAResume(I2S_HandleTypeDef * hi2s)1312 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1313 {
1314 /* Process Locked */
1315 __HAL_LOCK(hi2s);
1316
1317 if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1318 {
1319 /* Enable the I2S DMA Tx request */
1320 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1321 }
1322 else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1323 {
1324 /* Enable the I2S DMA Rx request */
1325 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1326 }
1327 else
1328 {
1329 /* nothing to do */
1330 }
1331
1332 /* If the I2S peripheral is still not enabled, enable it */
1333 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
1334 {
1335 /* Enable I2S peripheral */
1336 __HAL_I2S_ENABLE(hi2s);
1337 }
1338
1339 /* Process Unlocked */
1340 __HAL_UNLOCK(hi2s);
1341
1342 return HAL_OK;
1343 }
1344
1345 /**
1346 * @brief Stops the audio DMA Stream/Channel playing from the Media.
1347 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1348 * the configuration information for I2S module
1349 * @retval HAL status
1350 */
HAL_I2S_DMAStop(I2S_HandleTypeDef * hi2s)1351 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1352 {
1353 HAL_StatusTypeDef errorcode = HAL_OK;
1354 /* The Lock is not implemented on this API to allow the user application
1355 to call the HAL SPI API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1356 when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1357 and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1358 */
1359
1360 if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
1361 {
1362 /* Abort the I2S DMA tx Stream/Channel */
1363 if (hi2s->hdmatx != NULL)
1364 {
1365 /* Disable the I2S DMA tx Stream/Channel */
1366 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1367 {
1368 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1369 errorcode = HAL_ERROR;
1370 }
1371 }
1372
1373 /* Wait until TXE flag is set */
1374 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, I2S_TIMEOUT_FLAG) != HAL_OK)
1375 {
1376 /* Set the error code */
1377 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1378 hi2s->State = HAL_I2S_STATE_READY;
1379 errorcode = HAL_ERROR;
1380 }
1381
1382 /* Wait until BSY flag is Reset */
1383 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, I2S_TIMEOUT_FLAG) != HAL_OK)
1384 {
1385 /* Set the error code */
1386 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1387 hi2s->State = HAL_I2S_STATE_READY;
1388 errorcode = HAL_ERROR;
1389 }
1390
1391 /* Disable I2S peripheral */
1392 __HAL_I2S_DISABLE(hi2s);
1393
1394 /* Clear UDR flag */
1395 __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1396
1397 /* Disable the I2S Tx DMA requests */
1398 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1399
1400 }
1401
1402 else if ((hi2s->Init.Mode == I2S_MODE_MASTER_RX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_RX))
1403 {
1404 /* Abort the I2S DMA rx Stream/Channel */
1405 if (hi2s->hdmarx != NULL)
1406 {
1407 /* Disable the I2S DMA rx Stream/Channel */
1408 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1409 {
1410 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1411 errorcode = HAL_ERROR;
1412 }
1413 }
1414
1415 /* Disable I2S peripheral */
1416 __HAL_I2S_DISABLE(hi2s);
1417
1418 /* Clear OVR flag */
1419 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1420
1421 /* Disable the I2S Rx DMA request */
1422 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1423
1424 if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
1425 {
1426 /* Set the error code */
1427 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_BUSY_LINE_RX);
1428
1429 /* Set the I2S State ready */
1430 hi2s->State = HAL_I2S_STATE_READY;
1431 errorcode = HAL_ERROR;
1432 }
1433 else
1434 {
1435 /* Read DR to Flush RX Data */
1436 READ_REG((hi2s->Instance)->DR);
1437 }
1438 }
1439
1440 hi2s->State = HAL_I2S_STATE_READY;
1441
1442 return errorcode;
1443 }
1444
1445 /**
1446 * @brief This function handles I2S interrupt request.
1447 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1448 * the configuration information for I2S module
1449 * @retval None
1450 */
HAL_I2S_IRQHandler(I2S_HandleTypeDef * hi2s)1451 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1452 {
1453 uint32_t itsource = hi2s->Instance->CR2;
1454 uint32_t itflag = hi2s->Instance->SR;
1455
1456 /* I2S in mode Receiver ------------------------------------------------*/
1457 if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) == RESET) &&
1458 (I2S_CHECK_FLAG(itflag, I2S_FLAG_RXNE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_RXNE) != RESET))
1459 {
1460 I2S_Receive_IT(hi2s);
1461 return;
1462 }
1463
1464 /* I2S in mode Tramitter -----------------------------------------------*/
1465 if ((I2S_CHECK_FLAG(itflag, I2S_FLAG_TXE) != RESET) && (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_TXE) != RESET))
1466 {
1467 I2S_Transmit_IT(hi2s);
1468 return;
1469 }
1470
1471 /* I2S interrupt error -------------------------------------------------*/
1472 if (I2S_CHECK_IT_SOURCE(itsource, I2S_IT_ERR) != RESET)
1473 {
1474 /* I2S Overrun error interrupt occurred ---------------------------------*/
1475 if (I2S_CHECK_FLAG(itflag, I2S_FLAG_OVR) != RESET)
1476 {
1477 /* Disable RXNE and ERR interrupt */
1478 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1479
1480 /* Set the error code and execute error callback*/
1481 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1482 }
1483
1484 /* I2S Underrun error interrupt occurred --------------------------------*/
1485 if (I2S_CHECK_FLAG(itflag, I2S_FLAG_UDR) != RESET)
1486 {
1487 /* Disable TXE and ERR interrupt */
1488 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1489
1490 /* Set the error code and execute error callback*/
1491 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1492 }
1493
1494 /* Set the I2S State ready */
1495 hi2s->State = HAL_I2S_STATE_READY;
1496
1497 /* Call user error callback */
1498 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1499 hi2s->ErrorCallback(hi2s);
1500 #else
1501 HAL_I2S_ErrorCallback(hi2s);
1502 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1503 }
1504 }
1505
1506 /**
1507 * @brief Tx Transfer Half completed callbacks
1508 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1509 * the configuration information for I2S module
1510 * @retval None
1511 */
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1512 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1513 {
1514 /* Prevent unused argument(s) compilation warning */
1515 UNUSED(hi2s);
1516
1517 /* NOTE : This function Should not be modified, when the callback is needed,
1518 the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1519 */
1520 }
1521
1522 /**
1523 * @brief Tx Transfer completed callbacks
1524 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1525 * the configuration information for I2S module
1526 * @retval None
1527 */
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef * hi2s)1528 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
1529 {
1530 /* Prevent unused argument(s) compilation warning */
1531 UNUSED(hi2s);
1532
1533 /* NOTE : This function Should not be modified, when the callback is needed,
1534 the HAL_I2S_TxCpltCallback could be implemented in the user file
1535 */
1536 }
1537
1538 /**
1539 * @brief Rx Transfer half completed callbacks
1540 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1541 * the configuration information for I2S module
1542 * @retval None
1543 */
HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1544 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1545 {
1546 /* Prevent unused argument(s) compilation warning */
1547 UNUSED(hi2s);
1548
1549 /* NOTE : This function Should not be modified, when the callback is needed,
1550 the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
1551 */
1552 }
1553
1554 /**
1555 * @brief Rx Transfer completed callbacks
1556 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1557 * the configuration information for I2S module
1558 * @retval None
1559 */
HAL_I2S_RxCpltCallback(I2S_HandleTypeDef * hi2s)1560 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1561 {
1562 /* Prevent unused argument(s) compilation warning */
1563 UNUSED(hi2s);
1564
1565 /* NOTE : This function Should not be modified, when the callback is needed,
1566 the HAL_I2S_RxCpltCallback could be implemented in the user file
1567 */
1568 }
1569
1570 /**
1571 * @brief I2S error callbacks
1572 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1573 * the configuration information for I2S module
1574 * @retval None
1575 */
HAL_I2S_ErrorCallback(I2S_HandleTypeDef * hi2s)1576 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
1577 {
1578 /* Prevent unused argument(s) compilation warning */
1579 UNUSED(hi2s);
1580
1581 /* NOTE : This function Should not be modified, when the callback is needed,
1582 the HAL_I2S_ErrorCallback could be implemented in the user file
1583 */
1584 }
1585
1586 /**
1587 * @}
1588 */
1589
1590 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1591 * @brief Peripheral State functions
1592 *
1593 @verbatim
1594 ===============================================================================
1595 ##### Peripheral State and Errors functions #####
1596 ===============================================================================
1597 [..]
1598 This subsection permits to get in run-time the status of the peripheral
1599 and the data flow.
1600
1601 @endverbatim
1602 * @{
1603 */
1604
1605 /**
1606 * @brief Return the I2S state
1607 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1608 * the configuration information for I2S module
1609 * @retval HAL state
1610 */
HAL_I2S_GetState(I2S_HandleTypeDef * hi2s)1611 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1612 {
1613 return hi2s->State;
1614 }
1615
1616 /**
1617 * @brief Return the I2S error code
1618 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1619 * the configuration information for I2S module
1620 * @retval I2S Error Code
1621 */
HAL_I2S_GetError(I2S_HandleTypeDef * hi2s)1622 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1623 {
1624 return hi2s->ErrorCode;
1625 }
1626 /**
1627 * @}
1628 */
1629
1630 /**
1631 * @}
1632 */
1633
1634 /** @addtogroup I2S_Private_Functions I2S Private Functions
1635 * @{
1636 */
1637 /**
1638 * @brief DMA I2S transmit process complete callback
1639 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1640 * the configuration information for the specified DMA module.
1641 * @retval None
1642 */
I2S_DMATxCplt(DMA_HandleTypeDef * hdma)1643 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1644 {
1645 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1646
1647 /* if DMA is configured in DMA_NORMAL Mode */
1648 if (hdma->Init.Mode == DMA_NORMAL)
1649 {
1650 /* Disable Tx DMA Request */
1651 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
1652
1653 hi2s->TxXferCount = 0U;
1654 hi2s->State = HAL_I2S_STATE_READY;
1655 }
1656 /* Call user Tx complete callback */
1657 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1658 hi2s->TxCpltCallback(hi2s);
1659 #else
1660 HAL_I2S_TxCpltCallback(hi2s);
1661 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1662 }
1663
1664 /**
1665 * @brief DMA I2S transmit process half complete callback
1666 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1667 * the configuration information for the specified DMA module.
1668 * @retval None
1669 */
I2S_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1670 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1671 {
1672 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1673
1674 /* Call user Tx half complete callback */
1675 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1676 hi2s->TxHalfCpltCallback(hi2s);
1677 #else
1678 HAL_I2S_TxHalfCpltCallback(hi2s);
1679 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1680 }
1681
1682 /**
1683 * @brief DMA I2S receive process complete callback
1684 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1685 * the configuration information for the specified DMA module.
1686 * @retval None
1687 */
I2S_DMARxCplt(DMA_HandleTypeDef * hdma)1688 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1689 {
1690 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1691
1692 /* if DMA is configured in DMA_NORMAL Mode */
1693 if (hdma->Init.Mode == DMA_NORMAL)
1694 {
1695 /* Disable Rx DMA Request */
1696 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
1697 hi2s->RxXferCount = 0U;
1698 hi2s->State = HAL_I2S_STATE_READY;
1699 }
1700 /* Call user Rx complete callback */
1701 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1702 hi2s->RxCpltCallback(hi2s);
1703 #else
1704 HAL_I2S_RxCpltCallback(hi2s);
1705 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1706 }
1707
1708 /**
1709 * @brief DMA I2S receive process half complete callback
1710 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1711 * the configuration information for the specified DMA module.
1712 * @retval None
1713 */
I2S_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1714 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1715 {
1716 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1717
1718 /* Call user Rx half complete callback */
1719 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1720 hi2s->RxHalfCpltCallback(hi2s);
1721 #else
1722 HAL_I2S_RxHalfCpltCallback(hi2s);
1723 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1724 }
1725
1726 /**
1727 * @brief DMA I2S communication error callback
1728 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1729 * the configuration information for the specified DMA module.
1730 * @retval None
1731 */
I2S_DMAError(DMA_HandleTypeDef * hdma)1732 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1733 {
1734 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
1735
1736 /* Disable Rx and Tx DMA Request */
1737 CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1738 hi2s->TxXferCount = 0U;
1739 hi2s->RxXferCount = 0U;
1740
1741 hi2s->State = HAL_I2S_STATE_READY;
1742
1743 /* Set the error code and execute error callback*/
1744 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1745 /* Call user error callback */
1746 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1747 hi2s->ErrorCallback(hi2s);
1748 #else
1749 HAL_I2S_ErrorCallback(hi2s);
1750 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1751 }
1752
1753 /**
1754 * @brief Transmit an amount of data in non-blocking mode with Interrupt
1755 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1756 * the configuration information for I2S module
1757 * @retval None
1758 */
I2S_Transmit_IT(I2S_HandleTypeDef * hi2s)1759 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
1760 {
1761 /* Transmit data */
1762 hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
1763 hi2s->pTxBuffPtr++;
1764 hi2s->TxXferCount--;
1765
1766 if (hi2s->TxXferCount == 0U)
1767 {
1768 /* Disable TXE and ERR interrupt */
1769 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1770
1771 hi2s->State = HAL_I2S_STATE_READY;
1772 /* Call user Tx complete callback */
1773 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1774 hi2s->TxCpltCallback(hi2s);
1775 #else
1776 HAL_I2S_TxCpltCallback(hi2s);
1777 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1778 }
1779 }
1780
1781 /**
1782 * @brief Receive an amount of data in non-blocking mode with Interrupt
1783 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1784 * the configuration information for I2S module
1785 * @retval None
1786 */
I2S_Receive_IT(I2S_HandleTypeDef * hi2s)1787 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
1788 {
1789 /* Receive data */
1790 (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
1791 hi2s->pRxBuffPtr++;
1792 hi2s->RxXferCount--;
1793
1794 if (hi2s->RxXferCount == 0U)
1795 {
1796 /* Disable RXNE and ERR interrupt */
1797 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1798
1799 hi2s->State = HAL_I2S_STATE_READY;
1800 /* Call user Rx complete callback */
1801 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
1802 hi2s->RxCpltCallback(hi2s);
1803 #else
1804 HAL_I2S_RxCpltCallback(hi2s);
1805 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1806 }
1807 }
1808
1809 /**
1810 * @brief This function handles I2S Communication Timeout.
1811 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
1812 * the configuration information for I2S module
1813 * @param Flag Flag checked
1814 * @param State Value of the flag expected
1815 * @param Timeout Duration of the timeout
1816 * @retval HAL status
1817 */
I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,FlagStatus State,uint32_t Timeout)1818 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
1819 uint32_t Timeout)
1820 {
1821 uint32_t tickstart;
1822
1823 /* Get tick */
1824 tickstart = HAL_GetTick();
1825
1826 /* Wait until flag is set to status*/
1827 while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
1828 {
1829 if (Timeout != HAL_MAX_DELAY)
1830 {
1831 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
1832 {
1833 /* Set the I2S State ready */
1834 hi2s->State = HAL_I2S_STATE_READY;
1835
1836 /* Process Unlocked */
1837 __HAL_UNLOCK(hi2s);
1838
1839 return HAL_TIMEOUT;
1840 }
1841 }
1842 }
1843 return HAL_OK;
1844 }
1845
1846 /**
1847 * @}
1848 */
1849
1850 /**
1851 * @}
1852 */
1853
1854 /**
1855 * @}
1856 */
1857 #endif /* SPI_I2S_SUPPORT */
1858
1859 #endif /* HAL_I2S_MODULE_ENABLED */
1860
1861