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