1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_i2s.c
4 * @author MCD Application Team
5 * @version V1.0.1
6 * @date 25-June-2015
7 * @brief I2S HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Integrated Interchip Sound (I2S) peripheral:
10 * + Initialization and de-initialization functions
11 * + IO operation functions
12 * + Peripheral State and Errors functions
13 @verbatim
14 ===============================================================================
15 ##### How to use this driver #####
16 ===============================================================================
17 [..]
18 The I2S HAL driver can be used as follows:
19
20 (#) Declare a I2S_HandleTypeDef handle structure.
21 (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
22 (##) Enable the SPIx interface clock.
23 (##) I2S pins configuration:
24 (+++) Enable the clock for the I2S GPIOs.
25 (+++) Configure these I2S pins as alternate function pull-up.
26 (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
27 and HAL_I2S_Receive_IT() APIs).
28 (+++) Configure the I2Sx interrupt priority.
29 (+++) Enable the NVIC I2S IRQ handle.
30 (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
31 and HAL_I2S_Receive_DMA() APIs:
32 (+++) Declare a DMA handle structure for the Tx/Rx channel.
33 (+++) Enable the DMAx interface clock.
34 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
35 (+++) Configure the DMA Tx/Rx Channel.
36 (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
37 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
38 DMA Tx/Rx Channel.
39
40 (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
41 using HAL_I2S_Init() function.
42
43 -@- The specific I2S interrupts (Transmission complete interrupt,
44 RXNE interrupt and Error Interrupts) will be managed using the macros
45 __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
46 -@- Make sure that either:
47 (+@) I2S clock is configured based on SYSCLK or
48 (+@) External clock source is configured after setting correctly
49 the define constant EXTERNAL_CLOCK_VALUE in the stm32f3xx_hal_conf.h file.
50
51 (#) Three mode of operations are available within this driver :
52
53 *** Polling mode IO operation ***
54 =================================
55 [..]
56 (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
57 (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
58
59 *** Interrupt mode IO operation ***
60 ===================================
61 [..]
62 (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
63 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
64 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
65 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
66 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
67 (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
68 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
69 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
70 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
71 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
72 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
73 add his own code by customization of function pointer HAL_I2S_ErrorCallback
74
75 *** DMA mode IO operation ***
76 ==============================
77 [..]
78 (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
79 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
80 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
81 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
82 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
83 (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
84 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
85 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
86 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
87 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
88 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
89 add his own code by customization of function pointer HAL_I2S_ErrorCallback
90 (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
91 (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
92 (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
93
94 *** I2S HAL driver macros list ***
95 =============================================
96 [..]
97 Below the list of most used macros in I2S HAL driver.
98
99 (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
100 (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
101 (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
102 (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
103 (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
104
105 [..]
106 (@) You can refer to the I2S HAL driver header file for more useful macros
107
108 @endverbatim
109 ******************************************************************************
110 * @attention
111 *
112 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
113 *
114 * Redistribution and use in source and binary forms, with or without modification,
115 * are permitted provided that the following conditions are met:
116 * 1. Redistributions of source code must retain the above copyright notice,
117 * this list of conditions and the following disclaimer.
118 * 2. Redistributions in binary form must reproduce the above copyright notice,
119 * this list of conditions and the following disclaimer in the documentation
120 * and/or other materials provided with the distribution.
121 * 3. Neither the name of STMicroelectronics nor the names of its contributors
122 * may be used to endorse or promote products derived from this software
123 * without specific prior written permission.
124 *
125 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
126 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
127 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
129 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
130 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
131 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
132 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
133 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
134 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135 *
136 ******************************************************************************
137 */
138
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32f7xx_hal.h"
141
142 /** @addtogroup STM32F7xx_HAL_Driver
143 * @{
144 */
145
146 /** @defgroup I2S I2S
147 * @brief I2S HAL module driver
148 * @{
149 */
150
151 #ifdef HAL_I2S_MODULE_ENABLED
152
153 /* Private typedef -----------------------------------------------------------*/
154 /* Private define ------------------------------------------------------------*/
155 /* Private macro -------------------------------------------------------------*/
156 /* Private variables ---------------------------------------------------------*/
157 /* Private function prototypes -----------------------------------------------*/
158 /** @defgroup I2S_Private_Functions I2S Private Functions
159 * @{
160 */
161 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
162 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
163 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
164 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
165 static void I2S_DMAError(DMA_HandleTypeDef *hdma);
166 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
167 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
168 static uint32_t I2S_GetClockFreq(I2S_HandleTypeDef *hi2s);
169 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State, uint32_t Timeout);
170 /**
171 * @}
172 */
173
174 /* Exported functions ---------------------------------------------------------*/
175
176 /** @defgroup I2S_Exported_Functions I2S Exported Functions
177 * @{
178 */
179
180 /** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions
181 * @brief Initialization and Configuration functions
182 *
183 @verbatim
184 ===============================================================================
185 ##### Initialization and de-initialization functions #####
186 ===============================================================================
187 [..] This subsection provides a set of functions allowing to initialize and
188 de-initialize the I2Sx peripheral in simplex mode:
189
190 (+) User must Implement HAL_I2S_MspInit() function in which he configures
191 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
192
193 (+) Call the function HAL_I2S_Init() to configure the selected device with
194 the selected configuration:
195 (++) Mode
196 (++) Standard
197 (++) Data Format
198 (++) MCLK Output
199 (++) Audio frequency
200 (++) Polarity
201 (++) Full duplex mode
202
203 (+) Call the function HAL_I2S_DeInit() to restore the default configuration
204 of the selected I2Sx peripheral.
205 @endverbatim
206 * @{
207 */
208
209 /**
210 * @brief Initializes the I2S according to the specified parameters
211 * in the I2S_InitTypeDef and create the associated handle.
212 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
213 * the configuration information for I2S module
214 * @retval HAL status
215 */
HAL_I2S_Init(I2S_HandleTypeDef * hi2s)216 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
217 {
218 uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
219 uint32_t tmp = 0, i2sclk = 0;
220
221 /* Check the I2S handle allocation */
222 if (hi2s == NULL) {
223 return HAL_ERROR;
224 }
225
226 /* Check the parameters */
227 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
228 assert_param(IS_I2S_MODE(hi2s->Init.Mode));
229 assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
230 assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
231 assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
232 assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
233 assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
234 assert_param(IS_I2S_CLOCKSOURCE(hi2s->Init.ClockSource));
235
236 if (hi2s->State == HAL_I2S_STATE_RESET) {
237 /* Allocate lock resource and initialize it */
238 hi2s->Lock = HAL_UNLOCKED;
239 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
240 HAL_I2S_MspInit(hi2s);
241 }
242
243 hi2s->State = HAL_I2S_STATE_BUSY;
244
245 /*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
246 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
247 hi2s->Instance->I2SCFGR &= ~(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
248 SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
249 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD);
250 hi2s->Instance->I2SPR = 0x0002;
251
252 /* Get the I2SCFGR register value */
253 tmpreg = hi2s->Instance->I2SCFGR;
254
255 /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
256 if (hi2s->Init.AudioFreq == I2S_AUDIOFREQ_DEFAULT) {
257 i2sodd = (uint16_t)0;
258 i2sdiv = (uint16_t)2;
259 }
260 /* If the requested audio frequency is not the default, compute the prescaler */
261 else {
262 /* Check the frame length (For the Prescaler computing) *******************/
263 if (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) {
264 /* Packet length is 16 bits */
265 packetlength = 1;
266 } else {
267 /* Packet length is 32 bits */
268 packetlength = 2;
269 }
270
271 /* Get I2S source Clock frequency ****************************************/
272
273 /* If an external I2S clock has to be used, the specific define should be set
274 in the project configuration or in the stm32f3xx_conf.h file */
275 if (hi2s->Init.ClockSource == I2S_CLOCK_EXTERNAL) {
276 /* Set the I2S clock to the external clock value */
277 i2sclk = EXTERNAL_CLOCK_VALUE;
278 } else {
279 /* Get the I2S source clock value */
280 i2sclk = I2S_GetClockFreq(hi2s);
281 }
282
283 /* Compute the Real divider depending on the MCLK output state, with a floating point */
284 if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE) {
285 /* MCLK output is enabled */
286 tmp = (uint16_t)(((((i2sclk / 256) * 10) / hi2s->Init.AudioFreq)) + 5);
287 } else {
288 /* MCLK output is disabled */
289 tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / hi2s->Init.AudioFreq)) + 5);
290 }
291
292 /* Remove the flatting point */
293 tmp = tmp / 10;
294
295 /* Check the parity of the divider */
296 i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
297
298 /* Compute the i2sdiv prescaler */
299 i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
300
301 /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
302 i2sodd = (uint16_t) (i2sodd << 8);
303 }
304
305 /* Test if the divider is 1 or 0 or greater than 0xFF */
306 if ((i2sdiv < 2) || (i2sdiv > 0xFF)) {
307 /* Set the default values */
308 i2sdiv = 2;
309 i2sodd = 0;
310 }
311
312 /* Write to SPIx I2SPR register the computed value */
313 hi2s->Instance->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)hi2s->Init.MCLKOutput));
314
315 /* Configure the I2S with the I2S_InitStruct values */
316 tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(hi2s->Init.Mode | \
317 (uint16_t)(hi2s->Init.Standard | (uint16_t)(hi2s->Init.DataFormat | \
318 (uint16_t)hi2s->Init.CPOL))));
319
320 /* Write to SPIx I2SCFGR */
321 hi2s->Instance->I2SCFGR = tmpreg;
322
323 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
324 hi2s->State= HAL_I2S_STATE_READY;
325
326 return HAL_OK;
327 }
328
329 /**
330 * @brief DeInitializes the I2S peripheral
331 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
332 * the configuration information for I2S module
333 * @retval HAL status
334 */
HAL_I2S_DeInit(I2S_HandleTypeDef * hi2s)335 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
336 {
337 /* Check the I2S handle allocation */
338 if (hi2s == NULL) {
339 return HAL_ERROR;
340 }
341
342 /* Check the parameters */
343 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
344
345 hi2s->State = HAL_I2S_STATE_BUSY;
346
347 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
348 HAL_I2S_MspDeInit(hi2s);
349
350 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
351 hi2s->State = HAL_I2S_STATE_RESET;
352
353 /* Release Lock */
354 __HAL_UNLOCK(hi2s);
355
356 return HAL_OK;
357 }
358
359 /**
360 * @brief I2S MSP Init
361 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
362 * the configuration information for I2S module
363 * @retval None
364 */
HAL_I2S_MspInit(I2S_HandleTypeDef * hi2s)365 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
366 {
367 /* NOTE : This function Should not be modified, when the callback is needed,
368 the HAL_I2S_MspInit could be implemented in the user file
369 */
370 }
371
372 /**
373 * @brief I2S MSP DeInit
374 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
375 * the configuration information for I2S module
376 * @retval None
377 */
HAL_I2S_MspDeInit(I2S_HandleTypeDef * hi2s)378 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
379 {
380 /* NOTE : This function Should not be modified, when the callback is needed,
381 the HAL_I2S_MspDeInit could be implemented in the user file
382 */
383 }
384
385 /**
386 * @}
387 */
388
389 /** @defgroup I2S_Exported_Functions_Group2 Input and Output operation functions
390 * @brief Data transfers functions
391 *
392 @verbatim
393 ===============================================================================
394 ##### IO operation functions #####
395 ===============================================================================
396 [..]
397 This subsection provides a set of functions allowing to manage the I2S data
398 transfers.
399
400 (#) There are two modes of transfer:
401 (++) Blocking mode : The communication is performed in the polling mode.
402 The status of all data processing is returned by the same function
403 after finishing transfer.
404 (++) No-Blocking mode : The communication is performed using Interrupts
405 or DMA. These functions return the status of the transfer startup.
406 The end of the data processing will be indicated through the
407 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
408 using DMA mode.
409
410 (#) Blocking mode functions are :
411 (++) HAL_I2S_Transmit()
412 (++) HAL_I2S_Receive()
413
414 (#) No-Blocking mode functions with Interrupt are :
415 (++) HAL_I2S_Transmit_IT()
416 (++) HAL_I2S_Receive_IT()
417
418 (#) No-Blocking mode functions with DMA are :
419 (++) HAL_I2S_Transmit_DMA()
420 (++) HAL_I2S_Receive_DMA()
421
422 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
423 (++) HAL_I2S_TxCpltCallback()
424 (++) HAL_I2S_RxCpltCallback()
425 (++) HAL_I2S_ErrorCallback()
426
427 @endverbatim
428 * @{
429 */
430
431 /**
432 * @brief Transmit an amount of data in blocking mode
433 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
434 * the configuration information for I2S module
435 * @param pData: a 16-bit pointer to data buffer.
436 * @param Size: number of data sample to be sent:
437 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
438 * configuration phase, the Size parameter means the number of 16-bit data length
439 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
440 * the Size parameter means the number of 16-bit data length.
441 * @param Timeout: Timeout duration
442 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
443 * between Master and Slave(example: audio streaming).
444 * @retval HAL status
445 */
HAL_I2S_Transmit(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)446 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
447 {
448 if ((pData == NULL ) || (Size == 0)) {
449 return HAL_ERROR;
450 }
451
452 if (hi2s->State == HAL_I2S_STATE_READY) {
453 if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
454 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
455 hi2s->TxXferSize = (Size << 1);
456 hi2s->TxXferCount = (Size << 1);
457 } else {
458 hi2s->TxXferSize = Size;
459 hi2s->TxXferCount = Size;
460 }
461
462 /* Process Locked */
463 __HAL_LOCK(hi2s);
464
465 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
466 hi2s->State = HAL_I2S_STATE_BUSY_TX;
467
468 /* Check if the I2S is already enabled */
469 if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
470 /* Enable I2S peripheral */
471 __HAL_I2S_ENABLE(hi2s);
472 }
473
474 while (hi2s->TxXferCount > 0) {
475 hi2s->Instance->DR = (*pData++);
476 hi2s->TxXferCount--;
477 /* Wait until TXE flag is set */
478 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK) {
479 /* Set the error code and execute error callback*/
480 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
481 HAL_I2S_ErrorCallback(hi2s);
482 return HAL_TIMEOUT;
483 }
484
485 /* Check if an underrun occurs */
486 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) {
487 /* Set the I2S State ready */
488 hi2s->State = HAL_I2S_STATE_READY;
489
490 /* Process Unlocked */
491 __HAL_UNLOCK(hi2s);
492
493 /* Set the error code and execute error callback*/
494 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
495 HAL_I2S_ErrorCallback(hi2s);
496
497 return HAL_ERROR;
498 }
499 }
500
501 /* Check if Slave mode is selected */
502 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX)) {
503 /* Wait until Busy flag is reset */
504 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK) {
505 /* Set the error code and execute error callback*/
506 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
507 HAL_I2S_ErrorCallback(hi2s);
508 return HAL_TIMEOUT;
509 }
510 }
511
512 hi2s->State = HAL_I2S_STATE_READY;
513
514 /* Process Unlocked */
515 __HAL_UNLOCK(hi2s);
516
517 return HAL_OK;
518 } else {
519 return HAL_BUSY;
520 }
521 }
522
523 /**
524 * @brief Receive an amount of data in blocking mode
525 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
526 * the configuration information for I2S module
527 * @param pData: a 16-bit pointer to data buffer.
528 * @param Size: number of data sample to be sent:
529 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
530 * configuration phase, the Size parameter means the number of 16-bit data length
531 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
532 * the Size parameter means the number of 16-bit data length.
533 * @param Timeout: Timeout duration
534 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
535 * between Master and Slave(example: audio streaming).
536 * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
537 * in continuous way and as the I2S is not disabled at the end of the I2S transaction.
538 * @retval HAL status
539 */
HAL_I2S_Receive(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)540 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
541 {
542 if ((pData == NULL ) || (Size == 0)) {
543 return HAL_ERROR;
544 }
545
546 if (hi2s->State == HAL_I2S_STATE_READY) {
547 if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
548 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
549 hi2s->RxXferSize = (Size << 1);
550 hi2s->RxXferCount = (Size << 1);
551 } else {
552 hi2s->RxXferSize = Size;
553 hi2s->RxXferCount = Size;
554 }
555 /* Process Locked */
556 __HAL_LOCK(hi2s);
557
558 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
559 hi2s->State = HAL_I2S_STATE_BUSY_RX;
560
561 /* Check if the I2S is already enabled */
562 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
563 /* Enable I2S peripheral */
564 __HAL_I2S_ENABLE(hi2s);
565 }
566
567 /* Check if Master Receiver mode is selected */
568 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) {
569 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
570 access to the SPI_SR register. */
571 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
572 }
573
574 /* Receive data */
575 while (hi2s->RxXferCount > 0) {
576 /* Wait until RXNE flag is set */
577 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK) {
578 /* Set the error code and execute error callback*/
579 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
580 HAL_I2S_ErrorCallback(hi2s);
581 return HAL_TIMEOUT;
582 }
583
584 /* Check if an overrun occurs */
585 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) {
586 /* Set the I2S State ready */
587 hi2s->State = HAL_I2S_STATE_READY;
588
589 /* Process Unlocked */
590 __HAL_UNLOCK(hi2s);
591
592 /* Set the error code and execute error callback*/
593 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
594 HAL_I2S_ErrorCallback(hi2s);
595
596 return HAL_ERROR;
597 }
598
599 (*pData++) = hi2s->Instance->DR;
600 hi2s->RxXferCount--;
601 }
602
603 hi2s->State = HAL_I2S_STATE_READY;
604
605 /* Process Unlocked */
606 __HAL_UNLOCK(hi2s);
607
608 return HAL_OK;
609 } else {
610 return HAL_BUSY;
611 }
612 }
613
614 /**
615 * @brief Transmit an amount of data in non-blocking mode with Interrupt
616 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
617 * the configuration information for I2S module
618 * @param pData: a 16-bit pointer to data buffer.
619 * @param Size: number of data sample to be sent:
620 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
621 * configuration phase, the Size parameter means the number of 16-bit data length
622 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
623 * the Size parameter means the number of 16-bit data length.
624 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
625 * between Master and Slave(example: audio streaming).
626 * @retval HAL status
627 */
HAL_I2S_Transmit_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)628 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
629 {
630 if (hi2s->State == HAL_I2S_STATE_READY) {
631 if ((pData == NULL) || (Size == 0)) {
632 return HAL_ERROR;
633 }
634
635 hi2s->pTxBuffPtr = pData;
636 if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
637 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
638 hi2s->TxXferSize = (Size << 1);
639 hi2s->TxXferCount = (Size << 1);
640 } else {
641 hi2s->TxXferSize = Size;
642 hi2s->TxXferCount = Size;
643 }
644
645 /* Process Locked */
646 __HAL_LOCK(hi2s);
647
648 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
649 hi2s->State = HAL_I2S_STATE_BUSY_TX;
650
651 /* Enable TXE and ERR interrupt */
652 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
653
654 /* Check if the I2S is already enabled */
655 if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
656 /* Enable I2S peripheral */
657 __HAL_I2S_ENABLE(hi2s);
658 }
659
660 /* Process Unlocked */
661 __HAL_UNLOCK(hi2s);
662
663 return HAL_OK;
664 } else {
665 return HAL_BUSY;
666 }
667 }
668
669 /**
670 * @brief Receive an amount of data in non-blocking mode with Interrupt
671 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
672 * the configuration information for I2S module
673 * @param pData: a 16-bit pointer to the Receive data buffer.
674 * @param Size: number of data sample to be sent:
675 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
676 * configuration phase, the Size parameter means the number of 16-bit data length
677 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
678 * the Size parameter means the number of 16-bit data length.
679 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
680 * between Master and Slave(example: audio streaming).
681 * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronisation
682 * between Master and Slave otherwise the I2S interrupt should be optimized.
683 * @retval HAL status
684 */
HAL_I2S_Receive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)685 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
686 {
687 if (hi2s->State == HAL_I2S_STATE_READY) {
688 if ((pData == NULL) || (Size == 0)) {
689 return HAL_ERROR;
690 }
691
692 hi2s->pRxBuffPtr = pData;
693 if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
694 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
695 hi2s->RxXferSize = (Size << 1);
696 hi2s->RxXferCount = (Size << 1);
697 } else {
698 hi2s->RxXferSize = Size;
699 hi2s->RxXferCount = Size;
700 }
701 /* Process Locked */
702 __HAL_LOCK(hi2s);
703
704 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
705 hi2s->State = HAL_I2S_STATE_BUSY_RX;
706
707 /* Enable TXE and ERR interrupt */
708 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
709
710 /* Check if the I2S is already enabled */
711 if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
712 /* Enable I2S peripheral */
713 __HAL_I2S_ENABLE(hi2s);
714 }
715
716 /* Process Unlocked */
717 __HAL_UNLOCK(hi2s);
718
719 return HAL_OK;
720 } else {
721 return HAL_BUSY;
722 }
723 }
724
725 /**
726 * @brief Transmit an amount of data in non-blocking mode with DMA
727 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
728 * the configuration information for I2S module
729 * @param pData: a 16-bit pointer to the Transmit data buffer.
730 * @param Size: number of data sample to be sent:
731 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
732 * configuration phase, the Size parameter means the number of 16-bit data length
733 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
734 * the Size parameter means the number of 16-bit data length.
735 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
736 * between Master and Slave(example: audio streaming).
737 * @retval HAL status
738 */
HAL_I2S_Transmit_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)739 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
740 {
741 uint32_t *tmp;
742
743 if ((pData == NULL) || (Size == 0)) {
744 return HAL_ERROR;
745 }
746
747 if (hi2s->State == HAL_I2S_STATE_READY) {
748 hi2s->pTxBuffPtr = pData;
749 if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
750 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
751 hi2s->TxXferSize = (Size << 1);
752 hi2s->TxXferCount = (Size << 1);
753 } else {
754 hi2s->TxXferSize = Size;
755 hi2s->TxXferCount = Size;
756 }
757
758 /* Process Locked */
759 __HAL_LOCK(hi2s);
760
761 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
762 hi2s->State = HAL_I2S_STATE_BUSY_TX;
763
764 /* Set the I2S Tx DMA Half transfer complete callback */
765 hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
766
767 /* Set the I2S TxDMA transfer complete callback */
768 hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
769
770 /* Set the DMA error callback */
771 hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
772
773 /* Enable the Tx DMA Channel */
774 tmp = (uint32_t*)&pData;
775 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
776
777 /* Check if the I2S is already enabled */
778 if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
779 /* Enable I2S peripheral */
780 __HAL_I2S_ENABLE(hi2s);
781 }
782
783 /* Enable Tx DMA Request */
784 hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN;
785
786 /* Process Unlocked */
787 __HAL_UNLOCK(hi2s);
788
789 return HAL_OK;
790 } else {
791 return HAL_BUSY;
792 }
793 }
794
795 /**
796 * @brief Receive an amount of data in non-blocking mode with DMA
797 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
798 * the configuration information for I2S module
799 * @param pData: a 16-bit pointer to the Receive data buffer.
800 * @param Size: number of data sample to be sent:
801 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
802 * configuration phase, the Size parameter means the number of 16-bit data length
803 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
804 * the Size parameter means the number of 16-bit data length.
805 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
806 * between Master and Slave(example: audio streaming).
807 * @retval HAL status
808 */
HAL_I2S_Receive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)809 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
810 {
811 uint32_t *tmp;
812
813 if ((pData == NULL) || (Size == 0)) {
814 return HAL_ERROR;
815 }
816
817 if (hi2s->State == HAL_I2S_STATE_READY) {
818 hi2s->pRxBuffPtr = pData;
819 if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
820 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
821 hi2s->RxXferSize = (Size << 1);
822 hi2s->RxXferCount = (Size << 1);
823 } else {
824 hi2s->RxXferSize = Size;
825 hi2s->RxXferCount = Size;
826 }
827 /* Process Locked */
828 __HAL_LOCK(hi2s);
829
830 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
831 hi2s->State = HAL_I2S_STATE_BUSY_RX;
832
833 /* Set the I2S Rx DMA Half transfer complete callback */
834 hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
835
836 /* Set the I2S Rx DMA transfer complete callback */
837 hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
838
839 /* Set the DMA error callback */
840 hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
841
842 /* Check if Master Receiver mode is selected */
843 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) {
844 /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
845 access to the SPI_SR register. */
846 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
847 }
848
849 /* Enable the Rx DMA Channel */
850 tmp = (uint32_t*)&pData;
851 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
852
853 /* Check if the I2S is already enabled */
854 if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
855 /* Enable I2S peripheral */
856 __HAL_I2S_ENABLE(hi2s);
857 }
858
859 /* Enable Rx DMA Request */
860 hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;
861
862 /* Process Unlocked */
863 __HAL_UNLOCK(hi2s);
864
865 return HAL_OK;
866 } else {
867 return HAL_BUSY;
868 }
869 }
870
871 /**
872 * @brief Pauses the audio stream playing from the Media.
873 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
874 * the configuration information for I2S module
875 * @retval HAL status
876 */
HAL_I2S_DMAPause(I2S_HandleTypeDef * hi2s)877 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
878 {
879 /* Process Locked */
880 __HAL_LOCK(hi2s);
881
882 if (hi2s->State == HAL_I2S_STATE_BUSY_TX) {
883 /* Disable the I2S DMA Tx request */
884 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
885 } else if (hi2s->State == HAL_I2S_STATE_BUSY_RX) {
886 /* Disable the I2S DMA Rx request */
887 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
888 } else if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) {
889 if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX)||(hi2s->Init.Mode == I2S_MODE_MASTER_TX)) {
890 /* Disable the I2S DMA Tx request */
891 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
892 } else {
893 /* Disable the I2S DMA Rx request */
894 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
895 }
896 }
897
898 /* Process Unlocked */
899 __HAL_UNLOCK(hi2s);
900
901 return HAL_OK;
902 }
903
904 /**
905 * @brief Resumes the audio stream playing from the Media.
906 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
907 * the configuration information for I2S module
908 * @retval HAL status
909 */
HAL_I2S_DMAResume(I2S_HandleTypeDef * hi2s)910 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
911 {
912 /* Process Locked */
913 __HAL_LOCK(hi2s);
914
915 if (hi2s->State == HAL_I2S_STATE_BUSY_TX) {
916 /* Enable the I2S DMA Tx request */
917 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
918 } else if (hi2s->State == HAL_I2S_STATE_BUSY_RX) {
919 /* Enable the I2S DMA Rx request */
920 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
921 }
922
923 /* If the I2S peripheral is still not enabled, enable it */
924 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE)) {
925 /* Enable I2S peripheral */
926 __HAL_I2S_ENABLE(hi2s);
927 }
928
929 /* Process Unlocked */
930 __HAL_UNLOCK(hi2s);
931
932 return HAL_OK;
933 }
934
935 /**
936 * @brief Stops the audio stream playing from the Media.
937 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
938 * the configuration information for I2S module
939 * @retval HAL status
940 */
HAL_I2S_DMAStop(I2S_HandleTypeDef * hi2s)941 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
942 {
943 /* Process Locked */
944 __HAL_LOCK(hi2s);
945
946 /* Disable the I2S Tx/Rx DMA requests */
947 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
948 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
949
950 /* Abort the I2S DMA Channel tx */
951 if (hi2s->hdmatx != NULL) {
952 /* Disable the I2S DMA channel */
953 __HAL_DMA_DISABLE(hi2s->hdmatx);
954 HAL_DMA_Abort(hi2s->hdmatx);
955 }
956 /* Abort the I2S DMA Channel rx */
957 if (hi2s->hdmarx != NULL) {
958 /* Disable the I2S DMA channel */
959 __HAL_DMA_DISABLE(hi2s->hdmarx);
960 HAL_DMA_Abort(hi2s->hdmarx);
961 }
962
963 /* Disable I2S peripheral */
964 __HAL_I2S_DISABLE(hi2s);
965
966 hi2s->State = HAL_I2S_STATE_READY;
967
968 /* Process Unlocked */
969 __HAL_UNLOCK(hi2s);
970
971 return HAL_OK;
972 }
973
974 /**
975 * @brief This function handles I2S interrupt request.
976 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
977 * the configuration information for I2S module
978 * @retval HAL status
979 */
HAL_I2S_IRQHandler(I2S_HandleTypeDef * hi2s)980 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
981 {
982 __IO uint32_t i2ssr = hi2s->Instance->SR;
983
984 if (hi2s->State == HAL_I2S_STATE_BUSY_RX) {
985 /* I2S in mode Receiver ----------------------------------------------------*/
986 if (((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET)) {
987 I2S_Receive_IT(hi2s);
988 }
989
990 /* I2S Overrun error interrupt occurred -------------------------------------*/
991 if (((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) {
992 /* Disable RXNE and ERR interrupt */
993 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
994
995 /* Set the I2S State ready */
996 hi2s->State = HAL_I2S_STATE_READY;
997
998 /* Set the error code and execute error callback*/
999 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
1000 HAL_I2S_ErrorCallback(hi2s);
1001 }
1002 } else if (hi2s->State == HAL_I2S_STATE_BUSY_TX) {
1003 /* I2S in mode Transmitter ---------------------------------------------------*/
1004 if (((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET)) {
1005 I2S_Transmit_IT(hi2s);
1006 }
1007
1008 /* I2S Underrun error interrupt occurred ------------------------------------*/
1009 if (((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) {
1010 /* Disable TXE and ERR interrupt */
1011 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1012
1013 /* Set the I2S State ready */
1014 hi2s->State = HAL_I2S_STATE_READY;
1015
1016 /* Set the error code and execute error callback*/
1017 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
1018 HAL_I2S_ErrorCallback(hi2s);
1019 }
1020 }
1021 }
1022
1023 /**
1024 * @}
1025 */
1026
1027 /**
1028 * @}
1029 */
1030
1031 /** @addtogroup I2S_Private_Functions I2S Private Functions
1032 * @{
1033 */
1034 /**
1035 * @brief This function handles I2S Communication Timeout.
1036 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1037 * the configuration information for I2S module
1038 * @param Flag: Flag checked
1039 * @param State: Value of the flag expected
1040 * @param Timeout: Duration of the timeout
1041 * @retval HAL status
1042 */
I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,uint32_t State,uint32_t Timeout)1043 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag,
1044 uint32_t State, uint32_t Timeout)
1045 {
1046 uint32_t tickstart = 0;
1047
1048 /* Get tick */
1049 tickstart = HAL_GetTick();
1050
1051 /* Wait until flag is set */
1052 if (State == RESET) {
1053 while (__HAL_I2S_GET_FLAG(hi2s, Flag) == RESET) {
1054 if (Timeout != HAL_MAX_DELAY) {
1055 if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1056 /* Set the I2S State ready */
1057 hi2s->State= HAL_I2S_STATE_READY;
1058
1059 /* Process Unlocked */
1060 __HAL_UNLOCK(hi2s);
1061
1062 return HAL_TIMEOUT;
1063 }
1064 }
1065 }
1066 } else {
1067 while (__HAL_I2S_GET_FLAG(hi2s, Flag) != RESET) {
1068 if (Timeout != HAL_MAX_DELAY) {
1069 if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1070 /* Set the I2S State ready */
1071 hi2s->State= HAL_I2S_STATE_READY;
1072
1073 /* Process Unlocked */
1074 __HAL_UNLOCK(hi2s);
1075
1076 return HAL_TIMEOUT;
1077 }
1078 }
1079 }
1080 }
1081 return HAL_OK;
1082 }
1083 /**
1084 * @}
1085 */
1086
1087 /** @addtogroup I2S_Exported_Functions I2S Exported Functions
1088 * @{
1089 */
1090
1091 /** @addtogroup I2S_Exported_Functions_Group2 Input and Output operation functions
1092 * @{
1093 */
1094 /**
1095 * @brief Tx Transfer Half completed callbacks
1096 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1097 * the configuration information for I2S module
1098 * @retval None
1099 */
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1100 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1101 {
1102 /* NOTE : This function Should not be modified, when the callback is needed,
1103 the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1104 */
1105 }
1106
1107 /**
1108 * @brief Tx Transfer completed callbacks
1109 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1110 * the configuration information for I2S module
1111 * @retval None
1112 */
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef * hi2s)1113 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
1114 {
1115 /* NOTE : This function Should not be modified, when the callback is needed,
1116 the HAL_I2S_TxCpltCallback could be implemented in the user file
1117 */
1118 }
1119
1120 /**
1121 * @brief Rx Transfer half completed callbacks
1122 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1123 * the configuration information for I2S module
1124 * @retval None
1125 */
HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1126 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1127 {
1128 /* NOTE : This function Should not be modified, when the callback is needed,
1129 the HAL_I2S_RxCpltCallback could be implemented in the user file
1130 */
1131 }
1132
1133 /**
1134 * @brief Rx Transfer completed callbacks
1135 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1136 * the configuration information for I2S module
1137 * @retval None
1138 */
HAL_I2S_RxCpltCallback(I2S_HandleTypeDef * hi2s)1139 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1140 {
1141 /* NOTE : This function Should not be modified, when the callback is needed,
1142 the HAL_I2S_RxCpltCallback could be implemented in the user file
1143 */
1144 }
1145
1146 /**
1147 * @brief I2S error callbacks
1148 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1149 * the configuration information for I2S module
1150 * @retval None
1151 */
HAL_I2S_ErrorCallback(I2S_HandleTypeDef * hi2s)1152 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
1153 {
1154 /* NOTE : This function Should not be modified, when the callback is needed,
1155 the HAL_I2S_ErrorCallback could be implemented in the user file
1156 */
1157 }
1158
1159 /**
1160 * @}
1161 */
1162
1163 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1164 * @brief Peripheral State functions
1165 *
1166 @verbatim
1167 ===============================================================================
1168 ##### Peripheral State and Errors functions #####
1169 ===============================================================================
1170 [..]
1171 This subsection permits to get in run-time the status of the peripheral
1172 and the data flow.
1173
1174 @endverbatim
1175 * @{
1176 */
1177
1178 /**
1179 * @brief Return the I2S state
1180 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1181 * the configuration information for I2S module
1182 * @retval HAL state
1183 */
HAL_I2S_GetState(I2S_HandleTypeDef * hi2s)1184 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1185 {
1186 return hi2s->State;
1187 }
1188
1189 /**
1190 * @brief Return the I2S error code
1191 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1192 * the configuration information for I2S module
1193 * @retval I2S Error Code
1194 */
HAL_I2S_GetError(I2S_HandleTypeDef * hi2s)1195 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1196 {
1197 return hi2s->ErrorCode;
1198 }
1199 /**
1200 * @}
1201 */
1202
1203 /**
1204 * @}
1205 */
1206
1207 /**
1208 * @brief Get I2S Input Clock based on I2S source clock selection
1209 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1210 * the configuration information for I2S module.
1211 * @retval I2S Clock Input
1212 */
I2S_GetClockFreq(I2S_HandleTypeDef * hi2s)1213 static uint32_t I2S_GetClockFreq(I2S_HandleTypeDef *hi2s)
1214 {
1215 uint32_t tmpreg = 0;
1216 /* This variable used to store the VCO Input (value in Hz) */
1217 uint32_t vcoinput = 0;
1218 /* This variable used to store the I2S_CK_x (value in Hz) */
1219 uint32_t i2sclocksource = 0;
1220
1221 /* Configure I2S Clock based on I2S source clock selection */
1222
1223 /* I2S_CLK_x : I2S Block Clock configuration for different clock sources selected */
1224 switch (hi2s->Init.ClockSource) {
1225 case I2S_CLOCK_SYSCLK : {
1226 /* Configure the PLLI2S division factor */
1227 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
1228 if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) {
1229 /* In Case the PLL Source is HSI (Internal Clock) */
1230 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1231 } else {
1232 /* In Case the PLL Source is HSE (External Clock) */
1233 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
1234 }
1235
1236 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1237 /* I2S_CLK(first level) = PLLI2S_VCO Output/PLLI2SR */
1238 tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28;
1239 i2sclocksource = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg);
1240
1241 break;
1242 }
1243 case I2S_CLOCK_EXTERNAL : {
1244 i2sclocksource = EXTERNAL_CLOCK_VALUE;
1245 break;
1246 }
1247 default : {
1248 break;
1249 }
1250 }
1251
1252 /* the return result is the value of I2S clock */
1253 return i2sclocksource;
1254 }
1255
1256 /** @addtogroup I2S_Private_Functions I2S Private Functions
1257 * @{
1258 */
1259 /**
1260 * @brief DMA I2S transmit process complete callback
1261 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1262 * the configuration information for the specified DMA module.
1263 * @retval None
1264 */
I2S_DMATxCplt(DMA_HandleTypeDef * hdma)1265 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1266 {
1267 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1268
1269 if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) {
1270 hi2s->TxXferCount = 0;
1271
1272 /* Disable Tx DMA Request */
1273 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
1274
1275 if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) {
1276 if (hi2s->RxXferCount == 0) {
1277 hi2s->State = HAL_I2S_STATE_READY;
1278 }
1279 } else {
1280 hi2s->State = HAL_I2S_STATE_READY;
1281 }
1282 }
1283 HAL_I2S_TxCpltCallback(hi2s);
1284 }
1285
1286 /**
1287 * @brief DMA I2S transmit process half complete callback
1288 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1289 * the configuration information for the specified DMA module.
1290 * @retval None
1291 */
I2S_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1292 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1293 {
1294 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1295
1296 HAL_I2S_TxHalfCpltCallback(hi2s);
1297 }
1298
1299 /**
1300 * @brief DMA I2S receive process complete callback
1301 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1302 * the configuration information for the specified DMA module.
1303 * @retval None
1304 */
I2S_DMARxCplt(DMA_HandleTypeDef * hdma)1305 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1306 {
1307 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1308
1309 if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) {
1310 /* Disable Rx DMA Request */
1311 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
1312
1313 hi2s->RxXferCount = 0;
1314 if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) {
1315 if (hi2s->TxXferCount == 0) {
1316 hi2s->State = HAL_I2S_STATE_READY;
1317 }
1318 } else {
1319 hi2s->State = HAL_I2S_STATE_READY;
1320 }
1321 }
1322 HAL_I2S_RxCpltCallback(hi2s);
1323 }
1324
1325 /**
1326 * @brief DMA I2S receive process half complete callback
1327 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1328 * the configuration information for the specified DMA module.
1329 * @retval None
1330 */
I2S_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1331 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1332 {
1333 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1334
1335 HAL_I2S_RxHalfCpltCallback(hi2s);
1336 }
1337
1338 /**
1339 * @brief DMA I2S communication error callback
1340 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1341 * the configuration information for the specified DMA module.
1342 * @retval None
1343 */
I2S_DMAError(DMA_HandleTypeDef * hdma)1344 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1345 {
1346 I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1347
1348 /* Disable Rx and Tx DMA Request */
1349 hi2s->Instance->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1350 hi2s->TxXferCount = 0;
1351 hi2s->RxXferCount = 0;
1352
1353 hi2s->State= HAL_I2S_STATE_READY;
1354
1355 /* Set the error code and execute error callback*/
1356 hi2s->ErrorCode |= HAL_I2S_ERROR_DMA;
1357 HAL_I2S_ErrorCallback(hi2s);
1358 }
1359
1360 /**
1361 * @brief Transmit an amount of data in non-blocking mode with Interrupt
1362 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
1363 * the configuration information for I2S module
1364 * @retval None
1365 */
I2S_Transmit_IT(I2S_HandleTypeDef * hi2s)1366 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
1367 {
1368 /* Transmit data */
1369 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
1370 hi2s->TxXferCount--;
1371
1372 if (hi2s->TxXferCount == 0) {
1373 /* Disable TXE and ERR interrupt */
1374 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1375
1376 hi2s->State = HAL_I2S_STATE_READY;
1377 HAL_I2S_TxCpltCallback(hi2s);
1378 }
1379 }
1380
1381 /**
1382 * @brief Receive an amount of data in non-blocking mode with Interrupt
1383 * @param hi2s: I2S handle
1384 * @retval None
1385 */
I2S_Receive_IT(I2S_HandleTypeDef * hi2s)1386 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
1387 {
1388 /* Receive data */
1389 (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
1390 hi2s->RxXferCount--;
1391
1392 if (hi2s->RxXferCount == 0) {
1393 /* Disable RXNE and ERR interrupt */
1394 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1395
1396 hi2s->State = HAL_I2S_STATE_READY;
1397 HAL_I2S_RxCpltCallback(hi2s);
1398 }
1399 }
1400 /**
1401 * @}
1402 */
1403
1404 #endif /* HAL_I2S_MODULE_ENABLED */
1405 /**
1406 * @}
1407 */
1408
1409 /**
1410 * @}
1411 */
1412
1413 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1414