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