/** * @brief Initializes the Audio Codec audio interface (I2S) * @note This function assumes that the I2S input clock (through PLL_R in * Devices RevA/Z and through dedicated PLLI2S_R in Devices RevB/Y) * is already configured and ready to be used. * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. * @retval None */ static void I2S2_Init(uint32_t AudioFreq) { /* Initialize the hAudioInI2s Instance parameter */ hAudioInI2s.Instance = I2S2; /* Disable I2S block */ __HAL_I2S_DISABLE(&hAudioInI2s); /* I2S2 peripheral configuration */ hAudioInI2s.Init.AudioFreq = 2 * AudioFreq; hAudioInI2s.Init.ClockSource = I2S_CLOCK_PLL; hAudioInI2s.Init.CPOL = I2S_CPOL_HIGH; hAudioInI2s.Init.DataFormat = I2S_DATAFORMAT_16B; hAudioInI2s.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE; hAudioInI2s.Init.Mode = I2S_MODE_MASTER_RX; hAudioInI2s.Init.Standard = I2S_STANDARD_LSB; /* Initialize the I2S peripheral with the structure above */ if(HAL_I2S_GetState(&hAudioInI2s) == HAL_I2S_STATE_RESET) { I2S2_MspInit(); } HAL_I2S_Init(&hAudioInI2s); }
/** * @brief Initializes the Audio Codec audio interface (I2S) * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. */ static void I2SOUT_Init(uint32_t AudioFreq) { /* Initialize the hAudioOutI2s Instance parameter */ hAudioOutI2s.Instance = I2SOUT; /* Disable I2S block */ __HAL_I2S_DISABLE(&hAudioOutI2s); /* Perform MSP initialization at first function call */ if(HAL_I2S_GetState(&hAudioOutI2s) == HAL_I2S_STATE_RESET) { I2SOUT_MspInit(); } /* I2SOUT peripheral configuration */ hAudioOutI2s.Init.AudioFreq = AudioFreq; hAudioOutI2s.Init.CPOL = I2S_CPOL_LOW; hAudioOutI2s.Init.DataFormat = I2S_DATAFORMAT_16B; hAudioOutI2s.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE; hAudioOutI2s.Init.Mode = I2S_MODE_MASTER_TX; hAudioOutI2s.Init.Standard = I2S_STANDARD; /* Initialize the I2S peripheral with the structure above */ HAL_I2S_Init(&hAudioOutI2s); }
/** * @brief DMA I2S communication error callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma) { I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Check if the SPI2S is disabled to edit CFG1 register */ if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { /* Disable Rx and Tx DMA Request */ CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN)); } else { /* Disable SPI peripheral */ __HAL_I2S_DISABLE(hi2s); /* Disable Rx and Tx DMA Request */ CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN)); /* Enable SPI peripheral */ __HAL_I2S_ENABLE(hi2s); } hi2s->TxXferCount = 0U; hi2s->RxXferCount = 0U; hi2s->State= HAL_I2S_STATE_READY; /* Set the error code and execute error callback*/ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); HAL_I2S_ErrorCallback(hi2s); }
/** * @brief Resumes the audio stream playing from the Media. * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval HAL status */ __weak HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s) { /* Process Locked */ __HAL_LOCK(hi2s); /* Disable the I2S Tx/Rx DMA requests */ hi2s->Instance->CR2 &= ~SPI_CR2_TXDMAEN; hi2s->Instance->CR2 &= ~SPI_CR2_RXDMAEN; /* Abort the I2S DMA Stream tx */ if(hi2s->hdmatx != NULL) { HAL_DMA_Abort(hi2s->hdmatx); } /* Abort the I2S DMA Stream rx */ if(hi2s->hdmarx != NULL) { HAL_DMA_Abort(hi2s->hdmarx); } /* Disable I2S peripheral */ __HAL_I2S_DISABLE(hi2s); hi2s->State = HAL_I2S_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; }
/** * @brief Resumes the audio stream playing from the Media. * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval HAL status */ HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s) { /* Process Locked */ __HAL_LOCK(hi2s); /* Disable the I2S Tx/Rx DMA requests */ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN); CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); /* Abort the I2S DMA Channel tx */ if(hi2s->hdmatx != NULL) { /* Disable the I2S DMA channel */ __HAL_DMA_DISABLE(hi2s->hdmatx); HAL_DMA_Abort(hi2s->hdmatx); } /* Abort the I2S DMA Channel rx */ if(hi2s->hdmarx != NULL) { /* Disable the I2S DMA channel */ __HAL_DMA_DISABLE(hi2s->hdmarx); HAL_DMA_Abort(hi2s->hdmarx); } /* Disable I2S peripheral */ __HAL_I2S_DISABLE(hi2s); hi2s->State = HAL_I2S_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; }
/** * @brief DeInitializes the I2S peripheral * @param hi2s pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval HAL status */ HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s) { /* Check the I2S handle allocation */ if(hi2s == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance)); hi2s->State = HAL_I2S_STATE_BUSY; /* Disable the I2S Peripheral Clock */ __HAL_I2S_DISABLE(hi2s); /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ HAL_I2S_MspDeInit(hi2s); hi2s->ErrorCode = HAL_I2S_ERROR_NONE; hi2s->State = HAL_I2S_STATE_RESET; /* Release Lock */ __HAL_UNLOCK(hi2s); return HAL_OK; }
/** * @brief Initializes the Audio Codec audio interface (I2S) * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. * @retval AUDIO_StatusTypeDef AUDIO Status */ static AUDIO_StatusTypeDef I2Sx_Init(uint32_t AudioFreq) { /* I2S peripheral configuration */ hAudioOutI2s.Init.AudioFreq = AudioFreq; hAudioOutI2s.Init.ClockSource = I2S_CLOCK_SYSCLK; hAudioOutI2s.Init.CPOL = I2S_CPOL_LOW; hAudioOutI2s.Init.DataFormat = I2S_DATAFORMAT_16B; hAudioOutI2s.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE; hAudioOutI2s.Init.Mode = I2S_MODE_MASTER_TX; hAudioOutI2s.Init.Standard = I2S_STANDARD; hAudioOutI2s.Instance = I2Sx; /* Disable I2S block */ __HAL_I2S_DISABLE(&hAudioOutI2s); /* Initialize the I2S peripheral with the structure above */ if(HAL_I2S_GetState(&hAudioOutI2s) == HAL_I2S_STATE_RESET) { I2Sx_MspInit(); } if (HAL_I2S_Init(&hAudioOutI2s) != HAL_OK) { return AUDIO_ERROR; } return AUDIO_OK; }
/** * @brief Initializes the Audio Codec audio interface (I2S). * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. * @retval None */ static void I2Sx_Init(uint32_t AudioFreq) { /* Initialize the haudio_i2s Instance parameter */ haudio_i2s.Instance = AUDIO_I2Sx; /* Disable I2S block */ __HAL_I2S_DISABLE(&haudio_i2s); haudio_i2s.Init.Mode = I2S_MODE_MASTER_TX; haudio_i2s.Init.Standard = I2S_STANDARD; haudio_i2s.Init.DataFormat = I2S_DATAFORMAT_16B; haudio_i2s.Init.AudioFreq = AudioFreq; haudio_i2s.Init.CPOL = I2S_CPOL_LOW; haudio_i2s.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE; if(HAL_I2S_GetState(&haudio_i2s) == HAL_I2S_STATE_RESET) { I2Sx_MspInit(); } /* Init the I2S */ HAL_I2S_Init(&haudio_i2s); }
/** * @brief DMA I2S transmit receive process complete callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma) { I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; if(((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & DMA_SxCR_CIRC) == 0U) { /* Check if the SPI2S is disabled to edit CFG1 register */ if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { /* Disable Tx/Rx DMA Request */ CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN); } else { /* Disable SPI peripheral */ __HAL_I2S_DISABLE(hi2s); /* Disable Rx DMA Request */ CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN); /* Enable SPI peripheral */ __HAL_I2S_ENABLE(hi2s); } hi2s->TxXferCount = 0U; hi2s->RxXferCount = 0U; hi2s->State = HAL_I2S_STATE_READY; if (hi2s->ErrorCode != HAL_I2S_ERROR_NONE) { HAL_I2S_ErrorCallback(hi2s); return; } } HAL_I2SEx_TxRxCpltCallback(hi2s); }
void i2s_init() { MEMS_MICRO_CLK_ENABLE(); /* Initialize the hAudioInI2s Instance parameter */ hMemsMicro.Instance = MEMS_MICRO_I2S; /* Disable I2S block */ __HAL_I2S_DISABLE(&hMemsMicro); /* I2S2 peripheral configuration */ hMemsMicro.Init.AudioFreq = I2S_AUDIOFREQ_48K; hMemsMicro.Init.ClockSource = I2S_CLOCK_PLL; hMemsMicro.Init.CPOL = I2S_CPOL_HIGH; hMemsMicro.Init.DataFormat = I2S_DATAFORMAT_16B; hMemsMicro.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE; hMemsMicro.Init.Mode = I2S_MODE_MASTER_RX; hMemsMicro.Init.Standard = I2S_STANDARD_LSB; mems_micro_gpio_init(); mems_micro_dma_init(); assert(HAL_I2S_Init(&hMemsMicro) == HAL_OK); }
/** * @brief Transmit and Receive an amount of data in non-blocking mode with DMA * @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 frames to be sent. * @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_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size) { /* Check Mode parameter */ assert_param(IS_I2S_FD_MODE(hi2s->Init.Mode)); if((pTxData == NULL) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hi2s); if(hi2s->State == HAL_I2S_STATE_READY) { hi2s->pTxBuffPtr = pTxData; hi2s->pRxBuffPtr = pRxData; hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; 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 << 1U); hi2s->TxXferCount = (Size << 1U); hi2s->RxXferSize = (Size << 1U); hi2s->RxXferCount = (Size << 1U); } else { hi2s->TxXferSize = Size; hi2s->TxXferCount = Size; hi2s->RxXferSize = Size; hi2s->RxXferCount = Size; } /* Set the I2S Rx DMA Half transfert complete callback */ hi2s->hdmarx->XferHalfCpltCallback = I2SEx_DMATxRxHalfCplt; /* Set the I2S Rx DMA transfert complete callback */ hi2s->hdmarx->XferCpltCallback = I2SEx_DMATxRxCplt; /* Set the DMA error callback */ hi2s->hdmarx->XferErrorCallback = I2SEx_TxRxDMAError; /* Enable the Rx DMA Channel */ HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr, hi2s->RxXferSize); /* Check if the I2S Rx requests are already enabled */ if(HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN)) { /* Check if the SPI2S is disabled to edit CFG1 register */ if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { /* Enable Rx DMA Request */ SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); } else { /* Disable SPI peripheral */ __HAL_I2S_DISABLE(hi2s); /* Enable Rx DMA Request */ SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); /* Enable SPI peripheral */ __HAL_I2S_ENABLE(hi2s); } } /* Set the I2S Tx DMA transfer callbacks as NULL because the communication closing is performed in DMA reception callbacks */ hi2s->hdmatx->XferHalfCpltCallback = NULL; hi2s->hdmatx->XferCpltCallback = NULL; hi2s->hdmatx->XferErrorCallback = NULL; /* Enable the Tx DMA Channel */ HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR, hi2s->TxXferSize); /* Check if the I2S Tx requests are already enabled */ if(HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN)) { /* Check if the SPI2S is disabled to edit CFG1 register */ if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { /* Enable Tx DMA Request */ SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); } else { /* Disable SPI peripheral */ __HAL_I2S_DISABLE(hi2s); /* Enable Tx/Rx DMA Request */ SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); /* Enable SPI peripheral */ __HAL_I2S_ENABLE(hi2s); } } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_BUSY; } }