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