STM32F439xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_i2s_ex.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 I2S extension peripheral: 00008 * + Extension features Functions 00009 * 00010 @verbatim 00011 ============================================================================== 00012 ##### I2S Extension features ##### 00013 ============================================================================== 00014 [..] 00015 (#) In I2S full duplex mode, each SPI peripheral is able to manage sending and receiving 00016 data simultaneously using two data lines. Each SPI peripheral has an extended block 00017 called I2Sxext (i.e I2S2ext for SPI2 and I2S3ext for SPI3). 00018 (#) The extension block is not a full SPI IP, it is used only as I2S slave to 00019 implement full duplex mode. The extension block uses the same clock sources 00020 as its master. 00021 00022 (#) Both I2Sx and I2Sx_ext can be configured as transmitters or receivers. 00023 00024 [..] 00025 (@) Only I2Sx can deliver SCK and WS to I2Sx_ext in full duplex mode, where 00026 I2Sx can be I2S2 or I2S3. 00027 00028 ##### How to use this driver ##### 00029 =============================================================================== 00030 [..] 00031 Three operation modes are available within this driver : 00032 00033 *** Polling mode IO operation *** 00034 ================================= 00035 [..] 00036 (+) Send and receive in the same time an amount of data in blocking mode using HAL_I2SEx_TransmitReceive() 00037 00038 *** Interrupt mode IO operation *** 00039 =================================== 00040 [..] 00041 (+) Send and receive in the same time an amount of data in non blocking mode using HAL_I2SEx_TransmitReceive_IT() 00042 (+) At transmission/reception end of transfer HAL_I2SEx_TxRxCpltCallback is executed and user can 00043 add his own code by customization of function pointer HAL_I2SEx_TxRxCpltCallback 00044 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can 00045 add his own code by customization of function pointer HAL_I2S_ErrorCallback 00046 00047 *** DMA mode IO operation *** 00048 ============================== 00049 [..] 00050 (+) Send and receive an amount of data in non blocking mode (DMA) using HAL_I2SEx_TransmitReceive_DMA() 00051 (+) At transmission/reception end of transfer HAL_I2SEx_TxRxCpltCallback is executed and user can 00052 add his own code by customization of function pointer HAL_I2S_TxRxCpltCallback 00053 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can 00054 add his own code by customization of function pointer HAL_I2S_ErrorCallback 00055 @endverbatim 00056 00057 Additional Figure: The Extended block uses the same clock sources as its master. 00058 00059 +-----------------------+ 00060 I2Sx_SCK | | 00061 ----------+-->| I2Sx |------------------->I2Sx_SD(in/out) 00062 +--|-->| | 00063 | | +-----------------------+ 00064 | | 00065 I2S_WS | | 00066 ------>| | 00067 | | +-----------------------+ 00068 | +-->| | 00069 | | I2Sx_ext |------------------->I2Sx_extSD(in/out) 00070 +----->| | 00071 +-----------------------+ 00072 ****************************************************************************** 00073 * @attention 00074 * 00075 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00076 * 00077 * Redistribution and use in source and binary forms, with or without modification, 00078 * are permitted provided that the following conditions are met: 00079 * 1. Redistributions of source code must retain the above copyright notice, 00080 * this list of conditions and the following disclaimer. 00081 * 2. Redistributions in binary form must reproduce the above copyright notice, 00082 * this list of conditions and the following disclaimer in the documentation 00083 * and/or other materials provided with the distribution. 00084 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00085 * may be used to endorse or promote products derived from this software 00086 * without specific prior written permission. 00087 * 00088 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00089 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00090 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00091 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00092 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00093 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00094 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00095 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00096 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00097 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00098 * 00099 ****************************************************************************** 00100 */ 00101 00102 /* Includes ------------------------------------------------------------------*/ 00103 #include "stm32f4xx_hal.h" 00104 00105 /** @addtogroup STM32F4xx_HAL_Driver 00106 * @{ 00107 */ 00108 00109 #ifdef HAL_I2S_MODULE_ENABLED 00110 00111 /** @defgroup I2SEx I2SEx 00112 * @brief I2S Extended HAL module driver 00113 * @{ 00114 */ 00115 00116 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) 00117 00118 /* Private typedef -----------------------------------------------------------*/ 00119 /** @defgroup I2SEx_Private_Typedef I2S Extended Private Typedef 00120 * @{ 00121 */ 00122 typedef enum 00123 { 00124 I2S_USE_I2S = 0x00U, /*!< I2Sx should be used */ 00125 I2S_USE_I2SEXT = 0x01U, /*!< I2Sx_ext should be used */ 00126 }I2S_UseTypeDef; 00127 /** 00128 * @} 00129 */ 00130 /* Private define ------------------------------------------------------------*/ 00131 /* Private macro -------------------------------------------------------------*/ 00132 /* Private variables ---------------------------------------------------------*/ 00133 /* Private function prototypes -----------------------------------------------*/ 00134 /** @defgroup I2SEx_Private_Functions I2S Extended Private Functions 00135 * @{ 00136 */ 00137 static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma); 00138 static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma); 00139 static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma); 00140 static void I2SEx_FullDuplexTx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed); 00141 static void I2SEx_FullDuplexRx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed); 00142 static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, 00143 uint32_t State, uint32_t Timeout, I2S_UseTypeDef i2sUsed); 00144 /** 00145 * @} 00146 */ 00147 00148 /** 00149 * @} 00150 */ 00151 00152 /* Private functions ---------------------------------------------------------*/ 00153 /* Exported functions --------------------------------------------------------*/ 00154 00155 /** @addtogroup I2SEx I2SEx 00156 * @{ 00157 */ 00158 00159 /** @addtogroup I2SEx_Exported_Functions I2S Extended Exported Functions 00160 * @{ 00161 */ 00162 00163 /** @defgroup I2SEx_Exported_Functions_Group1 I2S Extended IO operation functions 00164 * @brief I2SEx IO operation functions 00165 * 00166 @verbatim 00167 =============================================================================== 00168 ##### IO operation functions##### 00169 =============================================================================== 00170 [..] 00171 This subsection provides a set of functions allowing to manage the I2S data 00172 transfers. 00173 00174 (#) There are two modes of transfer: 00175 (++) Blocking mode : The communication is performed in the polling mode. 00176 The status of all data processing is returned by the same function 00177 after finishing transfer. 00178 (++) No-Blocking mode : The communication is performed using Interrupts 00179 or DMA. These functions return the status of the transfer startup. 00180 The end of the data processing will be indicated through the 00181 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when 00182 using DMA mode. 00183 00184 (#) Blocking mode functions are : 00185 (++) HAL_I2SEx_TransmitReceive() 00186 00187 (#) No-Blocking mode functions with Interrupt are : 00188 (++) HAL_I2SEx_TransmitReceive_IT() 00189 (++) HAL_I2SEx_FullDuplex_IRQHandler() 00190 00191 (#) No-Blocking mode functions with DMA are : 00192 (++) HAL_I2SEx_TransmitReceive_DMA() 00193 00194 (#) A set of Transfer Complete Callback are provided in non Blocking mode: 00195 (++) HAL_I2SEx_TxRxCpltCallback() 00196 @endverbatim 00197 * @{ 00198 */ 00199 /** 00200 * @brief Full-Duplex Transmit/Receive data in blocking mode. 00201 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00202 * the configuration information for I2S module 00203 * @param pTxData a 16-bit pointer to the Transmit data buffer. 00204 * @param pRxData a 16-bit pointer to the Receive data buffer. 00205 * @param Size number of data sample to be sent: 00206 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 00207 * configuration phase, the Size parameter means the number of 16-bit data length 00208 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 00209 * the Size parameter means the number of 16-bit data length. 00210 * @param Timeout Timeout duration 00211 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 00212 * between Master and Slave(example: audio streaming). 00213 * @retval HAL status 00214 */ 00215 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, 00216 uint16_t Size, uint32_t Timeout) 00217 { 00218 uint32_t tmp1 = 0U; 00219 00220 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U)) 00221 { 00222 return HAL_ERROR; 00223 } 00224 00225 /* Check the I2S State */ 00226 if(hi2s->State == HAL_I2S_STATE_READY) 00227 { 00228 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 00229 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended 00230 is selected during the I2S configuration phase, the Size parameter means the number 00231 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data 00232 frame is selected the Size parameter means the number of 16-bit data length. */ 00233 if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B)) 00234 { 00235 hi2s->TxXferSize = (Size << 1U); 00236 hi2s->TxXferCount = (Size << 1U); 00237 hi2s->RxXferSize = (Size << 1U); 00238 hi2s->RxXferCount = (Size << 1U); 00239 } 00240 else 00241 { 00242 hi2s->TxXferSize = Size; 00243 hi2s->TxXferCount = Size; 00244 hi2s->RxXferSize = Size; 00245 hi2s->RxXferCount = Size; 00246 } 00247 00248 /* Process Locked */ 00249 __HAL_LOCK(hi2s); 00250 00251 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 00252 00253 /* Set the I2S State busy TX/RX */ 00254 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; 00255 00256 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; 00257 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ 00258 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX)) 00259 { 00260 /* Prepare the First Data before enabling the I2S */ 00261 hi2s->Instance->DR = (*pTxData++); 00262 hi2s->TxXferCount--; 00263 00264 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ 00265 __HAL_I2SEXT_ENABLE(hi2s); 00266 00267 /* Enable I2Sx peripheral */ 00268 __HAL_I2S_ENABLE(hi2s); 00269 00270 /* Check if Master Receiver mode is selected */ 00271 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) 00272 { 00273 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read 00274 access to the SPI_SR register. */ 00275 __HAL_I2SEXT_CLEAR_OVRFLAG(hi2s); 00276 } 00277 00278 while((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U)) 00279 { 00280 if(hi2s->TxXferCount > 0U) 00281 { 00282 /* Wait until TXE flag is set */ 00283 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2S) != HAL_OK) 00284 { 00285 /* Set the error code and execute error callback*/ 00286 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); 00287 HAL_I2S_ErrorCallback(hi2s); 00288 return HAL_TIMEOUT; 00289 } 00290 /* Write Data on DR register */ 00291 hi2s->Instance->DR = (*pTxData++); 00292 hi2s->TxXferCount--; 00293 00294 /* Check if an underrun occurs */ 00295 if((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_TX)) 00296 { 00297 /* Clear Underrun flag */ 00298 __HAL_I2S_CLEAR_UDRFLAG(hi2s); 00299 00300 /* Set the I2S State ready */ 00301 hi2s->State = HAL_I2S_STATE_READY; 00302 00303 /* Process Unlocked */ 00304 __HAL_UNLOCK(hi2s); 00305 00306 /* Set the error code and execute error callback*/ 00307 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_UDR); 00308 HAL_I2S_ErrorCallback(hi2s); 00309 00310 return HAL_ERROR; 00311 } 00312 } 00313 if(hi2s->RxXferCount > 0U) 00314 { 00315 /* Wait until RXNE flag is set */ 00316 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK) 00317 { 00318 /* Set the error code and execute error callback*/ 00319 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_TIMEOUT); 00320 HAL_I2S_ErrorCallback(hi2s); 00321 return HAL_TIMEOUT; 00322 } 00323 /* Read Data from DR register */ 00324 (*pRxData++) = I2SxEXT(hi2s->Instance)->DR; 00325 hi2s->RxXferCount--; 00326 00327 /* Check if an overrun occurs */ 00328 if(__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) 00329 { 00330 /* Clear Overrun flag */ 00331 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 00332 00333 /* Set the I2S State ready */ 00334 hi2s->State = HAL_I2S_STATE_READY; 00335 00336 /* Process Unlocked */ 00337 __HAL_UNLOCK(hi2s); 00338 00339 /* Set the error code and execute error callback*/ 00340 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR); 00341 HAL_I2S_ErrorCallback(hi2s); 00342 00343 return HAL_ERROR; 00344 } 00345 } 00346 } 00347 } 00348 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ 00349 else 00350 { 00351 /* Prepare the First Data before enabling the I2S */ 00352 I2SxEXT(hi2s->Instance)->DR = (*pTxData++); 00353 hi2s->TxXferCount--; 00354 00355 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */ 00356 __HAL_I2SEXT_ENABLE(hi2s); 00357 00358 /* Enable I2S peripheral before the I2Sext*/ 00359 __HAL_I2S_ENABLE(hi2s); 00360 00361 /* Check if Master Receiver mode is selected */ 00362 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) 00363 { 00364 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read 00365 access to the SPI_SR register. */ 00366 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 00367 } 00368 00369 while((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U)) 00370 { 00371 if(hi2s->TxXferCount > 0U) 00372 { 00373 /* Wait until TXE flag is set */ 00374 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK) 00375 { 00376 /* Set the error code and execute error callback*/ 00377 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_TIMEOUT); 00378 HAL_I2S_ErrorCallback(hi2s); 00379 return HAL_TIMEOUT; 00380 } 00381 /* Write Data on DR register */ 00382 I2SxEXT(hi2s->Instance)->DR = (*pTxData++); 00383 hi2s->TxXferCount--; 00384 00385 /* Check if an underrun occurs */ 00386 if((__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_RX)) 00387 { 00388 /* Clear Underrun flag */ 00389 __HAL_I2S_CLEAR_UDRFLAG(hi2s); 00390 00391 /* Set the I2S State ready */ 00392 hi2s->State = HAL_I2S_STATE_READY; 00393 00394 /* Process Unlocked */ 00395 __HAL_UNLOCK(hi2s); 00396 00397 /* Set the error code and execute error callback*/ 00398 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_UDR); 00399 HAL_I2S_ErrorCallback(hi2s); 00400 00401 return HAL_ERROR; 00402 } 00403 } 00404 if(hi2s->RxXferCount > 0U) 00405 { 00406 /* Wait until RXNE flag is set */ 00407 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2S) != HAL_OK) 00408 { 00409 /* Set the error code and execute error callback*/ 00410 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_TIMEOUT); 00411 HAL_I2S_ErrorCallback(hi2s); 00412 return HAL_TIMEOUT; 00413 } 00414 /* Read Data from DR register */ 00415 (*pRxData++) = hi2s->Instance->DR; 00416 hi2s->RxXferCount--; 00417 00418 /* Check if an overrun occurs */ 00419 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) 00420 { 00421 /* Clear Overrun flag */ 00422 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 00423 00424 /* Set the I2S State ready */ 00425 hi2s->State = HAL_I2S_STATE_READY; 00426 00427 /* Process Unlocked */ 00428 __HAL_UNLOCK(hi2s); 00429 00430 /* Set the error code and execute error callback*/ 00431 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR); 00432 HAL_I2S_ErrorCallback(hi2s); 00433 00434 return HAL_ERROR; 00435 } 00436 } 00437 } 00438 } 00439 00440 /* Set the I2S State ready */ 00441 hi2s->State = HAL_I2S_STATE_READY; 00442 00443 /* Process Unlocked */ 00444 __HAL_UNLOCK(hi2s); 00445 00446 return HAL_OK; 00447 } 00448 else 00449 { 00450 return HAL_BUSY; 00451 } 00452 } 00453 00454 /** 00455 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt 00456 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00457 * the configuration information for I2S module 00458 * @param pTxData a 16-bit pointer to the Transmit data buffer. 00459 * @param pRxData a 16-bit pointer to the Receive data buffer. 00460 * @param Size number of data sample to be sent: 00461 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 00462 * configuration phase, the Size parameter means the number of 16-bit data length 00463 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 00464 * the Size parameter means the number of 16-bit data length. 00465 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 00466 * between Master and Slave(example: audio streaming). 00467 * @retval HAL status 00468 */ 00469 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, 00470 uint16_t Size) 00471 { 00472 uint32_t tmp1 = 0U; 00473 00474 if(hi2s->State == HAL_I2S_STATE_READY) 00475 { 00476 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U)) 00477 { 00478 return HAL_ERROR; 00479 } 00480 00481 hi2s->pTxBuffPtr = pTxData; 00482 hi2s->pRxBuffPtr = pRxData; 00483 00484 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 00485 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended 00486 is selected during the I2S configuration phase, the Size parameter means the number 00487 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data 00488 frame is selected the Size parameter means the number of 16-bit data length. */ 00489 if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B)) 00490 { 00491 hi2s->TxXferSize = (Size << 1U); 00492 hi2s->TxXferCount = (Size << 1U); 00493 hi2s->RxXferSize = (Size << 1U); 00494 hi2s->RxXferCount = (Size << 1U); 00495 } 00496 else 00497 { 00498 hi2s->TxXferSize = Size; 00499 hi2s->TxXferCount = Size; 00500 hi2s->RxXferSize = Size; 00501 hi2s->RxXferCount = Size; 00502 } 00503 00504 /* Process Locked */ 00505 __HAL_LOCK(hi2s); 00506 00507 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 00508 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; 00509 00510 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; 00511 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ 00512 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX)) 00513 { 00514 /* Enable I2Sext RXNE and ERR interrupts */ 00515 __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 00516 00517 /* Enable I2Sx TXE and ERR interrupts */ 00518 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 00519 00520 /* Check if the I2S is already enabled */ 00521 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) 00522 { 00523 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX) 00524 { 00525 /* Prepare the First Data before enabling the I2S */ 00526 if(hi2s->TxXferCount != 0U) 00527 { 00528 /* Transmit First data */ 00529 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); 00530 hi2s->TxXferCount--; 00531 00532 if(hi2s->TxXferCount == 0U) 00533 { 00534 /* Disable TXE and ERR interrupt */ 00535 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 00536 00537 if(hi2s->RxXferCount == 0U) 00538 { 00539 /* Disable I2Sext RXNE and ERR interrupt */ 00540 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE| I2S_IT_ERR)); 00541 00542 hi2s->State = HAL_I2S_STATE_READY; 00543 HAL_I2SEx_TxRxCpltCallback(hi2s); 00544 } 00545 } 00546 } 00547 } 00548 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ 00549 __HAL_I2SEXT_ENABLE(hi2s); 00550 00551 /* Enable I2Sx peripheral */ 00552 __HAL_I2S_ENABLE(hi2s); 00553 } 00554 } 00555 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ 00556 else 00557 { 00558 /* Enable I2Sext TXE and ERR interrupts */ 00559 __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 00560 00561 /* Enable I2Sext RXNE and ERR interrupts */ 00562 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 00563 00564 /* Check if the I2S is already enabled */ 00565 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) 00566 { 00567 /* Check if the I2S_MODE_MASTER_RX is selected */ 00568 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) 00569 { 00570 /* Prepare the First Data before enabling the I2S */ 00571 if(hi2s->TxXferCount != 0U) 00572 { 00573 /* Transmit First data */ 00574 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++); 00575 hi2s->TxXferCount--; 00576 00577 if(hi2s->TxXferCount == 0U) 00578 { 00579 /* Disable I2Sext TXE and ERR interrupt */ 00580 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 00581 if(hi2s->RxXferCount == 0U) 00582 { 00583 /* Disable RXNE and ERR interrupt */ 00584 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE| I2S_IT_ERR)); 00585 00586 hi2s->State = HAL_I2S_STATE_READY; 00587 HAL_I2SEx_TxRxCpltCallback(hi2s); 00588 } 00589 } 00590 } 00591 } 00592 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */ 00593 __HAL_I2SEXT_ENABLE(hi2s); 00594 00595 /* Enable I2S peripheral */ 00596 __HAL_I2S_ENABLE(hi2s); 00597 } 00598 } 00599 /* Process Unlocked */ 00600 __HAL_UNLOCK(hi2s); 00601 00602 return HAL_OK; 00603 } 00604 else 00605 { 00606 return HAL_BUSY; 00607 } 00608 } 00609 00610 /** 00611 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA 00612 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains 00613 * the configuration information for I2S module 00614 * @param pTxData a 16-bit pointer to the Transmit data buffer. 00615 * @param pRxData a 16-bit pointer to the Receive data buffer. 00616 * @param Size number of data sample to be sent: 00617 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S 00618 * configuration phase, the Size parameter means the number of 16-bit data length 00619 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 00620 * the Size parameter means the number of 16-bit data length. 00621 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 00622 * between Master and Slave(example: audio streaming). 00623 * @retval HAL status 00624 */ 00625 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, 00626 uint16_t Size) 00627 { 00628 uint32_t *tmp = NULL; 00629 uint32_t tmp1 = 0U; 00630 00631 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U)) 00632 { 00633 return HAL_ERROR; 00634 } 00635 00636 if(hi2s->State == HAL_I2S_STATE_READY) 00637 { 00638 hi2s->pTxBuffPtr = pTxData; 00639 hi2s->pRxBuffPtr = pRxData; 00640 00641 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 00642 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended 00643 is selected during the I2S configuration phase, the Size parameter means the number 00644 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data 00645 frame is selected the Size parameter means the number of 16-bit data length. */ 00646 if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B)) 00647 { 00648 hi2s->TxXferSize = (Size << 1U); 00649 hi2s->TxXferCount = (Size << 1U); 00650 hi2s->RxXferSize = (Size << 1U); 00651 hi2s->RxXferCount = (Size << 1U); 00652 } 00653 else 00654 { 00655 hi2s->TxXferSize = Size; 00656 hi2s->TxXferCount = Size; 00657 hi2s->RxXferSize = Size; 00658 hi2s->RxXferCount = Size; 00659 } 00660 00661 /* Process Locked */ 00662 __HAL_LOCK(hi2s); 00663 00664 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 00665 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; 00666 00667 /* Set the I2S Rx DMA Half transfer complete callback */ 00668 hi2s->hdmarx->XferHalfCpltCallback = I2SEx_TxRxDMAHalfCplt; 00669 00670 /* Set the I2S Rx DMA transfer complete callback */ 00671 hi2s->hdmarx->XferCpltCallback = I2SEx_TxRxDMACplt; 00672 00673 /* Set the I2S Rx DMA error callback */ 00674 hi2s->hdmarx->XferErrorCallback = I2SEx_TxRxDMAError; 00675 00676 /* Set the I2S Tx DMA Half transfer complete callback */ 00677 hi2s->hdmatx->XferHalfCpltCallback = I2SEx_TxRxDMAHalfCplt; 00678 00679 /* Set the I2S Tx DMA transfer complete callback */ 00680 hi2s->hdmatx->XferCpltCallback = I2SEx_TxRxDMACplt; 00681 00682 /* Set the I2S Tx DMA error callback */ 00683 hi2s->hdmatx->XferErrorCallback = I2SEx_TxRxDMAError; 00684 00685 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; 00686 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ 00687 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX)) 00688 { 00689 /* Enable the Rx DMA Stream */ 00690 tmp = (uint32_t*)&pRxData; 00691 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t*)tmp, hi2s->RxXferSize); 00692 00693 /* Enable Rx DMA Request */ 00694 SET_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_RXDMAEN); 00695 00696 /* Enable the Tx DMA Stream */ 00697 tmp = (uint32_t*)&pTxData; 00698 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize); 00699 00700 /* Enable Tx DMA Request */ 00701 SET_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN); 00702 00703 /* Check if the I2S is already enabled */ 00704 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) 00705 { 00706 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ 00707 __HAL_I2SEXT_ENABLE(hi2s); 00708 00709 /* Enable I2S peripheral after the I2Sext */ 00710 __HAL_I2S_ENABLE(hi2s); 00711 } 00712 } 00713 else 00714 { 00715 /* Check if Master Receiver mode is selected */ 00716 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) 00717 { 00718 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read 00719 access to the SPI_SR register. */ 00720 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 00721 } 00722 /* Enable the Tx DMA Stream */ 00723 tmp = (uint32_t*)&pTxData; 00724 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize); 00725 00726 /* Enable Tx DMA Request */ 00727 SET_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_TXDMAEN); 00728 00729 /* Enable the Rx DMA Stream */ 00730 tmp = (uint32_t*)&pRxData; 00731 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize); 00732 00733 /* Enable Rx DMA Request */ 00734 SET_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN); 00735 00736 /* Check if the I2S is already enabled */ 00737 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) 00738 { 00739 /* Enable I2Sext(transmitter) before enabling I2Sx peripheral */ 00740 __HAL_I2SEXT_ENABLE(hi2s); 00741 /* Enable I2S peripheral before the I2Sext */ 00742 __HAL_I2S_ENABLE(hi2s); 00743 } 00744 } 00745 00746 /* Process Unlocked */ 00747 __HAL_UNLOCK(hi2s); 00748 00749 return HAL_OK; 00750 } 00751 else 00752 { 00753 return HAL_BUSY; 00754 } 00755 } 00756 00757 /** 00758 * @brief This function handles I2S/I2Sext interrupt requests in full-duplex mode. 00759 * @param hi2s I2S handle 00760 * @retval HAL status 00761 */ 00762 void HAL_I2SEx_FullDuplex_IRQHandler(I2S_HandleTypeDef *hi2s) 00763 { 00764 __IO uint32_t i2ssr = hi2s->Instance->SR ; 00765 __IO uint32_t i2sextsr = I2SxEXT(hi2s->Instance)->SR; 00766 00767 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ 00768 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) 00769 || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)) 00770 { 00771 /* I2S in mode Transmitter -------------------------------------------------*/ 00772 if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET)) 00773 { 00774 /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX, 00775 the I2S TXE interrupt will be generated to manage the full-duplex transmit phase. */ 00776 I2SEx_FullDuplexTx_IT(hi2s, I2S_USE_I2S); 00777 } 00778 00779 /* I2Sext in mode Receiver -----------------------------------------------*/ 00780 if(((i2sextsr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET)) 00781 { 00782 /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX, 00783 the I2Sext RXNE interrupt will be generated to manage the full-duplex receive phase. */ 00784 I2SEx_FullDuplexRx_IT(hi2s, I2S_USE_I2SEXT); 00785 } 00786 00787 /* I2Sext Overrun error interrupt occured --------------------------------*/ 00788 if(((i2sextsr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) 00789 { 00790 /* Disable RXNE and ERR interrupt */ 00791 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 00792 00793 /* Disable TXE and ERR interrupt */ 00794 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 00795 00796 /* Clear Overrun flag */ 00797 __HAL_I2S_CLEAR_OVRFLAG(hi2s); 00798 00799 /* Set the I2S State ready */ 00800 hi2s->State = HAL_I2S_STATE_READY; 00801 00802 /* Set the error code and execute error callback*/ 00803 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR); 00804 HAL_I2S_ErrorCallback(hi2s); 00805 } 00806 00807 /* I2S Underrun error interrupt occured ----------------------------------*/ 00808 if(((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) 00809 { 00810 /* Disable TXE and ERR interrupt */ 00811 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 00812 00813 /* Disable RXNE and ERR interrupt */ 00814 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 00815 00816 /* Clear underrun flag */ 00817 __HAL_I2S_CLEAR_UDRFLAG(hi2s); 00818 00819 /* Set the I2S State ready */ 00820 hi2s->State = HAL_I2S_STATE_READY; 00821 00822 /* Set the error code and execute error callback*/ 00823 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_UDR); 00824 HAL_I2S_ErrorCallback(hi2s); 00825 } 00826 } 00827 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ 00828 else 00829 { 00830 /* I2Sext in mode Transmitter ----------------------------------------------*/ 00831 if(((i2sextsr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET)) 00832 { 00833 /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX, 00834 the I2Sext TXE interrupt will be generated to manage the full-duplex transmit phase. */ 00835 I2SEx_FullDuplexTx_IT(hi2s, I2S_USE_I2SEXT); 00836 } 00837 00838 /* I2S in mode Receiver --------------------------------------------------*/ 00839 if(((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET)) 00840 { 00841 /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX, 00842 the I2S RXNE interrupt will be generated to manage the full-duplex receive phase. */ 00843 I2SEx_FullDuplexRx_IT(hi2s, I2S_USE_I2S); 00844 } 00845 00846 /* I2S Overrun error interrupt occured -------------------------------------*/ 00847 if(((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) 00848 { 00849 /* Disable RXNE and ERR interrupt */ 00850 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 00851 00852 /* Disable TXE and ERR interrupt */ 00853 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 00854 00855 /* Set the I2S State ready */ 00856 hi2s->State = HAL_I2S_STATE_READY; 00857 00858 /* Set the error code and execute error callback*/ 00859 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR); 00860 HAL_I2S_ErrorCallback(hi2s); 00861 } 00862 00863 /* I2Sext Underrun error interrupt occured -------------------------------*/ 00864 if(((i2sextsr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) 00865 { 00866 /* Disable TXE and ERR interrupt */ 00867 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 00868 00869 /* Disable RXNE and ERR interrupt */ 00870 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 00871 00872 /* Set the I2S State ready */ 00873 hi2s->State = HAL_I2S_STATE_READY; 00874 00875 /* Set the error code and execute error callback*/ 00876 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_UDR); 00877 HAL_I2S_ErrorCallback(hi2s); 00878 } 00879 } 00880 } 00881 00882 /** 00883 * @brief Tx and Rx Transfer half completed callback 00884 * @param hi2s I2S handle 00885 * @retval None 00886 */ 00887 __weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s) 00888 { 00889 /* Prevent unused argument(s) compilation warning */ 00890 UNUSED(hi2s); 00891 00892 /* NOTE : This function Should not be modified, when the callback is needed, 00893 the HAL_I2SEx_TxRxHalfCpltCallback could be implemented in the user file 00894 */ 00895 } 00896 00897 /** 00898 * @brief Tx and Rx Transfer completed callback 00899 * @param hi2s I2S handle 00900 * @retval None 00901 */ 00902 __weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s) 00903 { 00904 /* Prevent unused argument(s) compilation warning */ 00905 UNUSED(hi2s); 00906 00907 /* NOTE : This function Should not be modified, when the callback is needed, 00908 the HAL_I2SEx_TxRxCpltCallback could be implemented in the user file 00909 */ 00910 } 00911 00912 /** 00913 * @} 00914 */ 00915 00916 /** 00917 * @} 00918 */ 00919 00920 /** @addtogroup I2SEx_Private_Functions I2S Extended Private Functions 00921 * @{ 00922 */ 00923 00924 /** 00925 * @brief DMA I2S transmit receive process half complete callback 00926 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00927 * the configuration information for the specified DMA module. 00928 * @retval None 00929 */ 00930 static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma) 00931 { 00932 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 00933 00934 HAL_I2SEx_TxRxHalfCpltCallback(hi2s); 00935 } 00936 00937 /** 00938 * @brief DMA I2S transmit receive process complete callback 00939 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 00940 * the configuration information for the specified DMA module. 00941 * @retval None 00942 */ 00943 static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma) 00944 { 00945 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 00946 00947 /* if DMA is not configured in DMA_CIRCULAR mode */ 00948 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) 00949 { 00950 if (hi2s->hdmarx == hdma) 00951 { 00952 /* Disable Rx DMA Request */ 00953 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||\ 00954 ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)) 00955 { 00956 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_RXDMAEN); 00957 } 00958 else 00959 { 00960 CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN); 00961 } 00962 00963 hi2s->RxXferCount = 0U; 00964 00965 if (hi2s->TxXferCount == 0U) 00966 { 00967 hi2s->State = HAL_I2S_STATE_READY; 00968 00969 HAL_I2SEx_TxRxCpltCallback(hi2s); 00970 } 00971 } 00972 00973 if (hi2s->hdmatx == hdma) 00974 { 00975 /* Disable Tx DMA Request */ 00976 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||\ 00977 ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)) 00978 { 00979 CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN); 00980 } 00981 else 00982 { 00983 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_TXDMAEN); 00984 } 00985 00986 hi2s->TxXferCount = 0U; 00987 00988 if (hi2s->RxXferCount == 0U) 00989 { 00990 hi2s->State = HAL_I2S_STATE_READY; 00991 00992 HAL_I2SEx_TxRxCpltCallback(hi2s); 00993 } 00994 } 00995 } 00996 } 00997 00998 /** 00999 * @brief DMA I2S communication error callback 01000 * @param hdma DMA handle 01001 * @retval None 01002 */ 01003 static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma) 01004 { 01005 I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01006 01007 /* Disable Rx and Tx DMA Request */ 01008 CLEAR_BIT(hi2s->Instance->CR2,(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN)); 01009 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN)); 01010 01011 hi2s->TxXferCount = 0U; 01012 hi2s->RxXferCount = 0U; 01013 01014 hi2s->State= HAL_I2S_STATE_READY; 01015 01016 /* Set the error code and execute error callback*/ 01017 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_DMA); 01018 HAL_I2S_ErrorCallback(hi2s); 01019 } 01020 01021 /** 01022 * @brief Full-Duplex IT handler transmit function 01023 * @param hi2s I2S handle 01024 * @param i2sUsed indicate if I2Sx or I2Sx_ext is concerned 01025 * @retval None 01026 */ 01027 static void I2SEx_FullDuplexTx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed) 01028 { 01029 if(i2sUsed == I2S_USE_I2S) 01030 { 01031 /* Write Data on DR register */ 01032 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); 01033 hi2s->TxXferCount--; 01034 01035 if(hi2s->TxXferCount == 0U) 01036 { 01037 /* Disable TXE and ERR interrupt */ 01038 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 01039 01040 if(hi2s->RxXferCount == 0U) 01041 { 01042 hi2s->State = HAL_I2S_STATE_READY; 01043 HAL_I2SEx_TxRxCpltCallback(hi2s); 01044 } 01045 } 01046 } 01047 else 01048 { 01049 /* Write Data on DR register */ 01050 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++); 01051 hi2s->TxXferCount--; 01052 01053 if(hi2s->TxXferCount == 0U) 01054 { 01055 /* Disable I2Sext TXE and ERR interrupt */ 01056 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); 01057 01058 if(hi2s->RxXferCount == 0U) 01059 { 01060 hi2s->State = HAL_I2S_STATE_READY; 01061 HAL_I2SEx_TxRxCpltCallback(hi2s); 01062 } 01063 } 01064 } 01065 } 01066 01067 /** 01068 * @brief Full-Duplex IT handler receive function 01069 * @param hi2s I2S handle 01070 * @param i2sUsed indicate if I2Sx or I2Sx_ext is concerned 01071 * @retval None 01072 */ 01073 static void I2SEx_FullDuplexRx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed) 01074 { 01075 if(i2sUsed == I2S_USE_I2S) 01076 { 01077 /* Read Data from DR register */ 01078 (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR; 01079 hi2s->RxXferCount--; 01080 01081 if(hi2s->RxXferCount == 0U) 01082 { 01083 /* Disable RXNE and ERR interrupt */ 01084 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 01085 01086 if(hi2s->TxXferCount == 0U) 01087 { 01088 hi2s->State = HAL_I2S_STATE_READY; 01089 HAL_I2SEx_TxRxCpltCallback(hi2s); 01090 } 01091 } 01092 } 01093 else 01094 { 01095 /* Read Data from DR register */ 01096 (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR; 01097 hi2s->RxXferCount--; 01098 01099 if(hi2s->RxXferCount == 0U) 01100 { 01101 /* Disable I2Sext RXNE and ERR interrupt */ 01102 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); 01103 01104 if(hi2s->TxXferCount == 0U) 01105 { 01106 hi2s->State = HAL_I2S_STATE_READY; 01107 HAL_I2SEx_TxRxCpltCallback(hi2s); 01108 } 01109 } 01110 } 01111 } 01112 01113 /** 01114 * @brief This function handles I2S Communication Timeout. 01115 * @param hi2s I2S handle 01116 * @param Flag Flag checked 01117 * @param State Value of the flag expected 01118 * @param Timeout Duration of the timeout 01119 * @param i2sUsed I2S instance reference 01120 * @retval HAL status 01121 */ 01122 static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, 01123 uint32_t State, uint32_t Timeout, I2S_UseTypeDef i2sUsed) 01124 { 01125 uint32_t tickstart = HAL_GetTick(); 01126 01127 if(i2sUsed == I2S_USE_I2S) 01128 { 01129 /* Wait until flag is reset */ 01130 while(((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State) 01131 { 01132 if(Timeout != HAL_MAX_DELAY) 01133 { 01134 if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) 01135 { 01136 /* Set the I2S State ready */ 01137 hi2s->State= HAL_I2S_STATE_READY; 01138 01139 /* Process Unlocked */ 01140 __HAL_UNLOCK(hi2s); 01141 01142 return HAL_TIMEOUT; 01143 } 01144 } 01145 } 01146 } 01147 else /* i2sUsed == I2S_USE_I2SEXT */ 01148 { 01149 /* Wait until flag is reset */ 01150 while(((__HAL_I2SEXT_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State) 01151 { 01152 if(Timeout != HAL_MAX_DELAY) 01153 { 01154 if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) 01155 { 01156 /* Set the I2S State ready */ 01157 hi2s->State= HAL_I2S_STATE_READY; 01158 01159 /* Process Unlocked */ 01160 __HAL_UNLOCK(hi2s); 01161 01162 return HAL_TIMEOUT; 01163 } 01164 } 01165 } 01166 } 01167 return HAL_OK; 01168 } 01169 01170 /** 01171 * @} 01172 */ 01173 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ 01174 01175 /** 01176 * @} 01177 */ 01178 #endif /* HAL_I2S_MODULE_ENABLED */ 01179 01180 /** 01181 * @} 01182 */ 01183 01184 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/