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