/** * @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 * @param pData: a 16-bit pointer to the Receive data buffer. * @param Size: number of data sample to be sent: * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S * configuration phase, the Size parameter means the number of 16-bit data length * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected * the Size parameter means the number of 16-bit data length. * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization * between Master and Slave(example: audio streaming). * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronisation * between Master and Slave otherwise the I2S interrupt should be optimized. * @retval HAL status */ HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) { uint32_t tmp1 = 0, tmp2 = 0; if(hi2s->State == HAL_I2S_STATE_READY) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } hi2s->pRxBuffPtr = pData; tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); if((tmp1 == I2S_DATAFORMAT_24B)||\ (tmp2 == I2S_DATAFORMAT_32B)) { hi2s->RxXferSize = Size*2; hi2s->RxXferCount = Size*2; } else { hi2s->RxXferSize = Size; hi2s->RxXferCount = Size; } /* Process Locked */ __HAL_LOCK(hi2s); hi2s->State = HAL_I2S_STATE_BUSY_RX; hi2s->ErrorCode = HAL_I2S_ERROR_NONE; /* Enable TXE and ERR interrupt */ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); /* Check if the I2S is already enabled */ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) { /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); } /* Process Unlocked */ __HAL_UNLOCK(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 * @param pData: a 16-bit pointer to data buffer. * @param Size: number of data sample to be sent: * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S * configuration phase, the Size parameter means the number of 16-bit data length * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected * the Size parameter means the number of 16-bit data length. * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization * between Master and Slave(example: audio streaming). * @retval HAL status */ HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hi2s); if(hi2s->State == HAL_I2S_STATE_READY) { hi2s->pTxBuffPtr = pData; hi2s->State = HAL_I2S_STATE_BUSY_TX; hi2s->ErrorCode = HAL_I2S_ERROR_NONE; if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\ ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) { hi2s->TxXferSize = (Size << 1); hi2s->TxXferCount = (Size << 1); } else { hi2s->TxXferSize = Size; hi2s->TxXferCount = Size; } /* Enable TXE and ERR interrupt */ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); /* Check if the I2S is already enabled */ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) { /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_BUSY; } }
/** * @brief Transmit and 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 * @param pTxData: a 16-bit pointer to the Transmit data buffer. * @param pRxData: a 16-bit pointer to the Receive data buffer. * @param Size: number of data sample to be sent: * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S * configuration phase, the Size parameter means the number of 16-bit data length * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected * the Size parameter means the number of 16-bit data length. * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization * between Master and Slave(example: audio streaming). * @note This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz * @retval HAL status */ HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size) { /* Check Mode parameter */ assert_param(IS_I2S_FD_MODE(hi2s->Init.Mode)); /* Process Locked */ __HAL_LOCK(hi2s); if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) { __HAL_UNLOCK(hi2s); return HAL_ERROR; } if (hi2s->State == HAL_I2S_STATE_READY) { __HAL_UNLOCK(hi2s); return HAL_BUSY; } /* Set the transaction information */ hi2s->State = HAL_I2S_STATE_BUSY_TX; hi2s->ErrorCode = HAL_I2S_ERROR_NONE; hi2s->pTxBuffPtr = pTxData; hi2s->TxXferSize = Size; hi2s->TxXferCount = Size; /* Init field not used in handle to zero */ hi2s->pRxBuffPtr = pRxData; hi2s->RxXferSize = Size; hi2s->RxXferCount = Size; /* Set the function for IT treatment */ if (hi2s->Init.DataFormat > I2S_DATAFORMAT_16B) { hi2s->RxISR = I2SEx_2linesRxISR_32BIT; hi2s->TxISR = I2SEx_2linesTxISR_32BIT; } else { hi2s->RxISR = I2SEx_2linesRxISR_16BIT; hi2s->TxISR = I2SEx_2linesTxISR_16BIT; } /* Check if the I2S is already enabled */ if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { /* Enable SPI peripheral */ __HAL_I2S_ENABLE(hi2s); } if (IS_I2S_MASTER(hi2s->Init.Mode)) { /* Master transfer start */ SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); } /* Enable TXE and ERR interrupt */ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_RXNE | I2S_IT_ERR)); /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; }
/** * @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 * @param pTxData: a 16-bit pointer to the Transmit data buffer. * @param pRxData: a 16-bit pointer to the Receive data buffer. * @param Size: number of data sample to be sent: * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S * configuration phase, the Size parameter means the number of 16-bit data length * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected * the Size parameter means the number of 16-bit data length. * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization * between Master and Slave(example: audio streaming). * @retval HAL status */ HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size) { uint32_t tmp1 = 0, tmp2 = 0; if(hi2s->State == HAL_I2S_STATE_READY) { if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) { return HAL_ERROR; } hi2s->pTxBuffPtr = pTxData; hi2s->pRxBuffPtr = pRxData; tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S configuration phase, the Size parameter means the number of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data frame is selected the Size parameter means the number of 16-bit data length. */ if((tmp1 == I2S_DATAFORMAT_24B)||\ (tmp2 == I2S_DATAFORMAT_32B)) { hi2s->TxXferSize = Size*2; hi2s->TxXferCount = Size*2; hi2s->RxXferSize = Size*2; hi2s->RxXferCount = Size*2; } else { hi2s->TxXferSize = Size; hi2s->TxXferCount = Size; hi2s->RxXferSize = Size; hi2s->RxXferCount = Size; } /* Process Locked */ __HAL_LOCK(hi2s); hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; hi2s->ErrorCode = HAL_I2S_ERROR_NONE; 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)) { /* Enable I2Sext RXNE and ERR interrupts */ I2SxEXT(hi2s->Instance)->CR2 |= (I2S_IT_RXNE | I2S_IT_ERR); /* Enable I2Sx TXE and ERR interrupts */ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); /* Check if the I2S is already enabled */ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) { /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE; /* Enable I2Sx peripheral */ __HAL_I2S_ENABLE(hi2s); } } /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ else { /* Enable I2Sext TXE and ERR interrupts */ I2SxEXT(hi2s->Instance)->CR2 |= (I2S_IT_TXE |I2S_IT_ERR); /* Enable I2Sext RXNE and ERR interrupts */ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); /* Check if the I2S is already enabled */ if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) { /* Check if the I2S_MODE_MASTER_RX is selected */ if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) { /* Prepare the First Data before enabling the I2S */ if(hi2s->TxXferCount != 0) { /* Transmit First data */ I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++); hi2s->TxXferCount--; if(hi2s->TxXferCount == 0) { /* Disable I2Sext TXE interrupt */ I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE; } } } /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */ I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE; } } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { return HAL_BUSY; } }