STM32F479xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_i2s.c 00004 * @author MCD Application Team 00005 * @brief I2S HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Integrated Interchip Sound (I2S) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral State and Errors functions 00011 @verbatim 00012 =============================================================================== 00013 ##### How to use this driver ##### 00014 =============================================================================== 00015 [..] 00016 The I2S HAL driver can be used as follow: 00017 00018 (#) Declare a I2S_HandleTypeDef handle structure. 00019 (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API: 00020 (##) Enable the SPIx interface clock. 00021 (##) I2S pins configuration: 00022 (+++) Enable the clock for the I2S GPIOs. 00023 (+++) Configure these I2S pins as alternate function pull-up. 00024 (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT() 00025 and HAL_I2S_Receive_IT() APIs). 00026 (+++) Configure the I2Sx interrupt priority. 00027 (+++) Enable the NVIC I2S IRQ handle. 00028 (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA() 00029 and HAL_I2S_Receive_DMA() APIs: 00030 (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel. 00031 (+++) Enable the DMAx interface clock. 00032 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. 00033 (+++) Configure the DMA Tx/Rx Stream/Channel. 00034 (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle. 00035 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the 00036 DMA Tx/Rx Stream/Channel. 00037 00038 (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity 00039 using HAL_I2S_Init() function. 00040 00041 -@- The specific I2S interrupts (Transmission complete interrupt, 00042 RXNE interrupt and Error Interrupts) will be managed using the macros 00043 __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process. 00044 -@- Make sure that either: 00045 (+@) I2S PLL clock is configured or 00046 (+@) External clock source is configured after setting correctly 00047 the define constant EXTERNAL_CLOCK_VALUE in the stm32f4xx_hal_conf.h file. 00048 00049 (#) Three mode of operations are available within this driver : 00050 00051 *** Polling mode IO operation *** 00052 ================================= 00053 [..] 00054 (+) Send an amount of data in blocking mode using HAL_I2S_Transmit() 00055 (+) Receive an amount of data in blocking mode using HAL_I2S_Receive() 00056 00057 *** Interrupt mode IO operation *** 00058 =================================== 00059 [..] 00060 (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT() 00061 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can 00062 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback 00063 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can 00064 add his own code by customization of function pointer HAL_I2S_TxCpltCallback 00065 (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT() 00066 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can 00067 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback 00068 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can 00069 add his own code by customization of function pointer HAL_I2S_RxCpltCallback 00070 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can 00071 add his own code by customization of function pointer HAL_I2S_ErrorCallback 00072 00073 *** DMA mode IO operation *** 00074 ============================== 00075 [..] 00076 (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA() 00077 (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can 00078 add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback 00079 (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can 00080 add his own code by customization of function pointer HAL_I2S_TxCpltCallback 00081 (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA() 00082 (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can 00083 add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback 00084 (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can 00085 add his own code by customization of function pointer HAL_I2S_RxCpltCallback 00086 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can 00087 add his own code by customization of function pointer HAL_I2S_ErrorCallback 00088 (+) Pause the DMA Transfer using HAL_I2S_DMAPause() 00089 (+) Resume the DMA Transfer using HAL_I2S_DMAResume() 00090 (+) Stop the DMA Transfer using HAL_I2S_DMAStop() 00091 In Slave mode, if HAL_I2S_DMAStop is used to stop the communication, an error 00092 HAL_I2S_ERROR_BUSY_LINE_RX is raised as the master continue to transmit data. 00093 In this case __HAL_I2S_FLUSH_RX_DR macro must be used to flush the remaining data 00094 inside DR register and avoid using DeInit/Init process for the next transfer. 00095 00096 *** I2S HAL driver macros list *** 00097 =================================== 00098 [..] 00099 Below the list of most used macros in I2S HAL driver. 00100 00101 (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode) 00102 (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode) 00103 (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts 00104 (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts 00105 (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not 00106 (+) __HAL_I2S_FLUSH_RX_DR: Read DR Register to Flush RX Data 00107 00108 [..] 00109 (@) You can refer to the I2S HAL driver header file for more useful macros 00110 00111 *** I2S HAL driver macros list *** 00112 =================================== 00113 [..] 00114 Callback registration: 00115 00116 (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1U 00117 allows the user to configure dynamically the driver callbacks. 00118 Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback. 00119 00120 Function HAL_I2S_RegisterCallback() allows to register following callbacks: 00121 (++) TxCpltCallback : I2S Tx Completed callback 00122 (++) RxCpltCallback : I2S Rx Completed callback 00123 (++) TxRxCpltCallback : I2S TxRx Completed callback 00124 (++) TxHalfCpltCallback : I2S Tx Half Completed callback 00125 (++) RxHalfCpltCallback : I2S Rx Half Completed callback 00126 (++) ErrorCallback : I2S Error callback 00127 (++) MspInitCallback : I2S Msp Init callback 00128 (++) MspDeInitCallback : I2S Msp DeInit callback 00129 This function takes as parameters the HAL peripheral handle, the Callback ID 00130 and a pointer to the user callback function. 00131 00132 00133 (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default 00134 weak function. 00135 HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle, 00136 and the Callback ID. 00137 This function allows to reset following callbacks: 00138 (++) TxCpltCallback : I2S Tx Completed callback 00139 (++) RxCpltCallback : I2S Rx Completed callback 00140 (++) TxRxCpltCallback : I2S TxRx Completed callback 00141 (++) TxHalfCpltCallback : I2S Tx Half Completed callback 00142 (++) RxHalfCpltCallback : I2S Rx Half Completed callback 00143 (++) ErrorCallback : I2S Error callback 00144 (++) MspInitCallback : I2S Msp Init callback 00145 (++) MspDeInitCallback : I2S Msp DeInit callback 00146 00147 [..] 00148 By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET 00149 all callbacks are set to the corresponding weak functions: 00150 examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback(). 00151 Exception done for MspInit and MspDeInit functions that are 00152 reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when 00153 these callbacks are null (not registered beforehand). 00154 If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit() 00155 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. 00156 00157 [..] 00158 Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only. 00159 Exception done MspInit/MspDeInit functions that can be registered/unregistered 00160 in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state, 00161 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. 00162 Then, the user first registers the MspInit/MspDeInit user callbacks 00163 using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit() 00164 or HAL_I2S_Init() function. 00165 00166 [..] 00167 When the compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or 00168 not defined, the callback registering feature is not available 00169 and weak (surcharged) callbacks are used. 00170 00171 @endverbatim 00172 ****************************************************************************** 00173 * @attention 00174 * 00175 * <h2><center>© Copyright (c) 2016 STMicroelectronics. 00176 * All rights reserved.</center></h2> 00177 * 00178 * This software component is licensed by ST under BSD 3-Clause license, 00179 * the "License"; You may not use this file except in compliance with the 00180 * License. You may obtain a copy of the License at: 00181 * opensource.org/licenses/BSD-3-Clause 00182 * 00183 ****************************************************************************** 00184 */ 00185 00186 /* Includes ------------------------------------------------------------------*/ 00187 #include "stm32f4xx_hal.h" 00188 00189 #ifdef HAL_I2S_MODULE_ENABLED 00190 00191 /** @addtogroup STM32F4xx_HAL_Driver 00192 * @{ 00193 */ 00194 00195 /** @defgroup I2S I2S 00196 * @brief I2S HAL module driver 00197 * @{ 00198 */ 00199 00200 /* Private typedef -----------------------------------------------------------*/ 00201 /* Private define ------------------------------------------------------------*/ 00202 #define I2S_TIMEOUT_FLAG 100U /*!< Timeout 100 ms */ 00203 /* Private macro -------------------------------------------------------------*/ 00204 /* Private variables ---------------------------------------------------------*/ 00205 /* Private function prototypes -----------------------------------------------*/ 00206 /** @defgroup I2S_Private_Functions I2S Private Functions 00207 * @{ 00208 */ 00209 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma); 00210 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma); 00211 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma); 00212 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma); 00213 static void I2S_DMAError(DMA_HandleTypeDef *hdma); 00214 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s); 00215 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s); 00216 static void I2S_IRQHandler(I2S_HandleTypeDef *hi2s); 00217 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State, 00218 uint32_t Timeout); 00219 /** 00220 * @} 00221 */ 00222 00223 /* Exported functions ---------------------------------------------------------*/ 00224 00225 /** @defgroup I2S_Exported_Functions I2S Exported Functions 00226 * @{ 00227 */ 00228 00229 /** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions 00230 * @brief Initialization and Configuration functions 00231 * 00232 @verbatim 00233 =============================================================================== 00234 ##### Initialization and de-initialization functions ##### 00235 =============================================================================== 00236 [..] This subsection provides a set of functions allowing to initialize and 00237 de-initialize the I2Sx peripheral in simplex mode: 00238 00239 (+) User must Implement HAL_I2S_MspInit() function in which he configures 00240 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). 00241 00242 (+) Call the function HAL_I2S_Init() to configure the selected device with 00243 the selected configuration: 00244 (++) Mode 00245 (++) Standard 00246 (++) Data Format 00247 (++) MCLK Output 00248 (++) Audio frequency 00249 (++) Polarity 00250 (++) Full duplex mode 00251 00252 (+) Call the function HAL_I2S_DeInit() to restore the default configuration 00253 of the selected I2Sx peripheral. 00254 @endverbatim 00255 * @{ 00256 */ 00257 00258 /** 00259 * @brief Initializes the I2S according to the specified parameters 00260 * in the I2S_InitTypeDef and create the associated handle. 00261 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00262 * the configuration information for I2S module 00263 * @retval HAL status 00264 */ 00265 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s) 00266 { 00267 uint32_t i2sdiv; 00268 uint32_t i2sodd; 00269 uint32_t packetlength; 00270 uint32_t tmp; 00271 uint32_t i2sclk; 00272 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00273 uint16_t tmpreg; 00274 #endif 00275 00276 /* Check the I2S handle allocation */ 00277 if (hi2s == NULL) 00278 { 00279 return HAL_ERROR; 00280 } 00281 00282 /* Check the I2S parameters */ 00283 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance)); 00284 assert_param(IS_I2S_MODE(hi2s->Init.Mode)); 00285 assert_param(IS_I2S_STANDARD(hi2s->Init.Standard)); 00286 assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat)); 00287 assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput)); 00288 assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq)); 00289 assert_param(IS_I2S_CPOL(hi2s->Init.CPOL)); 00290 assert_param(IS_I2S_CLOCKSOURCE(hi2s->Init.ClockSource)); 00291 00292 if (hi2s->State == HAL_I2S_STATE_RESET) 00293 { 00294 /* Allocate lock resource and initialize it */ 00295 hi2s->Lock = HAL_UNLOCKED; 00296 00297 /* Initialize Default I2S IrqHandler ISR */ 00298 hi2s->IrqHandlerISR = I2S_IRQHandler; 00299 00300 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 00301 /* Init the I2S Callback settings */ 00302 hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */ 00303 hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */ 00304 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00305 hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ 00306 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 00307 hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ 00308 hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ 00309 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00310 hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ 00311 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 00312 hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */ 00313 00314 if (hi2s->MspInitCallback == NULL) 00315 { 00316 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */ 00317 } 00318 00319 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ 00320 hi2s->MspInitCallback(hi2s); 00321 #else 00322 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ 00323 HAL_I2S_MspInit(hi2s); 00324 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 00325 } 00326 00327 hi2s->State = HAL_I2S_STATE_BUSY; 00328 00329 /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/ 00330 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ 00331 CLEAR_BIT(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \ 00332 SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \ 00333 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD)); 00334 hi2s->Instance->I2SPR = 0x0002U; 00335 00336 /*----------------------- I2SPR: I2SDIV and ODD Calculation -----------------*/ 00337 /* If the requested audio frequency is not the default, compute the prescaler */ 00338 if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT) 00339 { 00340 /* Check the frame length (For the Prescaler computing) ********************/ 00341 if (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) 00342 { 00343 /* Packet length is 16 bits */ 00344 packetlength = 16U; 00345 } 00346 else 00347 { 00348 /* Packet length is 32 bits */ 00349 packetlength = 32U; 00350 } 00351 00352 /* I2S standard */ 00353 if (hi2s->Init.Standard <= I2S_STANDARD_LSB) 00354 { 00355 /* In I2S standard packet length is multiplied by 2 */ 00356 packetlength = packetlength * 2U; 00357 } 00358 00359 /* Get the source clock value **********************************************/ 00360 #if defined(I2S_APB1_APB2_FEATURE) 00361 if (IS_I2S_APB1_INSTANCE(hi2s->Instance)) 00362 { 00363 i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S_APB1); 00364 } 00365 else 00366 { 00367 i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S_APB2); 00368 } 00369 #else 00370 i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S); 00371 #endif /* I2S_APB1_APB2_FEATURE */ 00372 00373 /* Compute the Real divider depending on the MCLK output state, with a floating point */ 00374 if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE) 00375 { 00376 /* MCLK output is enabled */ 00377 if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B) 00378 { 00379 tmp = (uint32_t)(((((i2sclk / (packetlength * 4U)) * 10U) / hi2s->Init.AudioFreq)) + 5U); 00380 } 00381 else 00382 { 00383 tmp = (uint32_t)(((((i2sclk / (packetlength * 8U)) * 10U) / hi2s->Init.AudioFreq)) + 5U); 00384 } 00385 } 00386 else 00387 { 00388 /* MCLK output is disabled */ 00389 tmp = (uint32_t)(((((i2sclk / packetlength) * 10U) / hi2s->Init.AudioFreq)) + 5U); 00390 } 00391 00392 /* Remove the flatting point */ 00393 tmp = tmp / 10U; 00394 00395 /* Check the parity of the divider */ 00396 i2sodd = (uint32_t)(tmp & (uint32_t)1U); 00397 00398 /* Compute the i2sdiv prescaler */ 00399 i2sdiv = (uint32_t)((tmp - i2sodd) / 2U); 00400 00401 /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ 00402 i2sodd = (uint32_t)(i2sodd << 8U); 00403 } 00404 else 00405 { 00406 /* Set the default values */ 00407 i2sdiv = 2U; 00408 i2sodd = 0U; 00409 } 00410 00411 /* Test if the divider is 1 or 0 or greater than 0xFF */ 00412 if ((i2sdiv < 2U) || (i2sdiv > 0xFFU)) 00413 { 00414 /* Set the error code and execute error callback*/ 00415 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER); 00416 return HAL_ERROR; 00417 } 00418 00419 /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/ 00420 00421 /* Write to SPIx I2SPR register the computed value */ 00422 hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput)); 00423 00424 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ 00425 /* And configure the I2S with the I2S_InitStruct values */ 00426 MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \ 00427 SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \ 00428 SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \ 00429 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD), \ 00430 (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | \ 00431 hi2s->Init.Standard | hi2s->Init.DataFormat | \ 00432 hi2s->Init.CPOL)); 00433 00434 #if defined(SPI_I2SCFGR_ASTRTEN) 00435 if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) || ((hi2s->Init.Standard == I2S_STANDARD_PCM_LONG))) 00436 { 00437 /* Write to SPIx I2SCFGR */ 00438 SET_BIT(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_ASTRTEN); 00439 } 00440 #endif /* SPI_I2SCFGR_ASTRTEN */ 00441 00442 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00443 00444 /* Configure the I2S extended if the full duplex mode is enabled */ 00445 assert_param(IS_I2S_FULLDUPLEX_MODE(hi2s->Init.FullDuplexMode)); 00446 00447 if (hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE) 00448 { 00449 /* Set FullDuplex I2S IrqHandler ISR if FULLDUPLEXMODE is enabled */ 00450 hi2s->IrqHandlerISR = HAL_I2SEx_FullDuplex_IRQHandler; 00451 00452 /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ 00453 CLEAR_BIT(I2SxEXT(hi2s->Instance)->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \ 00454 SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \ 00455 SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD)); 00456 I2SxEXT(hi2s->Instance)->I2SPR = 2U; 00457 00458 /* Get the I2SCFGR register value */ 00459 tmpreg = I2SxEXT(hi2s->Instance)->I2SCFGR; 00460 00461 /* Get the mode to be configured for the extended I2S */ 00462 if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX)) 00463 { 00464 tmp = I2S_MODE_SLAVE_RX; 00465 } 00466 else /* I2S_MODE_MASTER_RX || I2S_MODE_SLAVE_RX */ 00467 { 00468 tmp = I2S_MODE_SLAVE_TX; 00469 } 00470 00471 /* Configure the I2S Slave with the I2S Master parameter values */ 00472 tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | \ 00473 (uint16_t)tmp | \ 00474 (uint16_t)hi2s->Init.Standard | \ 00475 (uint16_t)hi2s->Init.DataFormat | \ 00476 (uint16_t)hi2s->Init.CPOL); 00477 00478 /* Write to SPIx I2SCFGR */ 00479 WRITE_REG(I2SxEXT(hi2s->Instance)->I2SCFGR, tmpreg); 00480 } 00481 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 00482 00483 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 00484 hi2s->State = HAL_I2S_STATE_READY; 00485 00486 return HAL_OK; 00487 } 00488 00489 /** 00490 * @brief DeInitializes the I2S peripheral 00491 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00492 * the configuration information for I2S module 00493 * @retval HAL status 00494 */ 00495 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s) 00496 { 00497 /* Check the I2S handle allocation */ 00498 if (hi2s == NULL) 00499 { 00500 return HAL_ERROR; 00501 } 00502 00503 /* Check the parameters */ 00504 assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance)); 00505 00506 hi2s->State = HAL_I2S_STATE_BUSY; 00507 00508 /* Disable the I2S Peripheral Clock */ 00509 __HAL_I2S_DISABLE(hi2s); 00510 00511 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 00512 if (hi2s->MspDeInitCallback == NULL) 00513 { 00514 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */ 00515 } 00516 00517 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ 00518 hi2s->MspDeInitCallback(hi2s); 00519 #else 00520 /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ 00521 HAL_I2S_MspDeInit(hi2s); 00522 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 00523 00524 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 00525 hi2s->State = HAL_I2S_STATE_RESET; 00526 00527 /* Release Lock */ 00528 __HAL_UNLOCK(hi2s); 00529 00530 return HAL_OK; 00531 } 00532 00533 /** 00534 * @brief I2S MSP Init 00535 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00536 * the configuration information for I2S module 00537 * @retval None 00538 */ 00539 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s) 00540 { 00541 /* Prevent unused argument(s) compilation warning */ 00542 UNUSED(hi2s); 00543 00544 /* NOTE : This function Should not be modified, when the callback is needed, 00545 the HAL_I2S_MspInit could be implemented in the user file 00546 */ 00547 } 00548 00549 /** 00550 * @brief I2S MSP DeInit 00551 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00552 * the configuration information for I2S module 00553 * @retval None 00554 */ 00555 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s) 00556 { 00557 /* Prevent unused argument(s) compilation warning */ 00558 UNUSED(hi2s); 00559 00560 /* NOTE : This function Should not be modified, when the callback is needed, 00561 the HAL_I2S_MspDeInit could be implemented in the user file 00562 */ 00563 } 00564 00565 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 00566 /** 00567 * @brief Register a User I2S Callback 00568 * To be used instead of the weak predefined callback 00569 * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains 00570 * the configuration information for the specified I2S. 00571 * @param CallbackID ID of the callback to be registered 00572 * @param pCallback pointer to the Callback function 00573 * @retval HAL status 00574 */ 00575 HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID, 00576 pI2S_CallbackTypeDef pCallback) 00577 { 00578 HAL_StatusTypeDef status = HAL_OK; 00579 00580 if (pCallback == NULL) 00581 { 00582 /* Update the error code */ 00583 hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK; 00584 00585 return HAL_ERROR; 00586 } 00587 /* Process locked */ 00588 __HAL_LOCK(hi2s); 00589 00590 if (HAL_I2S_STATE_READY == hi2s->State) 00591 { 00592 switch (CallbackID) 00593 { 00594 case HAL_I2S_TX_COMPLETE_CB_ID : 00595 hi2s->TxCpltCallback = pCallback; 00596 break; 00597 00598 case HAL_I2S_RX_COMPLETE_CB_ID : 00599 hi2s->RxCpltCallback = pCallback; 00600 break; 00601 00602 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00603 case HAL_I2S_TX_RX_COMPLETE_CB_ID : 00604 hi2s->TxRxCpltCallback = pCallback; 00605 break; 00606 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 00607 00608 case HAL_I2S_TX_HALF_COMPLETE_CB_ID : 00609 hi2s->TxHalfCpltCallback = pCallback; 00610 break; 00611 00612 case HAL_I2S_RX_HALF_COMPLETE_CB_ID : 00613 hi2s->RxHalfCpltCallback = pCallback; 00614 break; 00615 00616 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00617 case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID : 00618 hi2s->TxRxHalfCpltCallback = pCallback; 00619 break; 00620 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 00621 00622 case HAL_I2S_ERROR_CB_ID : 00623 hi2s->ErrorCallback = pCallback; 00624 break; 00625 00626 case HAL_I2S_MSPINIT_CB_ID : 00627 hi2s->MspInitCallback = pCallback; 00628 break; 00629 00630 case HAL_I2S_MSPDEINIT_CB_ID : 00631 hi2s->MspDeInitCallback = pCallback; 00632 break; 00633 00634 default : 00635 /* Update the error code */ 00636 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); 00637 00638 /* Return error status */ 00639 status = HAL_ERROR; 00640 break; 00641 } 00642 } 00643 else if (HAL_I2S_STATE_RESET == hi2s->State) 00644 { 00645 switch (CallbackID) 00646 { 00647 case HAL_I2S_MSPINIT_CB_ID : 00648 hi2s->MspInitCallback = pCallback; 00649 break; 00650 00651 case HAL_I2S_MSPDEINIT_CB_ID : 00652 hi2s->MspDeInitCallback = pCallback; 00653 break; 00654 00655 default : 00656 /* Update the error code */ 00657 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); 00658 00659 /* Return error status */ 00660 status = HAL_ERROR; 00661 break; 00662 } 00663 } 00664 else 00665 { 00666 /* Update the error code */ 00667 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); 00668 00669 /* Return error status */ 00670 status = HAL_ERROR; 00671 } 00672 00673 /* Release Lock */ 00674 __HAL_UNLOCK(hi2s); 00675 return status; 00676 } 00677 00678 /** 00679 * @brief Unregister an I2S Callback 00680 * I2S callback is redirected to the weak predefined callback 00681 * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains 00682 * the configuration information for the specified I2S. 00683 * @param CallbackID ID of the callback to be unregistered 00684 * @retval HAL status 00685 */ 00686 HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID) 00687 { 00688 HAL_StatusTypeDef status = HAL_OK; 00689 00690 /* Process locked */ 00691 __HAL_LOCK(hi2s); 00692 00693 if (HAL_I2S_STATE_READY == hi2s->State) 00694 { 00695 switch (CallbackID) 00696 { 00697 case HAL_I2S_TX_COMPLETE_CB_ID : 00698 hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */ 00699 break; 00700 00701 case HAL_I2S_RX_COMPLETE_CB_ID : 00702 hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */ 00703 break; 00704 00705 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00706 case HAL_I2S_TX_RX_COMPLETE_CB_ID : 00707 hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ 00708 break; 00709 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 00710 00711 case HAL_I2S_TX_HALF_COMPLETE_CB_ID : 00712 hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ 00713 break; 00714 00715 case HAL_I2S_RX_HALF_COMPLETE_CB_ID : 00716 hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ 00717 break; 00718 00719 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00720 case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID : 00721 hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ 00722 break; 00723 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 00724 00725 case HAL_I2S_ERROR_CB_ID : 00726 hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */ 00727 break; 00728 00729 case HAL_I2S_MSPINIT_CB_ID : 00730 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */ 00731 break; 00732 00733 case HAL_I2S_MSPDEINIT_CB_ID : 00734 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */ 00735 break; 00736 00737 default : 00738 /* Update the error code */ 00739 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); 00740 00741 /* Return error status */ 00742 status = HAL_ERROR; 00743 break; 00744 } 00745 } 00746 else if (HAL_I2S_STATE_RESET == hi2s->State) 00747 { 00748 switch (CallbackID) 00749 { 00750 case HAL_I2S_MSPINIT_CB_ID : 00751 hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */ 00752 break; 00753 00754 case HAL_I2S_MSPDEINIT_CB_ID : 00755 hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */ 00756 break; 00757 00758 default : 00759 /* Update the error code */ 00760 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); 00761 00762 /* Return error status */ 00763 status = HAL_ERROR; 00764 break; 00765 } 00766 } 00767 else 00768 { 00769 /* Update the error code */ 00770 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); 00771 00772 /* Return error status */ 00773 status = HAL_ERROR; 00774 } 00775 00776 /* Release Lock */ 00777 __HAL_UNLOCK(hi2s); 00778 return status; 00779 } 00780 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 00781 /** 00782 * @} 00783 */ 00784 00785 /** @defgroup I2S_Exported_Functions_Group2 IO operation functions 00786 * @brief Data transfers functions 00787 * 00788 @verbatim 00789 =============================================================================== 00790 ##### IO operation functions ##### 00791 =============================================================================== 00792 [..] 00793 This subsection provides a set of functions allowing to manage the I2S data 00794 transfers. 00795 00796 (#) There are two modes of transfer: 00797 (++) Blocking mode : The communication is performed in the polling mode. 00798 The status of all data processing is returned by the same function 00799 after finishing transfer. 00800 (++) No-Blocking mode : The communication is performed using Interrupts 00801 or DMA. These functions return the status of the transfer startup. 00802 The end of the data processing will be indicated through the 00803 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when 00804 using DMA mode. 00805 00806 (#) Blocking mode functions are : 00807 (++) HAL_I2S_Transmit() 00808 (++) HAL_I2S_Receive() 00809 00810 (#) No-Blocking mode functions with Interrupt are : 00811 (++) HAL_I2S_Transmit_IT() 00812 (++) HAL_I2S_Receive_IT() 00813 00814 (#) No-Blocking mode functions with DMA are : 00815 (++) HAL_I2S_Transmit_DMA() 00816 (++) HAL_I2S_Receive_DMA() 00817 00818 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: 00819 (++) HAL_I2S_TxCpltCallback() 00820 (++) HAL_I2S_RxCpltCallback() 00821 (++) HAL_I2S_ErrorCallback() 00822 00823 @endverbatim 00824 * @{ 00825 */ 00826 00827 /** 00828 * @brief Transmit an amount of data in blocking mode 00829 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00830 * the configuration information for I2S module 00831 * @param pData a 16-bit pointer to data buffer. 00832 * @param Size number of data sample to be sent: 00833 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 00834 * configuration phase, the Size parameter means the number of 16-bit data length 00835 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 00836 * the Size parameter means the number of 24-bit or 32-bit data length. 00837 * @param Timeout Timeout duration 00838 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 00839 * between Master and Slave(example: audio streaming). 00840 * @retval HAL status 00841 */ 00842 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout) 00843 { 00844 uint32_t tmpreg_cfgr; 00845 00846 if ((pData == NULL) || (Size == 0U)) 00847 { 00848 return HAL_ERROR; 00849 } 00850 00851 /* Process Locked */ 00852 __HAL_LOCK(hi2s); 00853 00854 if (hi2s->State != HAL_I2S_STATE_READY) 00855 { 00856 __HAL_UNLOCK(hi2s); 00857 return HAL_BUSY; 00858 } 00859 00860 /* Set state and reset error code */ 00861 hi2s->State = HAL_I2S_STATE_BUSY_TX; 00862 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 00863 hi2s->pTxBuffPtr = pData; 00864 00865 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 00866 00867 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B)) 00868 { 00869 hi2s->TxXferSize = (Size << 1U); 00870 hi2s->TxXferCount = (Size << 1U); 00871 } 00872 else 00873 { 00874 hi2s->TxXferSize = Size; 00875 hi2s->TxXferCount = Size; 00876 } 00877 00878 tmpreg_cfgr = hi2s->Instance->I2SCFGR; 00879 00880 /* Check if the I2S is already enabled */ 00881 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) 00882 { 00883 /* Enable I2S peripheral */ 00884 __HAL_I2S_ENABLE(hi2s); 00885 } 00886 00887 /* Wait until TXE flag is set */ 00888 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK) 00889 { 00890 /* Set the error code */ 00891 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 00892 hi2s->State = HAL_I2S_STATE_READY; 00893 __HAL_UNLOCK(hi2s); 00894 return HAL_ERROR; 00895 } 00896 00897 while (hi2s->TxXferCount > 0U) 00898 { 00899 hi2s->Instance->DR = (*hi2s->pTxBuffPtr); 00900 hi2s->pTxBuffPtr++; 00901 hi2s->TxXferCount--; 00902 00903 /* Wait until TXE flag is set */ 00904 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK) 00905 { 00906 /* Set the error code */ 00907 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 00908 hi2s->State = HAL_I2S_STATE_READY; 00909 __HAL_UNLOCK(hi2s); 00910 return HAL_ERROR; 00911 } 00912 00913 /* Check if an underrun occurs */ 00914 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) 00915 { 00916 /* Clear underrun flag */ 00917 __HAL_I2S_CLEAR_UDRFLAG(hi2s); 00918 00919 /* Set the error code */ 00920 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR); 00921 } 00922 } 00923 00924 /* Check if Slave mode is selected */ 00925 if (((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX) 00926 || ((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX)) 00927 { 00928 /* Wait until Busy flag is reset */ 00929 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK) 00930 { 00931 /* Set the error code */ 00932 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 00933 hi2s->State = HAL_I2S_STATE_READY; 00934 __HAL_UNLOCK(hi2s); 00935 return HAL_ERROR; 00936 } 00937 } 00938 00939 hi2s->State = HAL_I2S_STATE_READY; 00940 __HAL_UNLOCK(hi2s); 00941 return HAL_OK; 00942 } 00943 00944 /** 00945 * @brief Receive an amount of data in blocking mode 00946 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00947 * the configuration information for I2S module 00948 * @param pData a 16-bit pointer to data buffer. 00949 * @param Size number of data sample to be sent: 00950 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 00951 * configuration phase, the Size parameter means the number of 16-bit data length 00952 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 00953 * the Size parameter means the number of 24-bit or 32-bit data length. 00954 * @param Timeout Timeout duration 00955 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 00956 * between Master and Slave(example: audio streaming). 00957 * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate 00958 * in continuous way and as the I2S is not disabled at the end of the I2S transaction. 00959 * @retval HAL status 00960 */ 00961 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout) 00962 { 00963 uint32_t tmpreg_cfgr; 00964 00965 if ((pData == NULL) || (Size == 0U)) 00966 { 00967 return HAL_ERROR; 00968 } 00969 00970 /* Process Locked */ 00971 __HAL_LOCK(hi2s); 00972 00973 if (hi2s->State != HAL_I2S_STATE_READY) 00974 { 00975 __HAL_UNLOCK(hi2s); 00976 return HAL_BUSY; 00977 } 00978 00979 /* Set state and reset error code */ 00980 hi2s->State = HAL_I2S_STATE_BUSY_RX; 00981 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 00982 hi2s->pRxBuffPtr = pData; 00983 00984 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 00985 00986 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B)) 00987 { 00988 hi2s->RxXferSize = (Size << 1U); 00989 hi2s->RxXferCount = (Size << 1U); 00990 } 00991 else 00992 { 00993 hi2s->RxXferSize = Size; 00994 hi2s->RxXferCount = Size; 00995 } 00996 00997 /* Check if the I2S is already enabled */ 00998 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) 00999 { 01000 /* Enable I2S peripheral */ 01001 __HAL_I2S_ENABLE(hi2s); 01002 } 01003 01004 /* Check if Master Receiver mode is selected */ 01005 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) 01006 { 01007 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read 01008 access to the SPI_SR register. */ 01009 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 01010 } 01011 01012 /* Receive data */ 01013 while (hi2s->RxXferCount > 0U) 01014 { 01015 /* Wait until RXNE flag is set */ 01016 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK) 01017 { 01018 /* Set the error code */ 01019 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 01020 hi2s->State = HAL_I2S_STATE_READY; 01021 __HAL_UNLOCK(hi2s); 01022 return HAL_ERROR; 01023 } 01024 01025 (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR; 01026 hi2s->pRxBuffPtr++; 01027 hi2s->RxXferCount--; 01028 01029 /* Check if an overrun occurs */ 01030 if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) 01031 { 01032 /* Clear overrun flag */ 01033 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 01034 01035 /* Set the error code */ 01036 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR); 01037 } 01038 } 01039 01040 hi2s->State = HAL_I2S_STATE_READY; 01041 __HAL_UNLOCK(hi2s); 01042 return HAL_OK; 01043 } 01044 01045 /** 01046 * @brief Transmit an amount of data in non-blocking mode with Interrupt 01047 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01048 * the configuration information for I2S module 01049 * @param pData a 16-bit pointer to data buffer. 01050 * @param Size number of data sample to be sent: 01051 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 01052 * configuration phase, the Size parameter means the number of 16-bit data length 01053 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 01054 * the Size parameter means the number of 24-bit or 32-bit data length. 01055 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 01056 * between Master and Slave(example: audio streaming). 01057 * @retval HAL status 01058 */ 01059 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) 01060 { 01061 uint32_t tmpreg_cfgr; 01062 01063 if ((pData == NULL) || (Size == 0U)) 01064 { 01065 return HAL_ERROR; 01066 } 01067 01068 /* Process Locked */ 01069 __HAL_LOCK(hi2s); 01070 01071 if (hi2s->State != HAL_I2S_STATE_READY) 01072 { 01073 __HAL_UNLOCK(hi2s); 01074 return HAL_BUSY; 01075 } 01076 01077 /* Set state and reset error code */ 01078 hi2s->State = HAL_I2S_STATE_BUSY_TX; 01079 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 01080 hi2s->pTxBuffPtr = pData; 01081 01082 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 01083 01084 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B)) 01085 { 01086 hi2s->TxXferSize = (Size << 1U); 01087 hi2s->TxXferCount = (Size << 1U); 01088 } 01089 else 01090 { 01091 hi2s->TxXferSize = Size; 01092 hi2s->TxXferCount = Size; 01093 } 01094 01095 /* Enable TXE and ERR interrupt */ 01096 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 01097 01098 /* Check if the I2S is already enabled */ 01099 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) 01100 { 01101 /* Enable I2S peripheral */ 01102 __HAL_I2S_ENABLE(hi2s); 01103 } 01104 01105 __HAL_UNLOCK(hi2s); 01106 return HAL_OK; 01107 } 01108 01109 /** 01110 * @brief Receive an amount of data in non-blocking mode with Interrupt 01111 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01112 * the configuration information for I2S module 01113 * @param pData a 16-bit pointer to the Receive data buffer. 01114 * @param Size number of data sample to be sent: 01115 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 01116 * configuration phase, the Size parameter means the number of 16-bit data length 01117 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 01118 * the Size parameter means the number of 24-bit or 32-bit data length. 01119 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 01120 * between Master and Slave(example: audio streaming). 01121 * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronization 01122 * between Master and Slave otherwise the I2S interrupt should be optimized. 01123 * @retval HAL status 01124 */ 01125 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) 01126 { 01127 uint32_t tmpreg_cfgr; 01128 01129 if ((pData == NULL) || (Size == 0U)) 01130 { 01131 return HAL_ERROR; 01132 } 01133 01134 /* Process Locked */ 01135 __HAL_LOCK(hi2s); 01136 01137 if (hi2s->State != HAL_I2S_STATE_READY) 01138 { 01139 __HAL_UNLOCK(hi2s); 01140 return HAL_BUSY; 01141 } 01142 01143 /* Set state and reset error code */ 01144 hi2s->State = HAL_I2S_STATE_BUSY_RX; 01145 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 01146 hi2s->pRxBuffPtr = pData; 01147 01148 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 01149 01150 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B)) 01151 { 01152 hi2s->RxXferSize = (Size << 1U); 01153 hi2s->RxXferCount = (Size << 1U); 01154 } 01155 else 01156 { 01157 hi2s->RxXferSize = Size; 01158 hi2s->RxXferCount = Size; 01159 } 01160 01161 /* Enable RXNE and ERR interrupt */ 01162 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 01163 01164 /* Check if the I2S is already enabled */ 01165 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) 01166 { 01167 /* Enable I2S peripheral */ 01168 __HAL_I2S_ENABLE(hi2s); 01169 } 01170 01171 __HAL_UNLOCK(hi2s); 01172 return HAL_OK; 01173 } 01174 01175 /** 01176 * @brief Transmit an amount of data in non-blocking mode with DMA 01177 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01178 * the configuration information for I2S module 01179 * @param pData a 16-bit pointer to the Transmit data buffer. 01180 * @param Size number of data sample to be sent: 01181 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 01182 * configuration phase, the Size parameter means the number of 16-bit data length 01183 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 01184 * the Size parameter means the number of 24-bit or 32-bit data length. 01185 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 01186 * between Master and Slave(example: audio streaming). 01187 * @retval HAL status 01188 */ 01189 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) 01190 { 01191 uint32_t tmpreg_cfgr; 01192 01193 if ((pData == NULL) || (Size == 0U)) 01194 { 01195 return HAL_ERROR; 01196 } 01197 01198 /* Process Locked */ 01199 __HAL_LOCK(hi2s); 01200 01201 if (hi2s->State != HAL_I2S_STATE_READY) 01202 { 01203 __HAL_UNLOCK(hi2s); 01204 return HAL_BUSY; 01205 } 01206 01207 /* Set state and reset error code */ 01208 hi2s->State = HAL_I2S_STATE_BUSY_TX; 01209 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 01210 hi2s->pTxBuffPtr = pData; 01211 01212 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 01213 01214 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B)) 01215 { 01216 hi2s->TxXferSize = (Size << 1U); 01217 hi2s->TxXferCount = (Size << 1U); 01218 } 01219 else 01220 { 01221 hi2s->TxXferSize = Size; 01222 hi2s->TxXferCount = Size; 01223 } 01224 01225 /* Set the I2S Tx DMA Half transfer complete callback */ 01226 hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt; 01227 01228 /* Set the I2S Tx DMA transfer complete callback */ 01229 hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt; 01230 01231 /* Set the DMA error callback */ 01232 hi2s->hdmatx->XferErrorCallback = I2S_DMAError; 01233 01234 /* Enable the Tx DMA Stream/Channel */ 01235 if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, 01236 (uint32_t)hi2s->pTxBuffPtr, 01237 (uint32_t)&hi2s->Instance->DR, 01238 hi2s->TxXferSize)) 01239 { 01240 /* Update SPI error code */ 01241 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); 01242 hi2s->State = HAL_I2S_STATE_READY; 01243 01244 __HAL_UNLOCK(hi2s); 01245 return HAL_ERROR; 01246 } 01247 01248 /* Check if the I2S is already enabled */ 01249 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE)) 01250 { 01251 /* Enable I2S peripheral */ 01252 __HAL_I2S_ENABLE(hi2s); 01253 } 01254 01255 /* Check if the I2S Tx request is already enabled */ 01256 if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN)) 01257 { 01258 /* Enable Tx DMA Request */ 01259 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN); 01260 } 01261 01262 __HAL_UNLOCK(hi2s); 01263 return HAL_OK; 01264 } 01265 01266 /** 01267 * @brief Receive an amount of data in non-blocking mode with DMA 01268 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01269 * the configuration information for I2S module 01270 * @param pData a 16-bit pointer to the Receive data buffer. 01271 * @param Size number of data sample to be sent: 01272 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 01273 * configuration phase, the Size parameter means the number of 16-bit data length 01274 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 01275 * the Size parameter means the number of 24-bit or 32-bit data length. 01276 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 01277 * between Master and Slave(example: audio streaming). 01278 * @retval HAL status 01279 */ 01280 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) 01281 { 01282 uint32_t tmpreg_cfgr; 01283 01284 if ((pData == NULL) || (Size == 0U)) 01285 { 01286 return HAL_ERROR; 01287 } 01288 01289 /* Process Locked */ 01290 __HAL_LOCK(hi2s); 01291 01292 if (hi2s->State != HAL_I2S_STATE_READY) 01293 { 01294 __HAL_UNLOCK(hi2s); 01295 return HAL_BUSY; 01296 } 01297 01298 /* Set state and reset error code */ 01299 hi2s->State = HAL_I2S_STATE_BUSY_RX; 01300 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 01301 hi2s->pRxBuffPtr = pData; 01302 01303 tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 01304 01305 if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B)) 01306 { 01307 hi2s->RxXferSize = (Size << 1U); 01308 hi2s->RxXferCount = (Size << 1U); 01309 } 01310 else 01311 { 01312 hi2s->RxXferSize = Size; 01313 hi2s->RxXferCount = Size; 01314 } 01315 01316 /* Set the I2S Rx DMA Half transfer complete callback */ 01317 hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt; 01318 01319 /* Set the I2S Rx DMA transfer complete callback */ 01320 hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt; 01321 01322 /* Set the DMA error callback */ 01323 hi2s->hdmarx->XferErrorCallback = I2S_DMAError; 01324 01325 /* Check if Master Receiver mode is selected */ 01326 if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) 01327 { 01328 /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read 01329 access to the SPI_SR register. */ 01330 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 01331 } 01332 01333 /* Enable the Rx DMA Stream/Channel */ 01334 if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr, 01335 hi2s->RxXferSize)) 01336 { 01337 /* Update SPI error code */ 01338 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); 01339 hi2s->State = HAL_I2S_STATE_READY; 01340 01341 __HAL_UNLOCK(hi2s); 01342 return HAL_ERROR; 01343 } 01344 01345 /* Check if the I2S is already enabled */ 01346 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE)) 01347 { 01348 /* Enable I2S peripheral */ 01349 __HAL_I2S_ENABLE(hi2s); 01350 } 01351 01352 /* Check if the I2S Rx request is already enabled */ 01353 if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN)) 01354 { 01355 /* Enable Rx DMA Request */ 01356 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); 01357 } 01358 01359 __HAL_UNLOCK(hi2s); 01360 return HAL_OK; 01361 } 01362 01363 /** 01364 * @brief Pauses the audio DMA Stream/Channel playing from the Media. 01365 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01366 * the configuration information for I2S module 01367 * @retval HAL status 01368 */ 01369 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s) 01370 { 01371 /* Process Locked */ 01372 __HAL_LOCK(hi2s); 01373 01374 if (hi2s->State == HAL_I2S_STATE_BUSY_TX) 01375 { 01376 /* Disable the I2S DMA Tx request */ 01377 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN); 01378 } 01379 else if (hi2s->State == HAL_I2S_STATE_BUSY_RX) 01380 { 01381 /* Disable the I2S DMA Rx request */ 01382 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); 01383 } 01384 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 01385 else if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) 01386 { 01387 /* Pause the audio file playing by disabling the I2S DMA request */ 01388 CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN)); 01389 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN)); 01390 } 01391 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 01392 else 01393 { 01394 /* nothing to do */ 01395 } 01396 01397 /* Process Unlocked */ 01398 __HAL_UNLOCK(hi2s); 01399 01400 return HAL_OK; 01401 } 01402 01403 /** 01404 * @brief Resumes the audio DMA Stream/Channel playing from the Media. 01405 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01406 * the configuration information for I2S module 01407 * @retval HAL status 01408 */ 01409 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s) 01410 { 01411 /* Process Locked */ 01412 __HAL_LOCK(hi2s); 01413 01414 if (hi2s->State == HAL_I2S_STATE_BUSY_TX) 01415 { 01416 /* Enable the I2S DMA Tx request */ 01417 SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN); 01418 } 01419 else if (hi2s->State == HAL_I2S_STATE_BUSY_RX) 01420 { 01421 /* Enable the I2S DMA Rx request */ 01422 SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); 01423 } 01424 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 01425 else if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) 01426 { 01427 /* Pause the audio file playing by disabling the I2S DMA request */ 01428 SET_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN)); 01429 SET_BIT(I2SxEXT(hi2s->Instance)->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN)); 01430 01431 /* If the I2Sext peripheral is still not enabled, enable it */ 01432 if ((I2SxEXT(hi2s->Instance)->I2SCFGR & SPI_I2SCFGR_I2SE) == 0U) 01433 { 01434 /* Enable I2Sext peripheral */ 01435 __HAL_I2SEXT_ENABLE(hi2s); 01436 } 01437 } 01438 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 01439 else 01440 { 01441 /* nothing to do */ 01442 } 01443 01444 /* If the I2S peripheral is still not enabled, enable it */ 01445 if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE)) 01446 { 01447 /* Enable I2S peripheral */ 01448 __HAL_I2S_ENABLE(hi2s); 01449 } 01450 01451 /* Process Unlocked */ 01452 __HAL_UNLOCK(hi2s); 01453 01454 return HAL_OK; 01455 } 01456 01457 /** 01458 * @brief Stops the audio DMA Stream/Channel playing from the Media. 01459 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01460 * the configuration information for I2S module 01461 * @retval HAL status 01462 */ 01463 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s) 01464 { 01465 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 01466 uint32_t tickstart; 01467 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 01468 HAL_StatusTypeDef errorcode = HAL_OK; 01469 /* The Lock is not implemented on this API to allow the user application 01470 to call the HAL SPI API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback() 01471 when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated 01472 and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback() 01473 */ 01474 01475 if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX)) 01476 { 01477 /* Abort the I2S DMA tx Stream/Channel */ 01478 if (hi2s->hdmatx != NULL) 01479 { 01480 /* Disable the I2S DMA tx Stream/Channel */ 01481 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx)) 01482 { 01483 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); 01484 errorcode = HAL_ERROR; 01485 } 01486 } 01487 01488 /* Wait until TXE flag is set */ 01489 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, I2S_TIMEOUT_FLAG) != HAL_OK) 01490 { 01491 /* Set the error code */ 01492 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 01493 hi2s->State = HAL_I2S_STATE_READY; 01494 errorcode = HAL_ERROR; 01495 } 01496 01497 /* Wait until BSY flag is Reset */ 01498 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, I2S_TIMEOUT_FLAG) != HAL_OK) 01499 { 01500 /* Set the error code */ 01501 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 01502 hi2s->State = HAL_I2S_STATE_READY; 01503 errorcode = HAL_ERROR; 01504 } 01505 01506 /* Disable I2S peripheral */ 01507 __HAL_I2S_DISABLE(hi2s); 01508 01509 /* Clear UDR flag */ 01510 __HAL_I2S_CLEAR_UDRFLAG(hi2s); 01511 01512 /* Disable the I2S Tx DMA requests */ 01513 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN); 01514 01515 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 01516 01517 if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) 01518 { 01519 /* Abort the I2S DMA rx Stream/Channel */ 01520 if (hi2s->hdmarx != NULL) 01521 { 01522 /* Disable the I2S DMA rx Stream/Channel */ 01523 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx)) 01524 { 01525 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); 01526 errorcode = HAL_ERROR; 01527 } 01528 } 01529 01530 /* Disable I2Sext peripheral */ 01531 __HAL_I2SEXT_DISABLE(hi2s); 01532 01533 /* Clear OVR flag */ 01534 __HAL_I2SEXT_CLEAR_OVRFLAG(hi2s); 01535 01536 /* Disable the I2SxEXT DMA request */ 01537 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_RXDMAEN); 01538 01539 if (hi2s->Init.Mode == I2S_MODE_SLAVE_TX) 01540 { 01541 /* Set the error code */ 01542 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_BUSY_LINE_RX); 01543 01544 /* Set the I2S State ready */ 01545 hi2s->State = HAL_I2S_STATE_READY; 01546 errorcode = HAL_ERROR; 01547 } 01548 else 01549 { 01550 /* Read DR to Flush RX Data */ 01551 READ_REG(I2SxEXT(hi2s->Instance)->DR); 01552 } 01553 } 01554 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 01555 } 01556 01557 else if ((hi2s->Init.Mode == I2S_MODE_MASTER_RX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)) 01558 { 01559 /* Abort the I2S DMA rx Stream/Channel */ 01560 if (hi2s->hdmarx != NULL) 01561 { 01562 /* Disable the I2S DMA rx Stream/Channel */ 01563 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx)) 01564 { 01565 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); 01566 errorcode = HAL_ERROR; 01567 } 01568 } 01569 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 01570 01571 if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) 01572 { 01573 /* Abort the I2S DMA tx Stream/Channel */ 01574 if (hi2s->hdmatx != NULL) 01575 { 01576 /* Disable the I2S DMA tx Stream/Channel */ 01577 if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx)) 01578 { 01579 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); 01580 errorcode = HAL_ERROR; 01581 } 01582 } 01583 01584 tickstart = HAL_GetTick(); 01585 01586 /* Wait until TXE flag is set */ 01587 while (__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_TXE) != SET) 01588 { 01589 if (((HAL_GetTick() - tickstart) > I2S_TIMEOUT_FLAG)) 01590 { 01591 /* Set the error code */ 01592 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 01593 01594 /* Set the I2S State ready */ 01595 hi2s->State = HAL_I2S_STATE_READY; 01596 errorcode = HAL_ERROR; 01597 } 01598 } 01599 01600 /* Wait until BSY flag is Reset */ 01601 while (__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_BSY) != RESET) 01602 { 01603 if (((HAL_GetTick() - tickstart) > I2S_TIMEOUT_FLAG)) 01604 { 01605 /* Set the error code */ 01606 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 01607 01608 /* Set the I2S State ready */ 01609 hi2s->State = HAL_I2S_STATE_READY; 01610 errorcode = HAL_ERROR; 01611 } 01612 } 01613 01614 /* Disable I2Sext peripheral */ 01615 __HAL_I2SEXT_DISABLE(hi2s); 01616 01617 /* Clear UDR flag */ 01618 __HAL_I2SEXT_CLEAR_UDRFLAG(hi2s); 01619 01620 /* Disable the I2SxEXT DMA request */ 01621 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_TXDMAEN); 01622 } 01623 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 01624 01625 /* Disable I2S peripheral */ 01626 __HAL_I2S_DISABLE(hi2s); 01627 01628 /* Clear OVR flag */ 01629 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 01630 01631 /* Disable the I2S Rx DMA request */ 01632 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); 01633 01634 if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX) 01635 { 01636 /* Set the error code */ 01637 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_BUSY_LINE_RX); 01638 01639 /* Set the I2S State ready */ 01640 hi2s->State = HAL_I2S_STATE_READY; 01641 errorcode = HAL_ERROR; 01642 } 01643 else 01644 { 01645 /* Read DR to Flush RX Data */ 01646 READ_REG((hi2s->Instance)->DR); 01647 } 01648 } 01649 01650 hi2s->State = HAL_I2S_STATE_READY; 01651 01652 return errorcode; 01653 } 01654 01655 /** 01656 * @brief This function handles I2S interrupt request. 01657 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01658 * the configuration information for I2S module 01659 * @retval None 01660 */ 01661 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s) 01662 { 01663 /* Call the IrqHandler ISR set during HAL_I2S_INIT */ 01664 hi2s->IrqHandlerISR(hi2s); 01665 } 01666 01667 /** 01668 * @brief Tx Transfer Half completed callbacks 01669 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01670 * the configuration information for I2S module 01671 * @retval None 01672 */ 01673 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) 01674 { 01675 /* Prevent unused argument(s) compilation warning */ 01676 UNUSED(hi2s); 01677 01678 /* NOTE : This function Should not be modified, when the callback is needed, 01679 the HAL_I2S_TxHalfCpltCallback could be implemented in the user file 01680 */ 01681 } 01682 01683 /** 01684 * @brief Tx Transfer completed callbacks 01685 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01686 * the configuration information for I2S module 01687 * @retval None 01688 */ 01689 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) 01690 { 01691 /* Prevent unused argument(s) compilation warning */ 01692 UNUSED(hi2s); 01693 01694 /* NOTE : This function Should not be modified, when the callback is needed, 01695 the HAL_I2S_TxCpltCallback could be implemented in the user file 01696 */ 01697 } 01698 01699 /** 01700 * @brief Rx Transfer half completed callbacks 01701 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01702 * the configuration information for I2S module 01703 * @retval None 01704 */ 01705 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) 01706 { 01707 /* Prevent unused argument(s) compilation warning */ 01708 UNUSED(hi2s); 01709 01710 /* NOTE : This function Should not be modified, when the callback is needed, 01711 the HAL_I2S_RxHalfCpltCallback could be implemented in the user file 01712 */ 01713 } 01714 01715 /** 01716 * @brief Rx Transfer completed callbacks 01717 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01718 * the configuration information for I2S module 01719 * @retval None 01720 */ 01721 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) 01722 { 01723 /* Prevent unused argument(s) compilation warning */ 01724 UNUSED(hi2s); 01725 01726 /* NOTE : This function Should not be modified, when the callback is needed, 01727 the HAL_I2S_RxCpltCallback could be implemented in the user file 01728 */ 01729 } 01730 01731 /** 01732 * @brief I2S error callbacks 01733 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01734 * the configuration information for I2S module 01735 * @retval None 01736 */ 01737 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s) 01738 { 01739 /* Prevent unused argument(s) compilation warning */ 01740 UNUSED(hi2s); 01741 01742 /* NOTE : This function Should not be modified, when the callback is needed, 01743 the HAL_I2S_ErrorCallback could be implemented in the user file 01744 */ 01745 } 01746 01747 /** 01748 * @} 01749 */ 01750 01751 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions 01752 * @brief Peripheral State functions 01753 * 01754 @verbatim 01755 =============================================================================== 01756 ##### Peripheral State and Errors functions ##### 01757 =============================================================================== 01758 [..] 01759 This subsection permits to get in run-time the status of the peripheral 01760 and the data flow. 01761 01762 @endverbatim 01763 * @{ 01764 */ 01765 01766 /** 01767 * @brief Return the I2S state 01768 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01769 * the configuration information for I2S module 01770 * @retval HAL state 01771 */ 01772 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s) 01773 { 01774 return hi2s->State; 01775 } 01776 01777 /** 01778 * @brief Return the I2S error code 01779 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01780 * the configuration information for I2S module 01781 * @retval I2S Error Code 01782 */ 01783 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s) 01784 { 01785 return hi2s->ErrorCode; 01786 } 01787 /** 01788 * @} 01789 */ 01790 01791 /** 01792 * @} 01793 */ 01794 01795 /** @addtogroup I2S_Private_Functions I2S Private Functions 01796 * @{ 01797 */ 01798 /** 01799 * @brief DMA I2S transmit process complete callback 01800 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01801 * the configuration information for the specified DMA module. 01802 * @retval None 01803 */ 01804 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma) 01805 { 01806 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */ 01807 01808 /* if DMA is configured in DMA_NORMAL Mode */ 01809 if (hdma->Init.Mode == DMA_NORMAL) 01810 { 01811 /* Disable Tx DMA Request */ 01812 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN); 01813 01814 hi2s->TxXferCount = 0U; 01815 hi2s->State = HAL_I2S_STATE_READY; 01816 } 01817 /* Call user Tx complete callback */ 01818 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 01819 hi2s->TxCpltCallback(hi2s); 01820 #else 01821 HAL_I2S_TxCpltCallback(hi2s); 01822 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 01823 } 01824 01825 /** 01826 * @brief DMA I2S transmit process half complete callback 01827 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01828 * the configuration information for the specified DMA module. 01829 * @retval None 01830 */ 01831 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma) 01832 { 01833 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */ 01834 01835 /* Call user Tx half complete callback */ 01836 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 01837 hi2s->TxHalfCpltCallback(hi2s); 01838 #else 01839 HAL_I2S_TxHalfCpltCallback(hi2s); 01840 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 01841 } 01842 01843 /** 01844 * @brief DMA I2S receive process complete callback 01845 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01846 * the configuration information for the specified DMA module. 01847 * @retval None 01848 */ 01849 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma) 01850 { 01851 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */ 01852 01853 /* if DMA is configured in DMA_NORMAL Mode */ 01854 if (hdma->Init.Mode == DMA_NORMAL) 01855 { 01856 /* Disable Rx DMA Request */ 01857 CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); 01858 hi2s->RxXferCount = 0U; 01859 hi2s->State = HAL_I2S_STATE_READY; 01860 } 01861 /* Call user Rx complete callback */ 01862 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 01863 hi2s->RxCpltCallback(hi2s); 01864 #else 01865 HAL_I2S_RxCpltCallback(hi2s); 01866 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 01867 } 01868 01869 /** 01870 * @brief DMA I2S receive process half complete callback 01871 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01872 * the configuration information for the specified DMA module. 01873 * @retval None 01874 */ 01875 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma) 01876 { 01877 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */ 01878 01879 /* Call user Rx half complete callback */ 01880 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 01881 hi2s->RxHalfCpltCallback(hi2s); 01882 #else 01883 HAL_I2S_RxHalfCpltCallback(hi2s); 01884 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 01885 } 01886 01887 /** 01888 * @brief DMA I2S communication error callback 01889 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01890 * the configuration information for the specified DMA module. 01891 * @retval None 01892 */ 01893 static void I2S_DMAError(DMA_HandleTypeDef *hdma) 01894 { 01895 I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */ 01896 01897 /* Disable Rx and Tx DMA Request */ 01898 CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN)); 01899 hi2s->TxXferCount = 0U; 01900 hi2s->RxXferCount = 0U; 01901 01902 hi2s->State = HAL_I2S_STATE_READY; 01903 01904 /* Set the error code and execute error callback*/ 01905 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); 01906 /* Call user error callback */ 01907 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 01908 hi2s->ErrorCallback(hi2s); 01909 #else 01910 HAL_I2S_ErrorCallback(hi2s); 01911 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 01912 } 01913 01914 /** 01915 * @brief Transmit an amount of data in non-blocking mode with Interrupt 01916 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01917 * the configuration information for I2S module 01918 * @retval None 01919 */ 01920 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s) 01921 { 01922 /* Transmit data */ 01923 hi2s->Instance->DR = (*hi2s->pTxBuffPtr); 01924 hi2s->pTxBuffPtr++; 01925 hi2s->TxXferCount--; 01926 01927 if (hi2s->TxXferCount == 0U) 01928 { 01929 /* Disable TXE and ERR interrupt */ 01930 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 01931 01932 hi2s->State = HAL_I2S_STATE_READY; 01933 /* Call user Tx complete callback */ 01934 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 01935 hi2s->TxCpltCallback(hi2s); 01936 #else 01937 HAL_I2S_TxCpltCallback(hi2s); 01938 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 01939 } 01940 } 01941 01942 /** 01943 * @brief Receive an amount of data in non-blocking mode with Interrupt 01944 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 01945 * the configuration information for I2S module 01946 * @retval None 01947 */ 01948 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s) 01949 { 01950 /* Receive data */ 01951 (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR; 01952 hi2s->pRxBuffPtr++; 01953 hi2s->RxXferCount--; 01954 01955 if (hi2s->RxXferCount == 0U) 01956 { 01957 /* Disable RXNE and ERR interrupt */ 01958 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 01959 01960 hi2s->State = HAL_I2S_STATE_READY; 01961 /* Call user Rx complete callback */ 01962 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 01963 hi2s->RxCpltCallback(hi2s); 01964 #else 01965 HAL_I2S_RxCpltCallback(hi2s); 01966 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 01967 } 01968 } 01969 01970 /** 01971 * @brief This function handles I2S interrupt request. 01972 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains 01973 * the configuration information for I2S module 01974 * @retval None 01975 */ 01976 static void I2S_IRQHandler(I2S_HandleTypeDef *hi2s) 01977 { 01978 __IO uint32_t i2ssr = hi2s->Instance->SR; 01979 01980 if (hi2s->State == HAL_I2S_STATE_BUSY_RX) 01981 { 01982 /* I2S in mode Receiver ------------------------------------------------*/ 01983 if (((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET)) 01984 { 01985 I2S_Receive_IT(hi2s); 01986 } 01987 01988 /* I2S Overrun error interrupt occurred -------------------------------------*/ 01989 if (((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) 01990 { 01991 /* Disable RXNE and ERR interrupt */ 01992 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 01993 01994 /* Clear Overrun flag */ 01995 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 01996 01997 /* Set the I2S State ready */ 01998 hi2s->State = HAL_I2S_STATE_READY; 01999 02000 02001 /* Set the error code and execute error callback*/ 02002 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR); 02003 /* Call user error callback */ 02004 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 02005 hi2s->ErrorCallback(hi2s); 02006 #else 02007 HAL_I2S_ErrorCallback(hi2s); 02008 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 02009 } 02010 } 02011 02012 if (hi2s->State == HAL_I2S_STATE_BUSY_TX) 02013 { 02014 /* I2S in mode Transmitter -----------------------------------------------*/ 02015 if (((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET)) 02016 { 02017 I2S_Transmit_IT(hi2s); 02018 } 02019 02020 /* I2S Underrun error interrupt occurred --------------------------------*/ 02021 if (((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) 02022 { 02023 /* Disable TXE and ERR interrupt */ 02024 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 02025 02026 /* Clear Underrun flag */ 02027 __HAL_I2S_CLEAR_UDRFLAG(hi2s); 02028 02029 /* Set the I2S State ready */ 02030 hi2s->State = HAL_I2S_STATE_READY; 02031 02032 /* Set the error code and execute error callback*/ 02033 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR); 02034 /* Call user error callback */ 02035 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) 02036 hi2s->ErrorCallback(hi2s); 02037 #else 02038 HAL_I2S_ErrorCallback(hi2s); 02039 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ 02040 } 02041 } 02042 } 02043 02044 /** 02045 * @brief This function handles I2S Communication Timeout. 02046 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 02047 * the configuration information for I2S module 02048 * @param Flag Flag checked 02049 * @param State Value of the flag expected 02050 * @param Timeout Duration of the timeout 02051 * @retval HAL status 02052 */ 02053 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State, 02054 uint32_t Timeout) 02055 { 02056 uint32_t tickstart; 02057 02058 /* Get tick */ 02059 tickstart = HAL_GetTick(); 02060 02061 /* Wait until flag is set to status*/ 02062 while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State) 02063 { 02064 if (Timeout != HAL_MAX_DELAY) 02065 { 02066 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U)) 02067 { 02068 /* Set the I2S State ready */ 02069 hi2s->State = HAL_I2S_STATE_READY; 02070 02071 /* Process Unlocked */ 02072 __HAL_UNLOCK(hi2s); 02073 02074 return HAL_TIMEOUT; 02075 } 02076 } 02077 } 02078 return HAL_OK; 02079 } 02080 02081 /** 02082 * @} 02083 */ 02084 02085 /** 02086 * @} 02087 */ 02088 02089 /** 02090 * @} 02091 */ 02092 02093 #endif /* HAL_I2S_MODULE_ENABLED */ 02094 02095 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/