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