/** * @brief This function handles I2S interrupt request. * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval None */ void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s) { uint32_t i2ssr = hi2s->Instance->SR; /* I2S in mode Receiver ------------------------------------------------*/ if(((i2ssr & I2S_FLAG_OVR) != I2S_FLAG_OVR) && ((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET)) { I2S_Receive_IT(hi2s); return; } /* I2S in mode Tramitter -----------------------------------------------*/ if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET)) { I2S_Transmit_IT(hi2s); return; } /* I2S interrupt error -------------------------------------------------*/ if(__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET) { /* I2S Overrun error interrupt occured ---------------------------------*/ if((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) { /* Disable RXNE and ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); /* Set the error code and execute error callback*/ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR); } /* I2S Underrun error interrupt occured --------------------------------*/ if((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) { /* Disable TXE and ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); /* Set the error code and execute error callback*/ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR); } /* I2S Frame format error interrupt occured --------------------------*/ if((i2ssr & I2S_FLAG_FRE) == I2S_FLAG_FRE) { /* Disable TXE and ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_RXNE | I2S_IT_ERR)); /* Set the error code and execute error callback*/ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_FRE); } /* Set the I2S State ready */ hi2s->State = HAL_I2S_STATE_READY; /* Call the Error Callback */ HAL_I2S_ErrorCallback(hi2s); } }
/** * @brief Receive an amount of data in non-blocking mode with Interrupt * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval HAL status */ static HAL_StatusTypeDef I2S_Receive_IT(I2S_HandleTypeDef *hi2s) { if(hi2s->State == HAL_I2S_STATE_BUSY_RX) { /* Receive data */ (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR; hi2s->RxXferCount--; /* Check if Master Receiver mode is selected */ if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) { /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read access to the SPI_SR register. */ __HAL_I2S_CLEAR_OVRFLAG(hi2s); } if(hi2s->RxXferCount == 0) { /* Disable RXNE and ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, (uint32_t)(I2S_IT_RXNE | I2S_IT_ERR)); hi2s->State = HAL_I2S_STATE_READY; HAL_I2S_RxCpltCallback(hi2s); } return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Transmit an amount of data in non-blocking mode with Interrupt * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval HAL status */ static HAL_StatusTypeDef I2S_Transmit_IT(I2S_HandleTypeDef *hi2s) { if(hi2s->State == HAL_I2S_STATE_BUSY_TX) { /* Transmit data */ hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); hi2s->TxXferCount--; if(hi2s->TxXferCount == 0) { /* Disable TXE and ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, (uint32_t)(I2S_IT_TXE | I2S_IT_ERR)); hi2s->State = HAL_I2S_STATE_READY; HAL_I2S_TxCpltCallback(hi2s); } return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Receive an amount of data in non-blocking mode with Interrupt * @param hi2s: I2S handle * @retval None */ static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s) { /* Receive data */ (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR; hi2s->RxXferCount--; if(hi2s->RxXferCount == 0) { /* Disable RXNE and ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); hi2s->State = HAL_I2S_STATE_READY; HAL_I2S_RxCpltCallback(hi2s); } }
/** * @brief Transmit an amount of data in non-blocking mode with Interrupt * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval None */ static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s) { /* Transmit data */ hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); hi2s->TxXferCount--; if(hi2s->TxXferCount == 0) { /* Disable TXE and ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); hi2s->State = HAL_I2S_STATE_READY; HAL_I2S_TxCpltCallback(hi2s); } }
/** * @brief Rx 32-bit handler for Transmit and Receive in Interrupt mode. * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module. * @retval None */ static void I2SEx_2linesRxISR_32BIT(struct __I2S_HandleTypeDef *hi2s) { /* Receive data in 32 Bit mode */ *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR; hi2s->pRxBuffPtr += sizeof(uint32_t); hi2s->RxXferCount--; if (hi2s->RxXferCount == 0U) { /* Disable RXNE interrupt */ __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_RXNE); if (hi2s->TxXferCount == 0U) { I2SEx_CloseRxTx_ISR(hi2s); } } }
/** * @brief Tx 32-bit handler for Transmit and Receive in Interrupt mode. * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module. * @retval None */ static void I2SEx_2linesTxISR_32BIT(struct __I2S_HandleTypeDef *hi2s) { /* Transmit data in 32 Bit mode */ *((__IO uint32_t *)&hi2s->Instance->TXDR) = *((uint32_t *)hi2s->pTxBuffPtr); hi2s->pTxBuffPtr += sizeof(uint32_t); hi2s->TxXferCount--; /* Enable CRC Transmission */ if (hi2s->TxXferCount == 0U) { /* Disable TXE interrupt */ __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_TXE); if (hi2s->RxXferCount == 0U) { I2SEx_CloseRxTx_ISR(hi2s); } } }
/** * @brief Handle the end of the RXTX transaction. * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module. * @retval None */ static void I2SEx_CloseRxTx_ISR(I2S_HandleTypeDef *hi2s) { /* Disable ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_TXE | I2S_IT_ERR)); if (hi2s->ErrorCode == HAL_I2S_ERROR_NONE) { if (hi2s->State == HAL_I2S_STATE_BUSY_RX) { hi2s->State = HAL_I2S_STATE_READY; HAL_I2S_RxCpltCallback(hi2s); } else { hi2s->State = HAL_I2S_STATE_READY; HAL_I2SEx_TxRxCpltCallback(hi2s); } } else { hi2s->State = HAL_I2S_STATE_READY; HAL_I2S_ErrorCallback(hi2s); } }
/** * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval HAL status */ HAL_StatusTypeDef I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s) { uint32_t tmp1 = 0, tmp2 = 0; if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) { /* Process Locked */ __HAL_LOCK(hi2s); tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX)) { if(hi2s->TxXferCount != 0) { if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE) != RESET) { /* Transmit data */ hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); hi2s->TxXferCount--; if(hi2s->TxXferCount == 0) { /* Disable TXE interrupt */ __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_TXE); } } } if(hi2s->RxXferCount != 0) { if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) == SPI_SR_RXNE) { /* Receive data */ (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR; hi2s->RxXferCount--; if(hi2s->RxXferCount == 0) { /* Disable I2Sext RXNE interrupt */ I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_RXNE; } } } } /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ else { if(hi2s->TxXferCount != 0) { if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) == SPI_SR_TXE) { /* Transmit data */ I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++); hi2s->TxXferCount--; if(hi2s->TxXferCount == 0) { /* Disable I2Sext TXE interrupt */ I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE; HAL_I2S_TxCpltCallback(hi2s); } } } if(hi2s->RxXferCount != 0) { if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE) != RESET) { /* Receive data */ (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR; hi2s->RxXferCount--; if(hi2s->RxXferCount == 0) { /* Disable RXNE interrupt */ __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_RXNE); HAL_I2S_RxCpltCallback(hi2s); } } } } tmp1 = hi2s->RxXferCount; tmp2 = hi2s->TxXferCount; if((tmp1 == 0) && (tmp2 == 0)) { /* Disable I2Sx ERR interrupt */ __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_ERR); /* Disable I2Sext ERR interrupt */ I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_ERR; hi2s->State = HAL_I2S_STATE_READY; } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { return HAL_BUSY; } }