cancel
Showing results for 
Search instead for 
Did you mean: 

Help with getting PDM Microphone running via SAI.

Christian Pommer
Associate II

Dear Readers,

I got a lot of problems getting a PDM microphone (IM69D130) via SAI running on an STM32L431. I connected it as specified in app Note AN5027 (Select --> HIGH; Clock --> SCK_A; DATA --> SAI_SD_A);

SAI_1 has 32 MHZ.

Sai_init:

hsai_BlockA1.Instance = SAI1_Block_A;
  hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;
  hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX;
  hsai_BlockA1.Init.DataSize = SAI_DATASIZE_16;
  hsai_BlockA1.Init.FirstBit = SAI_FIRSTBIT_MSB;
  hsai_BlockA1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
  hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
  hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
  hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
  hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_FULL;
  hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_8K;
  hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockA1.FrameInit.FrameLength = 64;
  hsai_BlockA1.FrameInit.ActiveFrameLength = 32;
  hsai_BlockA1.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
  hsai_BlockA1.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
  hsai_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
  hsai_BlockA1.SlotInit.FirstBitOffset = 0;
  hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
  hsai_BlockA1.SlotInit.SlotNumber = 4;
  hsai_BlockA1.SlotInit.SlotActive = 0x0000FFFF;

I use two buffers for DMA the SAI interface

#define Bufferlength 256
#define Internalbuffer 1000
 
int16_t Databuffer[Internalbuffer];
volatile bool Buffer1 = true;
volatile uint16_t SAI_Buffer1[Bufferlength];
volatile uint16_t SAI_Buffer2[Bufferlength];
void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
{
	Buffer1 = !Buffer1;
	if (NewData)
		Overrun = true;
	else
		Overrun = false;
	NewData = true;
	if(Buffer1)
	  HAL_SAI_Receive_DMA(&hsai_BlockA1,(uint8_t *) SAI_Buffer1, Bufferlength);
	else
	  HAL_SAI_Receive_DMA(&hsai_BlockA1,(uint8_t *) SAI_Buffer2, Bufferlength);
}
 
int main(void)
{
....
  PDM_Filter_Handler_t Newfilter;
  PDM_Filter_Config_t   PDM_FilterConfig;
  Newfilter.bit_order = PDM_FILTER_BIT_ORDER_MSB;
  Newfilter.endianness = PDM_FILTER_ENDIANNESS_LE;
  Newfilter.high_pass_tap =  0.999*pow(2, 30);
  Newfilter.out_ptr_channels = 1;
  Newfilter.in_ptr_channels  = 1;
 
  PDM_FilterConfig.output_samples_number = Bufferlength/64;
  PDM_FilterConfig.mic_gain = 24;
 
  PDM_FilterConfig.decimation_factor = PDM_FILTER_DEC_FACTOR_64;
 
 
  uint16_t bufferpos = 0;
  PDM_Filter_Init(&Newfilter);
  PDM_Filter_setConfig(&Newfilter, &PDM_FilterConfig);
 
  HAL_SAI_DMAResume(&hsai_BlockA1);
 
 HAL_SAI_Receive_DMA(&hsai_BlockA1, SAI_Buffer1, Bufferlength);
  while (1)
  {
	  if (NewData)
	  {
		 if (!Buffer1)
		 {
			  PDM_Filter((uint8_t*) SAI_Buffer1, &Databuffer[bufferpos], &Newfilter);
		 }
		 else
		 {
			  PDM_Filter((uint8_t*) SAI_Buffer2, &Databuffer[bufferpos], &Newfilter);
		  }
		 bufferpos += Bufferlength/64;
		  if (bufferpos >= Internalbuffer) //Buffer full
		  {
                       bufferpos = 0;
                  }
 
		  NewData = false;
	  }

I tried to see a sine wave with 100hz but nothing shows up. Did i make a mistake somewhere?

Best regards

Christian

3 REPLIES 3

Observe the waveforms on the pins, using oscilloscope or better, LA.

Read out and check/post content of relevant GPIO and SAI registers.

JW

Christian Pommer
Associate II

The Signal does not look unusual. Could it be, that i use the wrong clock strobe? I only got one microphone.0693W00000AMH0qQAH.png

Read out and check/post content of relevant GPIO and DMA and SAI registers.

Check the raw data in DMA buffers.

JW