cancel
Showing results for 
Search instead for 
Did you mean: 

Data corruption with PDM Microphone

kcire L.
Associate III

Hello,

I am using a MEMS PDM microphone and reading it in using I2S. The following parameters are set in my I2S and PDM configurations.

hi2s3.Instance = SPI3;
  hi2s3.Init.Mode = I2S_MODE_MASTER_RX;
  hi2s3.Init.Standard = I2S_STANDARD_MSB;
  hi2s3.Init.DataFormat = I2S_DATAFORMAT_24B;
  hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
  hi2s3.Init.AudioFreq = I2S_AUDIOFREQ_48K;
  hi2s3.Init.CPOL = I2S_CPOL_LOW;
  hi2s3.Init.ClockSource = I2S_CLOCK_PLL;
  hi2s3.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;

The PDM2PCM decimation factor is 64. I am sending the data out of the uart at 2Mbaud, but am getting gaps of corrupt values in my data. Is this because I am not sending it fast enough? If so, how could I buffer this better in order to fix this issue?

Thanks for any help, my code is here as well and an image of my plotted audio.

 HAL_I2S_Receive_DMA(&hi2s3, &pdmRxBuf[0],64);
   HAL_UART_Transmit_DMA(&huart2, (uint8_t *)txBuf, 256);
  /* USER CODE END 2 */
 
 
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 
	  if (rxstate==1) {
	     	PDM_Filter(&pdmRxBuf[0],&MidBuffer[0], &PDM1_filter_handler);
	     	for (int i=0; i<16;i++)
	     	{
	     		//MidBuffer[i] = j++;
	     		FifoWrite(MidBuffer[i]);
	     		//j %= 65535;
	     	}
	     	if (fifo_w_ptr-fifo_r_ptr > 128) fifo_read_enabled=1;
	     	rxstate=0;
 
	     }
 
	     if (rxstate==2) {
	     	PDM_Filter(&pdmRxBuf[64],&MidBuffer[0], &PDM1_filter_handler);
	     	for (int i=0; i<16;i++)
	     	{
	     		//MidBuffer[i] = j++;
	     		FifoWrite(MidBuffer[i]);
	     		//j %= 65535;
	     	}
	     	rxstate=0;
 
	     }
 
	     if (txstate==1) {
	     	if (fifo_read_enabled==1) {
	 			for (int i=0; i<64;i=i+1) {
	 				uint16_t data = FifoRead();
	 				txBuf[i] = data;
	 				//txBuf[i+2] = data;
	 			}
	     	}
	     	txstate=0;
	     }
 
	     if (txstate==2) {
	     	if (fifo_read_enabled==1) {
	 			for (int i=64; i<128;i=i+1) {
	 				uint16_t data = FifoRead();
	 				txBuf[i] = data;
	 			//	txBuf[i+2] = data;
	 			}
 
	 		}
	     	txstate=0;
	     }
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
{
	 txstate = 1;
}
 
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	 txstate = 2;
}
 
void HAL_I2S_RxHalfCpltCallback (I2S_HandleTypeDef *hi2s) {
	rxstate = 1;
}
 
void HAL_I2S_RxCpltCallback (I2S_HandleTypeDef *hi2s) {
	rxstate = 2;
}

11 REPLIES 11

I'm sorry, I just want to be sure I am understanding this completely. Could you please answer my question regarding changing the number of output samples to 32? What would the pdmRxBuf input size need to be?

Thanks for all your help.

Eleon BORLINI
ST Employee

Hi @kcire L.​ ,

it should be 32*64 (bits) = 128 halfwords of 16 bits, if you are referring to your question:

>> Can I double the pdmRxBuf to 128 and then assume this will convert to 32 (uint16_t values) of PCM data?

-Eleon