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