2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_i2s.c
\r
4 * @author MCD Application Team
\r
6 * @date 24-March-2015
\r
7 * @brief I2S HAL module driver.
\r
8 * This file provides firmware functions to manage the following
\r
9 * functionalities of the Integrated Interchip Sound (I2S) peripheral:
\r
10 * + Initialization and de-initialization functions
\r
11 * + IO operation functions
\r
12 * + Peripheral State and Errors functions
\r
14 ===============================================================================
\r
15 ##### How to use this driver #####
\r
16 ===============================================================================
\r
18 The I2S HAL driver can be used as follows:
\r
20 (#) Declare a I2S_HandleTypeDef handle structure.
\r
21 (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
\r
22 (##) Enable the SPIx interface clock.
\r
23 (##) I2S pins configuration:
\r
24 (+++) Enable the clock for the I2S GPIOs.
\r
25 (+++) Configure these I2S pins as alternate function pull-up.
\r
26 (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
\r
27 and HAL_I2S_Receive_IT() APIs).
\r
28 (+++) Configure the I2Sx interrupt priority.
\r
29 (+++) Enable the NVIC I2S IRQ handle.
\r
30 (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
\r
31 and HAL_I2S_Receive_DMA() APIs:
\r
32 (+++) Declare a DMA handle structure for the Tx/Rx channel.
\r
33 (+++) Enable the DMAx interface clock.
\r
34 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
\r
35 (+++) Configure the DMA Tx/Rx Channel.
\r
36 (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
\r
37 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
\r
40 (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
\r
41 using HAL_I2S_Init() function.
\r
43 -@- The specific I2S interrupts (Transmission complete interrupt,
\r
44 RXNE interrupt and Error Interrupts) will be managed using the macros
\r
45 __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
\r
46 -@- Make sure that either:
\r
47 (+@) I2S clock is configured based on SYSCLK or
\r
48 (+@) External clock source is configured after setting correctly
\r
49 the define constant EXTERNAL_CLOCK_VALUE in the stm32f3xx_hal_conf.h file.
\r
51 (#) Three mode of operations are available within this driver :
\r
53 *** Polling mode IO operation ***
\r
54 =================================
\r
56 (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
\r
57 (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
\r
59 *** Interrupt mode IO operation ***
\r
60 ===================================
\r
62 (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
\r
63 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
\r
64 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
\r
65 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
\r
66 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
\r
67 (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
\r
68 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
\r
69 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
\r
70 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
\r
71 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
\r
72 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
\r
73 add his own code by customization of function pointer HAL_I2S_ErrorCallback
\r
75 *** DMA mode IO operation ***
\r
76 ==============================
\r
78 (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
\r
79 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
\r
80 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
\r
81 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
\r
82 add his own code by customization of function pointer HAL_I2S_TxCpltCallback
\r
83 (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
\r
84 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
\r
85 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
\r
86 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
\r
87 add his own code by customization of function pointer HAL_I2S_RxCpltCallback
\r
88 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
\r
89 add his own code by customization of function pointer HAL_I2S_ErrorCallback
\r
90 (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
\r
91 (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
\r
92 (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
\r
94 *** I2S HAL driver macros list ***
\r
95 =============================================
\r
97 Below the list of most used macros in I2S HAL driver.
\r
99 (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
\r
100 (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
\r
101 (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
\r
102 (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
\r
103 (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
\r
106 (@) You can refer to the I2S HAL driver header file for more useful macros
\r
109 ******************************************************************************
\r
112 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
114 * Redistribution and use in source and binary forms, with or without modification,
\r
115 * are permitted provided that the following conditions are met:
\r
116 * 1. Redistributions of source code must retain the above copyright notice,
\r
117 * this list of conditions and the following disclaimer.
\r
118 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
119 * this list of conditions and the following disclaimer in the documentation
\r
120 * and/or other materials provided with the distribution.
\r
121 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
122 * may be used to endorse or promote products derived from this software
\r
123 * without specific prior written permission.
\r
125 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
126 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
127 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
128 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
129 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
130 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
131 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
132 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
133 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
134 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
136 ******************************************************************************
\r
139 /* Includes ------------------------------------------------------------------*/
\r
140 #include "stm32f7xx_hal.h"
\r
142 /** @addtogroup STM32F3xx_HAL_Driver
\r
146 /** @defgroup I2S I2S HAL module driver
\r
147 * @brief I2S HAL module driver
\r
151 #ifdef HAL_I2S_MODULE_ENABLED
\r
153 /* Private typedef -----------------------------------------------------------*/
\r
154 /* Private define ------------------------------------------------------------*/
\r
155 /* Private macro -------------------------------------------------------------*/
\r
156 /* Private variables ---------------------------------------------------------*/
\r
157 /* Private function prototypes -----------------------------------------------*/
\r
158 /** @defgroup I2S_Private_Functions I2S Private Functions
\r
161 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
\r
162 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
\r
163 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
\r
164 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
\r
165 static void I2S_DMAError(DMA_HandleTypeDef *hdma);
\r
166 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
\r
167 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
\r
168 static uint32_t I2S_GetClockFreq(I2S_HandleTypeDef *hi2s);
\r
169 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State, uint32_t Timeout);
\r
174 /* Exported functions ---------------------------------------------------------*/
\r
176 /** @defgroup I2S_Exported_Functions I2S Exported Functions
\r
180 /** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions
\r
181 * @brief Initialization and Configuration functions
\r
184 ===============================================================================
\r
185 ##### Initialization and de-initialization functions #####
\r
186 ===============================================================================
\r
187 [..] This subsection provides a set of functions allowing to initialize and
\r
188 de-initialize the I2Sx peripheral in simplex mode:
\r
190 (+) User must Implement HAL_I2S_MspInit() function in which he configures
\r
191 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
\r
193 (+) Call the function HAL_I2S_Init() to configure the selected device with
\r
194 the selected configuration:
\r
199 (++) Audio frequency
\r
201 (++) Full duplex mode
\r
203 (+) Call the function HAL_I2S_DeInit() to restore the default configuration
\r
204 of the selected I2Sx peripheral.
\r
210 * @brief Initializes the I2S according to the specified parameters
\r
211 * in the I2S_InitTypeDef and create the associated handle.
\r
212 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
213 * the configuration information for I2S module
\r
214 * @retval HAL status
\r
216 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
\r
218 uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
\r
219 uint32_t tmp = 0, i2sclk = 0;
\r
221 /* Check the I2S handle allocation */
\r
227 /* Check the parameters */
\r
228 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
\r
229 assert_param(IS_I2S_MODE(hi2s->Init.Mode));
\r
230 assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
\r
231 assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
\r
232 assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
\r
233 assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
\r
234 assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
\r
235 assert_param(IS_I2S_CLOCKSOURCE(hi2s->Init.ClockSource));
\r
237 hi2s->State = HAL_I2S_STATE_BUSY;
\r
239 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
\r
240 HAL_I2S_MspInit(hi2s);
\r
242 /*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
\r
243 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
\r
244 hi2s->Instance->I2SCFGR &= ~(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
\r
245 SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
\r
246 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD);
\r
247 hi2s->Instance->I2SPR = 0x0002;
\r
249 /* Get the I2SCFGR register value */
\r
250 tmpreg = hi2s->Instance->I2SCFGR;
\r
252 /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
\r
253 if(hi2s->Init.AudioFreq == I2S_AUDIOFREQ_DEFAULT)
\r
255 i2sodd = (uint16_t)0;
\r
256 i2sdiv = (uint16_t)2;
\r
258 /* If the requested audio frequency is not the default, compute the prescaler */
\r
261 /* Check the frame length (For the Prescaler computing) *******************/
\r
262 if(hi2s->Init.DataFormat == I2S_DATAFORMAT_16B)
\r
264 /* Packet length is 16 bits */
\r
269 /* Packet length is 32 bits */
\r
273 /* Get I2S source Clock frequency ****************************************/
\r
275 /* If an external I2S clock has to be used, the specific define should be set
\r
276 in the project configuration or in the stm32f3xx_conf.h file */
\r
277 if(hi2s->Init.ClockSource == I2S_CLOCK_EXTERNAL)
\r
279 /* Set the I2S clock to the external clock value */
\r
280 i2sclk = EXTERNAL_CLOCK_VALUE;
\r
284 /* Get the I2S source clock value */
\r
285 i2sclk = I2S_GetClockFreq(hi2s);
\r
288 /* Compute the Real divider depending on the MCLK output state, with a floating point */
\r
289 if(hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
\r
291 /* MCLK output is enabled */
\r
292 tmp = (uint16_t)(((((i2sclk / 256) * 10) / hi2s->Init.AudioFreq)) + 5);
\r
296 /* MCLK output is disabled */
\r
297 tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / hi2s->Init.AudioFreq)) + 5);
\r
300 /* Remove the flatting point */
\r
303 /* Check the parity of the divider */
\r
304 i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
\r
306 /* Compute the i2sdiv prescaler */
\r
307 i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
\r
309 /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
\r
310 i2sodd = (uint16_t) (i2sodd << 8);
\r
313 /* Test if the divider is 1 or 0 or greater than 0xFF */
\r
314 if((i2sdiv < 2) || (i2sdiv > 0xFF))
\r
316 /* Set the default values */
\r
321 /* Write to SPIx I2SPR register the computed value */
\r
322 hi2s->Instance->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)hi2s->Init.MCLKOutput));
\r
324 /* Configure the I2S with the I2S_InitStruct values */
\r
325 tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(hi2s->Init.Mode | \
\r
326 (uint16_t)(hi2s->Init.Standard | (uint16_t)(hi2s->Init.DataFormat | \
\r
327 (uint16_t)hi2s->Init.CPOL))));
\r
329 /* Write to SPIx I2SCFGR */
\r
330 hi2s->Instance->I2SCFGR = tmpreg;
\r
332 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
\r
333 hi2s->State= HAL_I2S_STATE_READY;
\r
339 * @brief DeInitializes the I2S peripheral
\r
340 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
341 * the configuration information for I2S module
\r
342 * @retval HAL status
\r
344 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
\r
346 /* Check the I2S handle allocation */
\r
352 /* Check the parameters */
\r
353 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
\r
355 hi2s->State = HAL_I2S_STATE_BUSY;
\r
357 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
\r
358 HAL_I2S_MspDeInit(hi2s);
\r
360 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
\r
361 hi2s->State = HAL_I2S_STATE_RESET;
\r
364 __HAL_UNLOCK(hi2s);
\r
370 * @brief I2S MSP Init
\r
371 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
372 * the configuration information for I2S module
\r
375 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
\r
377 /* NOTE : This function Should not be modified, when the callback is needed,
\r
378 the HAL_I2S_MspInit could be implemented in the user file
\r
383 * @brief I2S MSP DeInit
\r
384 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
385 * the configuration information for I2S module
\r
388 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
\r
390 /* NOTE : This function Should not be modified, when the callback is needed,
\r
391 the HAL_I2S_MspDeInit could be implemented in the user file
\r
399 /** @defgroup I2S_Exported_Functions_Group2 Input and Output operation functions
\r
400 * @brief Data transfers functions
\r
403 ===============================================================================
\r
404 ##### IO operation functions #####
\r
405 ===============================================================================
\r
407 This subsection provides a set of functions allowing to manage the I2S data
\r
410 (#) There are two modes of transfer:
\r
411 (++) Blocking mode : The communication is performed in the polling mode.
\r
412 The status of all data processing is returned by the same function
\r
413 after finishing transfer.
\r
414 (++) No-Blocking mode : The communication is performed using Interrupts
\r
415 or DMA. These functions return the status of the transfer startup.
\r
416 The end of the data processing will be indicated through the
\r
417 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
\r
420 (#) Blocking mode functions are :
\r
421 (++) HAL_I2S_Transmit()
\r
422 (++) HAL_I2S_Receive()
\r
424 (#) No-Blocking mode functions with Interrupt are :
\r
425 (++) HAL_I2S_Transmit_IT()
\r
426 (++) HAL_I2S_Receive_IT()
\r
428 (#) No-Blocking mode functions with DMA are :
\r
429 (++) HAL_I2S_Transmit_DMA()
\r
430 (++) HAL_I2S_Receive_DMA()
\r
432 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
\r
433 (++) HAL_I2S_TxCpltCallback()
\r
434 (++) HAL_I2S_RxCpltCallback()
\r
435 (++) HAL_I2S_ErrorCallback()
\r
442 * @brief Transmit an amount of data in blocking mode
\r
443 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
444 * the configuration information for I2S module
\r
445 * @param pData: a 16-bit pointer to data buffer.
\r
446 * @param Size: number of data sample to be sent:
\r
447 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
\r
448 * configuration phase, the Size parameter means the number of 16-bit data length
\r
449 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
\r
450 * the Size parameter means the number of 16-bit data length.
\r
451 * @param Timeout: Timeout duration
\r
452 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
\r
453 * between Master and Slave(example: audio streaming).
\r
454 * @retval HAL status
\r
456 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
\r
458 if((pData == NULL ) || (Size == 0))
\r
463 if(hi2s->State == HAL_I2S_STATE_READY)
\r
465 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
\r
466 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
\r
468 hi2s->TxXferSize = (Size << 1);
\r
469 hi2s->TxXferCount = (Size << 1);
\r
473 hi2s->TxXferSize = Size;
\r
474 hi2s->TxXferCount = Size;
\r
477 /* Process Locked */
\r
480 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
\r
481 hi2s->State = HAL_I2S_STATE_BUSY_TX;
\r
483 /* Check if the I2S is already enabled */
\r
484 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
\r
486 /* Enable I2S peripheral */
\r
487 __HAL_I2S_ENABLE(hi2s);
\r
490 while(hi2s->TxXferCount > 0)
\r
492 hi2s->Instance->DR = (*pData++);
\r
493 hi2s->TxXferCount--;
\r
494 /* Wait until TXE flag is set */
\r
495 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
\r
497 /* Set the error code and execute error callback*/
\r
498 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
\r
499 HAL_I2S_ErrorCallback(hi2s);
\r
500 return HAL_TIMEOUT;
\r
503 /* Check if an underrun occurs */
\r
504 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
\r
506 /* Set the I2S State ready */
\r
507 hi2s->State = HAL_I2S_STATE_READY;
\r
509 /* Process Unlocked */
\r
510 __HAL_UNLOCK(hi2s);
\r
512 /* Set the error code and execute error callback*/
\r
513 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
\r
514 HAL_I2S_ErrorCallback(hi2s);
\r
520 /* Wait until Busy flag is reset */
\r
521 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK)
\r
523 /* Set the error code and execute error callback*/
\r
524 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
\r
525 HAL_I2S_ErrorCallback(hi2s);
\r
526 return HAL_TIMEOUT;
\r
529 hi2s->State = HAL_I2S_STATE_READY;
\r
531 /* Process Unlocked */
\r
532 __HAL_UNLOCK(hi2s);
\r
543 * @brief Receive an amount of data in blocking mode
\r
544 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
545 * the configuration information for I2S module
\r
546 * @param pData: a 16-bit pointer to data buffer.
\r
547 * @param Size: number of data sample to be sent:
\r
548 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
\r
549 * configuration phase, the Size parameter means the number of 16-bit data length
\r
550 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
\r
551 * the Size parameter means the number of 16-bit data length.
\r
552 * @param Timeout: Timeout duration
\r
553 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
\r
554 * between Master and Slave(example: audio streaming).
\r
555 * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
\r
556 * in continuous way and as the I2S is not disabled at the end of the I2S transaction.
\r
557 * @retval HAL status
\r
559 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
\r
561 if((pData == NULL ) || (Size == 0))
\r
566 if(hi2s->State == HAL_I2S_STATE_READY)
\r
568 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
\r
569 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
\r
571 hi2s->RxXferSize = (Size << 1);
\r
572 hi2s->RxXferCount = (Size << 1);
\r
576 hi2s->RxXferSize = Size;
\r
577 hi2s->RxXferCount = Size;
\r
579 /* Process Locked */
\r
582 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
\r
583 hi2s->State = HAL_I2S_STATE_BUSY_RX;
\r
585 /* Check if the I2S is already enabled */
\r
586 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
\r
588 /* Enable I2S peripheral */
\r
589 __HAL_I2S_ENABLE(hi2s);
\r
592 /* Check if Master Receiver mode is selected */
\r
593 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
\r
595 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
\r
596 access to the SPI_SR register. */
\r
597 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
\r
601 while(hi2s->RxXferCount > 0)
\r
603 /* Wait until RXNE flag is set */
\r
604 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
\r
606 /* Set the error code and execute error callback*/
\r
607 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
\r
608 HAL_I2S_ErrorCallback(hi2s);
\r
609 return HAL_TIMEOUT;
\r
612 /* Check if an overrun occurs */
\r
613 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
\r
615 /* Set the I2S State ready */
\r
616 hi2s->State = HAL_I2S_STATE_READY;
\r
618 /* Process Unlocked */
\r
619 __HAL_UNLOCK(hi2s);
\r
621 /* Set the error code and execute error callback*/
\r
622 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
\r
623 HAL_I2S_ErrorCallback(hi2s);
\r
628 (*pData++) = hi2s->Instance->DR;
\r
629 hi2s->RxXferCount--;
\r
632 hi2s->State = HAL_I2S_STATE_READY;
\r
634 /* Process Unlocked */
\r
635 __HAL_UNLOCK(hi2s);
\r
646 * @brief Transmit an amount of data in non-blocking mode with Interrupt
\r
647 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
648 * the configuration information for I2S module
\r
649 * @param pData: a 16-bit pointer to data buffer.
\r
650 * @param Size: number of data sample to be sent:
\r
651 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
\r
652 * configuration phase, the Size parameter means the number of 16-bit data length
\r
653 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
\r
654 * the Size parameter means the number of 16-bit data length.
\r
655 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
\r
656 * between Master and Slave(example: audio streaming).
\r
657 * @retval HAL status
\r
659 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
\r
661 if(hi2s->State == HAL_I2S_STATE_READY)
\r
663 if((pData == NULL) || (Size == 0))
\r
668 hi2s->pTxBuffPtr = pData;
\r
669 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
\r
670 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
\r
672 hi2s->TxXferSize = (Size << 1);
\r
673 hi2s->TxXferCount = (Size << 1);
\r
677 hi2s->TxXferSize = Size;
\r
678 hi2s->TxXferCount = Size;
\r
681 /* Process Locked */
\r
684 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
\r
685 hi2s->State = HAL_I2S_STATE_BUSY_TX;
\r
687 /* Enable TXE and ERR interrupt */
\r
688 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
\r
690 /* Check if the I2S is already enabled */
\r
691 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
\r
693 /* Enable I2S peripheral */
\r
694 __HAL_I2S_ENABLE(hi2s);
\r
697 /* Process Unlocked */
\r
698 __HAL_UNLOCK(hi2s);
\r
709 * @brief Receive an amount of data in non-blocking mode with Interrupt
\r
710 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
711 * the configuration information for I2S module
\r
712 * @param pData: a 16-bit pointer to the Receive data buffer.
\r
713 * @param Size: number of data sample to be sent:
\r
714 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
\r
715 * configuration phase, the Size parameter means the number of 16-bit data length
\r
716 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
\r
717 * the Size parameter means the number of 16-bit data length.
\r
718 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
\r
719 * between Master and Slave(example: audio streaming).
\r
720 * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronisation
\r
721 * between Master and Slave otherwise the I2S interrupt should be optimized.
\r
722 * @retval HAL status
\r
724 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
\r
726 if(hi2s->State == HAL_I2S_STATE_READY)
\r
728 if((pData == NULL) || (Size == 0))
\r
733 hi2s->pRxBuffPtr = pData;
\r
734 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
\r
735 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
\r
737 hi2s->RxXferSize = (Size << 1);
\r
738 hi2s->RxXferCount = (Size << 1);
\r
742 hi2s->RxXferSize = Size;
\r
743 hi2s->RxXferCount = Size;
\r
745 /* Process Locked */
\r
748 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
\r
749 hi2s->State = HAL_I2S_STATE_BUSY_RX;
\r
751 /* Enable TXE and ERR interrupt */
\r
752 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
\r
754 /* Check if the I2S is already enabled */
\r
755 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
\r
757 /* Enable I2S peripheral */
\r
758 __HAL_I2S_ENABLE(hi2s);
\r
761 /* Process Unlocked */
\r
762 __HAL_UNLOCK(hi2s);
\r
773 * @brief Transmit an amount of data in non-blocking mode with DMA
\r
774 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
775 * the configuration information for I2S module
\r
776 * @param pData: a 16-bit pointer to the Transmit data buffer.
\r
777 * @param Size: number of data sample to be sent:
\r
778 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
\r
779 * configuration phase, the Size parameter means the number of 16-bit data length
\r
780 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
\r
781 * the Size parameter means the number of 16-bit data length.
\r
782 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
\r
783 * between Master and Slave(example: audio streaming).
\r
784 * @retval HAL status
\r
786 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
\r
790 if((pData == NULL) || (Size == 0))
\r
795 if(hi2s->State == HAL_I2S_STATE_READY)
\r
797 hi2s->pTxBuffPtr = pData;
\r
798 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
\r
799 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
\r
801 hi2s->TxXferSize = (Size << 1);
\r
802 hi2s->TxXferCount = (Size << 1);
\r
806 hi2s->TxXferSize = Size;
\r
807 hi2s->TxXferCount = Size;
\r
810 /* Process Locked */
\r
813 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
\r
814 hi2s->State = HAL_I2S_STATE_BUSY_TX;
\r
816 /* Set the I2S Tx DMA Half transfer complete callback */
\r
817 hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
\r
819 /* Set the I2S TxDMA transfer complete callback */
\r
820 hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
\r
822 /* Set the DMA error callback */
\r
823 hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
\r
825 /* Enable the Tx DMA Channel */
\r
826 tmp = (uint32_t*)&pData;
\r
827 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
\r
829 /* Check if the I2S is already enabled */
\r
830 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
\r
832 /* Enable I2S peripheral */
\r
833 __HAL_I2S_ENABLE(hi2s);
\r
836 /* Enable Tx DMA Request */
\r
837 hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN;
\r
839 /* Process Unlocked */
\r
840 __HAL_UNLOCK(hi2s);
\r
851 * @brief Receive an amount of data in non-blocking mode with DMA
\r
852 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
853 * the configuration information for I2S module
\r
854 * @param pData: a 16-bit pointer to the Receive data buffer.
\r
855 * @param Size: number of data sample to be sent:
\r
856 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
\r
857 * configuration phase, the Size parameter means the number of 16-bit data length
\r
858 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
\r
859 * the Size parameter means the number of 16-bit data length.
\r
860 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
\r
861 * between Master and Slave(example: audio streaming).
\r
862 * @retval HAL status
\r
864 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
\r
868 if((pData == NULL) || (Size == 0))
\r
873 if(hi2s->State == HAL_I2S_STATE_READY)
\r
875 hi2s->pRxBuffPtr = pData;
\r
876 if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
\r
877 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
\r
879 hi2s->RxXferSize = (Size << 1);
\r
880 hi2s->RxXferCount = (Size << 1);
\r
884 hi2s->RxXferSize = Size;
\r
885 hi2s->RxXferCount = Size;
\r
887 /* Process Locked */
\r
890 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
\r
891 hi2s->State = HAL_I2S_STATE_BUSY_RX;
\r
893 /* Set the I2S Rx DMA Half transfer complete callback */
\r
894 hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
\r
896 /* Set the I2S Rx DMA transfer complete callback */
\r
897 hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
\r
899 /* Set the DMA error callback */
\r
900 hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
\r
902 /* Check if Master Receiver mode is selected */
\r
903 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
\r
905 /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
\r
906 access to the SPI_SR register. */
\r
907 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
\r
910 /* Enable the Rx DMA Channel */
\r
911 tmp = (uint32_t*)&pData;
\r
912 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
\r
914 /* Check if the I2S is already enabled */
\r
915 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
\r
917 /* Enable I2S peripheral */
\r
918 __HAL_I2S_ENABLE(hi2s);
\r
921 /* Enable Rx DMA Request */
\r
922 hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;
\r
924 /* Process Unlocked */
\r
925 __HAL_UNLOCK(hi2s);
\r
936 * @brief Pauses the audio stream playing from the Media.
\r
937 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
938 * the configuration information for I2S module
\r
939 * @retval HAL status
\r
941 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
\r
943 /* Process Locked */
\r
946 if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
\r
948 /* Disable the I2S DMA Tx request */
\r
949 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
\r
951 else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
\r
953 /* Disable the I2S DMA Rx request */
\r
954 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
\r
956 else if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
\r
958 if((hi2s->Init.Mode == I2S_MODE_SLAVE_TX)||(hi2s->Init.Mode == I2S_MODE_MASTER_TX))
\r
960 /* Disable the I2S DMA Tx request */
\r
961 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
\r
965 /* Disable the I2S DMA Rx request */
\r
966 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
\r
970 /* Process Unlocked */
\r
971 __HAL_UNLOCK(hi2s);
\r
977 * @brief Resumes the audio stream playing from the Media.
\r
978 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
979 * the configuration information for I2S module
\r
980 * @retval HAL status
\r
982 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
\r
984 /* Process Locked */
\r
987 if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
\r
989 /* Enable the I2S DMA Tx request */
\r
990 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
\r
992 else if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
\r
994 /* Enable the I2S DMA Rx request */
\r
995 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
\r
998 /* If the I2S peripheral is still not enabled, enable it */
\r
999 if(HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
\r
1001 /* Enable I2S peripheral */
\r
1002 __HAL_I2S_ENABLE(hi2s);
\r
1005 /* Process Unlocked */
\r
1006 __HAL_UNLOCK(hi2s);
\r
1012 * @brief Stops the audio stream playing from the Media.
\r
1013 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1014 * the configuration information for I2S module
\r
1015 * @retval HAL status
\r
1017 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
\r
1019 /* Process Locked */
\r
1022 /* Disable the I2S Tx/Rx DMA requests */
\r
1023 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
\r
1024 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
\r
1026 /* Abort the I2S DMA Channel tx */
\r
1027 if(hi2s->hdmatx != NULL)
\r
1029 /* Disable the I2S DMA channel */
\r
1030 __HAL_DMA_DISABLE(hi2s->hdmatx);
\r
1031 HAL_DMA_Abort(hi2s->hdmatx);
\r
1033 /* Abort the I2S DMA Channel rx */
\r
1034 if(hi2s->hdmarx != NULL)
\r
1036 /* Disable the I2S DMA channel */
\r
1037 __HAL_DMA_DISABLE(hi2s->hdmarx);
\r
1038 HAL_DMA_Abort(hi2s->hdmarx);
\r
1041 /* Disable I2S peripheral */
\r
1042 __HAL_I2S_DISABLE(hi2s);
\r
1044 hi2s->State = HAL_I2S_STATE_READY;
\r
1046 /* Process Unlocked */
\r
1047 __HAL_UNLOCK(hi2s);
\r
1053 * @brief This function handles I2S interrupt request.
\r
1054 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1055 * the configuration information for I2S module
\r
1056 * @retval HAL status
\r
1058 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
\r
1060 __IO uint32_t i2ssr = hi2s->Instance->SR;
\r
1062 if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
\r
1064 /* I2S in mode Receiver ----------------------------------------------------*/
\r
1065 if(((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET))
\r
1067 I2S_Receive_IT(hi2s);
\r
1070 /* I2S Overrun error interrupt occurred -------------------------------------*/
\r
1071 if(((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
\r
1073 /* Disable RXNE and ERR interrupt */
\r
1074 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
\r
1076 /* Set the I2S State ready */
\r
1077 hi2s->State = HAL_I2S_STATE_READY;
\r
1079 /* Set the error code and execute error callback*/
\r
1080 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
\r
1081 HAL_I2S_ErrorCallback(hi2s);
\r
1084 else if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
\r
1086 /* I2S in mode Transmitter ---------------------------------------------------*/
\r
1087 if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET))
\r
1089 I2S_Transmit_IT(hi2s);
\r
1092 /* I2S Underrun error interrupt occurred ------------------------------------*/
\r
1093 if(((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
\r
1095 /* Disable TXE and ERR interrupt */
\r
1096 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
\r
1098 /* Set the I2S State ready */
\r
1099 hi2s->State = HAL_I2S_STATE_READY;
\r
1101 /* Set the error code and execute error callback*/
\r
1102 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
\r
1103 HAL_I2S_ErrorCallback(hi2s);
\r
1116 /** @addtogroup I2S_Private_Functions I2S Private Functions
\r
1120 * @brief This function handles I2S Communication Timeout.
\r
1121 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1122 * the configuration information for I2S module
\r
1123 * @param Flag: Flag checked
\r
1124 * @param State: Value of the flag expected
\r
1125 * @param Timeout: Duration of the timeout
\r
1126 * @retval HAL status
\r
1128 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag,
\r
1129 uint32_t State, uint32_t Timeout)
\r
1131 uint32_t tickstart = 0;
\r
1134 tickstart = HAL_GetTick();
\r
1136 /* Wait until flag is set */
\r
1137 if(State == RESET)
\r
1139 while(__HAL_I2S_GET_FLAG(hi2s, Flag) == RESET)
\r
1141 if(Timeout != HAL_MAX_DELAY)
\r
1143 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1145 /* Set the I2S State ready */
\r
1146 hi2s->State= HAL_I2S_STATE_READY;
\r
1148 /* Process Unlocked */
\r
1149 __HAL_UNLOCK(hi2s);
\r
1151 return HAL_TIMEOUT;
\r
1158 while(__HAL_I2S_GET_FLAG(hi2s, Flag) != RESET)
\r
1160 if(Timeout != HAL_MAX_DELAY)
\r
1162 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
1164 /* Set the I2S State ready */
\r
1165 hi2s->State= HAL_I2S_STATE_READY;
\r
1167 /* Process Unlocked */
\r
1168 __HAL_UNLOCK(hi2s);
\r
1170 return HAL_TIMEOUT;
\r
1181 /** @addtogroup I2S_Exported_Functions I2S Exported Functions
\r
1185 /** @addtogroup I2S_Exported_Functions_Group2 Input and Output operation functions
\r
1189 * @brief Tx Transfer Half completed callbacks
\r
1190 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1191 * the configuration information for I2S module
\r
1194 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
\r
1196 /* NOTE : This function Should not be modified, when the callback is needed,
\r
1197 the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
\r
1202 * @brief Tx Transfer completed callbacks
\r
1203 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1204 * the configuration information for I2S module
\r
1207 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
\r
1209 /* NOTE : This function Should not be modified, when the callback is needed,
\r
1210 the HAL_I2S_TxCpltCallback could be implemented in the user file
\r
1215 * @brief Rx Transfer half completed callbacks
\r
1216 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1217 * the configuration information for I2S module
\r
1220 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
\r
1222 /* NOTE : This function Should not be modified, when the callback is needed,
\r
1223 the HAL_I2S_RxCpltCallback could be implemented in the user file
\r
1228 * @brief Rx Transfer completed callbacks
\r
1229 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1230 * the configuration information for I2S module
\r
1233 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
\r
1235 /* NOTE : This function Should not be modified, when the callback is needed,
\r
1236 the HAL_I2S_RxCpltCallback could be implemented in the user file
\r
1241 * @brief I2S error callbacks
\r
1242 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1243 * the configuration information for I2S module
\r
1246 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
\r
1248 /* NOTE : This function Should not be modified, when the callback is needed,
\r
1249 the HAL_I2S_ErrorCallback could be implemented in the user file
\r
1257 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
\r
1258 * @brief Peripheral State functions
\r
1261 ===============================================================================
\r
1262 ##### Peripheral State and Errors functions #####
\r
1263 ===============================================================================
\r
1265 This subsection permits to get in run-time the status of the peripheral
\r
1266 and the data flow.
\r
1273 * @brief Return the I2S state
\r
1274 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1275 * the configuration information for I2S module
\r
1276 * @retval HAL state
\r
1278 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
\r
1280 return hi2s->State;
\r
1284 * @brief Return the I2S error code
\r
1285 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1286 * the configuration information for I2S module
\r
1287 * @retval I2S Error Code
\r
1289 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
\r
1291 return hi2s->ErrorCode;
\r
1302 * @brief Get I2S Input Clock based on I2S source clock selection
\r
1303 * @param hsai: pointer to a I2S_HandleTypeDef structure that contains
\r
1304 * the configuration information for I2S module.
\r
1305 * @retval I2S Clock Input
\r
1307 static uint32_t I2S_GetClockFreq(I2S_HandleTypeDef *hi2s)
\r
1309 uint32_t tmpreg = 0;
\r
1310 /* This variable used to store the VCO Input (value in Hz) */
\r
1311 uint32_t vcoinput = 0;
\r
1312 /* This variable used to store the I2S_CK_x (value in Hz) */
\r
1313 uint32_t i2sclocksource = 0;
\r
1315 /* Configure I2S Clock based on I2S source clock selection */
\r
1317 /* I2S_CLK_x : I2S Block Clock configuration for different clock sources selected */
\r
1318 switch(hi2s->Init.ClockSource)
\r
1320 case I2S_CLOCK_SYSCLK :
\r
1322 /* Configure the PLLI2S division factor */
\r
1323 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
\r
1324 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
\r
1326 /* In Case the PLL Source is HSI (Internal Clock) */
\r
1327 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
\r
1331 /* In Case the PLL Source is HSE (External Clock) */
\r
1332 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
\r
1335 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
\r
1336 /* I2S_CLK(first level) = PLLI2S_VCO Output/PLLI2SR */
\r
1337 tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28;
\r
1338 i2sclocksource = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg);
\r
1342 case I2S_CLOCK_EXTERNAL :
\r
1344 i2sclocksource = EXTERNAL_CLOCK_VALUE;
\r
1353 /* the return result is the value of I2S clock */
\r
1354 return i2sclocksource;
\r
1357 /** @addtogroup I2S_Private_Functions I2S Private Functions
\r
1361 * @brief DMA I2S transmit process complete callback
\r
1362 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
1363 * the configuration information for the specified DMA module.
\r
1366 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
\r
1368 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
\r
1370 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
\r
1372 hi2s->TxXferCount = 0;
\r
1374 /* Disable Tx DMA Request */
\r
1375 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
\r
1377 if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
\r
1379 if(hi2s->RxXferCount == 0)
\r
1381 hi2s->State = HAL_I2S_STATE_READY;
\r
1386 hi2s->State = HAL_I2S_STATE_READY;
\r
1389 HAL_I2S_TxCpltCallback(hi2s);
\r
1393 * @brief DMA I2S transmit process half complete callback
\r
1394 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
1395 * the configuration information for the specified DMA module.
\r
1398 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
\r
1400 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
\r
1402 HAL_I2S_TxHalfCpltCallback(hi2s);
\r
1406 * @brief DMA I2S receive process complete callback
\r
1407 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
1408 * the configuration information for the specified DMA module.
\r
1411 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
\r
1413 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
\r
1415 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
\r
1417 /* Disable Rx DMA Request */
\r
1418 hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
\r
1420 hi2s->RxXferCount = 0;
\r
1421 if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
\r
1423 if(hi2s->TxXferCount == 0)
\r
1425 hi2s->State = HAL_I2S_STATE_READY;
\r
1430 hi2s->State = HAL_I2S_STATE_READY;
\r
1433 HAL_I2S_RxCpltCallback(hi2s);
\r
1437 * @brief DMA I2S receive process half complete callback
\r
1438 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
1439 * the configuration information for the specified DMA module.
\r
1442 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
\r
1444 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
\r
1446 HAL_I2S_RxHalfCpltCallback(hi2s);
\r
1450 * @brief DMA I2S communication error callback
\r
1451 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
\r
1452 * the configuration information for the specified DMA module.
\r
1455 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
\r
1457 I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
\r
1459 /* Disable Rx and Tx DMA Request */
\r
1460 hi2s->Instance->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
\r
1461 hi2s->TxXferCount = 0;
\r
1462 hi2s->RxXferCount = 0;
\r
1464 hi2s->State= HAL_I2S_STATE_READY;
\r
1466 /* Set the error code and execute error callback*/
\r
1467 hi2s->ErrorCode |= HAL_I2S_ERROR_DMA;
\r
1468 HAL_I2S_ErrorCallback(hi2s);
\r
1472 * @brief Transmit an amount of data in non-blocking mode with Interrupt
\r
1473 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
\r
1474 * the configuration information for I2S module
\r
1477 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
\r
1479 /* Transmit data */
\r
1480 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
\r
1481 hi2s->TxXferCount--;
\r
1483 if(hi2s->TxXferCount == 0)
\r
1485 /* Disable TXE and ERR interrupt */
\r
1486 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
\r
1488 hi2s->State = HAL_I2S_STATE_READY;
\r
1489 HAL_I2S_TxCpltCallback(hi2s);
\r
1494 * @brief Receive an amount of data in non-blocking mode with Interrupt
\r
1495 * @param hi2s: I2S handle
\r
1498 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
\r
1500 /* Receive data */
\r
1501 (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
\r
1502 hi2s->RxXferCount--;
\r
1504 if(hi2s->RxXferCount == 0)
\r
1506 /* Disable RXNE and ERR interrupt */
\r
1507 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
\r
1509 hi2s->State = HAL_I2S_STATE_READY;
\r
1510 HAL_I2S_RxCpltCallback(hi2s);
\r
1517 #endif /* HAL_I2S_MODULE_ENABLED */
\r
1526 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r