2021-04-22 04:14 AM
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
2021-04-22 05:19 AM
Observe the waveforms on the pins, using oscilloscope or better, LA.
Read out and check/post content of relevant GPIO and SAI registers.
JW
2021-04-22 09:57 AM
The Signal does not look unusual. Could it be, that i use the wrong clock strobe? I only got one microphone.
2021-04-22 10:04 AM
Read out and check/post content of relevant GPIO and DMA and SAI registers.
Check the raw data in DMA buffers.
JW