2021-02-04 01:53 AM
I'm trying to get the SAI working in receive mode with a MEMS microphone, but when i try to receive data it only returns 0?
Here is the SAI setup:
saiHandle.Instance = SAI1_Block_A; // audio block A.
saiHandle.Init.Protocol = SAI_FREE_PROTOCOL;
saiHandle.Init.FirstBit = SAI_FIRSTBIT_MSB;
saiHandle.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
saiHandle.Init.AudioMode = SAI_MODEMASTER_RX; // block a must provide clock signals and receive from the data line.
saiHandle.Init.Synchro = SAI_ASYNCHRONOUS; // we only want to use this one audio block.
saiHandle.Init.SynchroExt = SAI_SYNCEXT_DISABLE; // disable sychronizing the 2 audio blocks.
saiHandle.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE; // assume to power the data?
saiHandle.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; // any frame length allowed.
saiHandle.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; // used for interrupts.
saiHandle.Init.MonoStereoMode = SAI_STEREOMODE; // mono mode only available in transmission mode.
saiHandle.Init.CompandingMode = SAI_NOCOMPANDING; // telecommunications specification (not needed)
saiHandle.Init.TriState = SAI_OUTPUT_NOTRELEASED; // assume the SAI is ma
saiHandle.Init.SynchroExt = SAI_SYNCEXT_DISABLE; // the SAI audio block A will use its internal clock.
// block frame parameters.
saiHandle.FrameInit.FrameLength = 64; // 64 bit frame. (2 slots)
saiHandle.FrameInit.ActiveFrameLength = 32; // Frame synchronization active level length. (half the frame length)
saiHandle.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
saiHandle.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
saiHandle.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
// block slot parameters.
saiHandle.SlotInit.FirstBitOffset = 0; // no offset in receive mode -> FBOFF <= (SLOTSZ - DS)
saiHandle.SlotInit.SlotSize = SAI_SLOTSIZE_32B; // 32 bits per slot to contain the 32 data bits (24 data, 8 zeroed)
saiHandle.SlotInit.SlotNumber = 2;
saiHandle.SlotInit.SlotActive = SAI_SLOTACTIVE_ALL;
/*
https://www.keil.com/pack/doc/CMSIS/Driver/html/group__sai__interface__gr.html
*/
HAL_StatusTypeDef saiStatus = HAL_SAI_InitProtocol(&saiHandle,
SAI_I2S_STANDARD, // runs the SAI_InitI2S() function.
SAI_PROTOCOL_DATASIZE_24BIT,// 24 bits (24 bit is standard for I2S).
2); // number of slots per frame - 1
__HAL_SAI_ENABLE(&saiHandle); // without this line of code the first read takes 84us because it settings sai enabled.
edit 1:
I have tried a 2 different clock configs, 4.5MHz, and 3.7MHz. The datasheet for the microphone says min freq 2048KHz, typical freq 3072KHz, max freq 4096KHz. So the 3.7 MHz should work but it has no effect.
https://cdn-shop.adafruit.com/product-files/3421/i2S+Datasheet.PDF
2021-02-05 05:07 AM
Hi @RBamf.1 ,
please note that if you suspect an issue related to the MEMS microphone, you should contact Knowles Acoustic support, since the product you posted is from their catalogue. ST MEMS microphones are not yet declared clock frequencies above 3.3MHz.
Since the STM32 libraries have been designed on these microphones, I can suggest you the X-CUBE-MEMSMIC1 example library, for example the project you can find in the directory \Projects\STM32L476RG-Nucleo\Demonstration\CCA02M2\Microphones_Streaming.
Eleon
2021-02-05 05:51 AM
I find it highly unlikely a microphone would return pure 0 even if clock would be outside specs.
I would start with observing the I2S lines using oscilloscope/LA.
JW