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