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