AnsweredAssumed Answered

STMF469I as I2S slave with external MEMS microphone

Question asked by Matti Sillanpää on Mar 8, 2017
Latest reply on Mar 9, 2017 by Matti Sillanpää

Hi.

 

 

I'm trying to understand the I2S configuration in STMF469I-Discovery. I've got external MEMS microphone that's outputting 16khz mono output. I can see with oscilloscope that the output is OK however I cannot seem to get the I2S configured correctly.

 

I've connected the mic like this and generated code with cubemx as I2S2 as slave with microphone outputting the clock signal (1Mhz), so no as SAI I2S input:

/**I2S2 GPIO Configuration
PB13 ------> I2S2_CK
PB12 ------> I2S2_WS
PC1 ------> I2S2_SD

 

I'm trying to read the output in task context like this:

 status = HAL_I2S_Receive(&hi2s2, buf, time * hi2s2.Init.AudioFreq, time*1000);

 

 

However the I2S_WaitFlagStateUntilTimeout expires as the while(__HAL_I2S_GET_FLAG(hi2s, Flag) == RESET) stays in RESET.

The HAL init is not the _weak definition stmf4xx_hal_i2s.c, but one _i2s_ex.c. Is this the problem or is this clock related?

 

I'm really having a hard time understanding the clock configuration and the audio pipelines as general. Is there any documentation about this? Below is the simple intialization generated by CubeMX and read function added by me.

 

/* I2S2 init function */
void MX_I2S2_Init(void)
{

hi2s2.Instance = SPI2;
hi2s2.Init.Mode = I2S_MODE_SLAVE_RX;
hi2s2.Init.Standard = I2S_STANDARD_LSB;
hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;
hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
//hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_44K;
hi2s2.Init.AudioFreq = I2S_FREQ;
hi2s2.Init.CPOL = I2S_CPOL_LOW;
hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
if (HAL_I2S_Init(&hi2s2) != HAL_OK)
{
Error_Handler();
}

}

void HAL_I2S_MspInit(I2S_HandleTypeDef* i2sHandle)
{

GPIO_InitTypeDef GPIO_InitStruct;
if(i2sHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */

/* USER CODE END SPI2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();

/**I2S2 GPIO Configuration
PB13 ------> I2S2_CK
PB12 ------> I2S2_WS
PC1 ------> I2S2_SD
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/* Peripheral DMA init*/

hdma_spi2_rx.Instance = DMA1_Stream3;
hdma_spi2_rx.Init.Channel = DMA_CHANNEL_0;
hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_rx.Init.Mode = DMA_NORMAL;
hdma_spi2_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(i2sHandle,hdmarx,hdma_spi2_rx);

/* USER CODE BEGIN SPI2_MspInit 1 */

/* USER CODE END SPI2_MspInit 1 */
}
}

void HAL_I2S_MspDeInit(I2S_HandleTypeDef* i2sHandle)
{

if(i2sHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspDeInit 0 */

/* USER CODE END SPI2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI2_CLK_DISABLE();

/**I2S2 GPIO Configuration
PB13 ------> I2S2_CK
PB12 ------> I2S2_WS
PC1 ------> I2S2_SD
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_12);

HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1);

/* Peripheral DMA DeInit*/
HAL_DMA_DeInit(i2sHandle->hdmarx);
}
/* USER CODE BEGIN SPI2_MspDeInit 1 */

/* USER CODE END SPI2_MspDeInit 1 */
}

/* USER CODE BEGIN 1 */
HAL_StatusTypeDef get_i2s_data(uint16_t *buf, uint16_t time) {
   HAL_StatusTypeDef status;

   HAL_I2S_MspDeInit(&hi2s2);
   MX_I2S2_Init();
   status = HAL_I2S_Receive(&hi2s2, buf, time * hi2s2.Init.AudioFreq, time*1000);

   return status;
}
/* USER CODE END 1 */

Outcomes