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