Skip to main content
Associate II
July 2, 2025
Solved

STM32H7A3ZI-Q: 4× INMP441 via SAI A/B in I²S/PCM mode – one stereo pair is noisy & distorted

Question:
I’m using an STM32H7A3ZI-Q with four INMP441 MEMS microphones. Each INMP441 outputs PCM (not PDM), and all four share the same BCLK (bit clock) and LRCLK/WS (word select). I’ve split the data lines into two stereo pairs:

  • SAI_A (master) → Microphones 1 & 2

  • SAI_B (synchronous slave) → Microphones 3 & 4

Both SAI blocks run in I²S/PCM mode, each with its own DMA stream.

  • Only one stereo pair connected → perfectly clean audio

  • All four microphones connected → one stereo pair becomes very noisy and distorted

 

 hsai_BlockA1.Instance = SAI1_Block_A;
 hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX;
 hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
 hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
 hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
 hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_3QF;
 hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_16K;
 hsai_BlockA1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
 hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
 hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
 hsai_BlockB1.Init.TriState = SAI_OUTPUT_NOTRELEASED;
 if (HAL_SAI_InitProtocol(&hsai_BlockA1, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_24BIT, 2) != HAL_OK)
 {
 Error_Handler();
 }
 hsai_BlockB1.Instance = SAI1_Block_B;
 hsai_BlockB1.Init.AudioMode = SAI_MODESLAVE_RX;
 hsai_BlockB1.Init.Synchro = SAI_SYNCHRONOUS;
 hsai_BlockB1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
 hsai_BlockB1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_3QF;
 hsai_BlockB1.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
 hsai_BlockB1.Init.MonoStereoMode = SAI_STEREOMODE;
 hsai_BlockB1.Init.CompandingMode = SAI_NOCOMPANDING;
 hsai_BlockB1.Init.TriState = SAI_OUTPUT_RELEASED;
 if (HAL_SAI_InitProtocol(&hsai_BlockB1, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_24BIT, 2) != HAL_OK)
 {
 Error_Handler();
 }

This is my SAI Configuration.

void Interleave4ch(const int32_t *bufA, const int32_t *bufB, uint32_t count)
{
 for (uint32_t i = 0; i < count; i++) {
 uint8_t *dst = &wavBuf[i * 4 * 3]; // 4 Channel × 3 Bytes

 int32_t a0 = bufA[2*i + 0];
 int32_t a1 = bufA[2*i + 1];
 int32_t b0 = bufB[2*i + 0];
 int32_t b1 = bufB[2*i + 1];

 // Channel 0
 dst[0] = a0 & 0xFF;
 dst[1] = (a0 >> 8) & 0xFF;
 dst[2] = (a0 >> 16) & 0xFF;
 // Channel 1
 dst[3] = a1 & 0xFF;
 dst[4] = (a1 >> 8) & 0xFF;
 dst[5] = (a1 >> 16) & 0xFF;
 // Channel 2
 dst[6] = b0 & 0xFF;
 dst[7] = (b0 >> 8) & 0xFF;
 dst[8] = (b0 >> 16) & 0xFF;
 // Channel 3
 dst[9] = b1 & 0xFF;
 dst[10] = (b1 >> 8) & 0xFF;
 dst[11] = (b1 >> 16) & 0xFF;
 }
}

This is my interleave function

What I’m looking for:

  • Which additional SAI or DMA settings become critical when handling four INMP441s in I²S/PCM mode?

  • Could an internal resource limit or clock jitter cause this?

  • Would it make sense to use a single SAI block in TDM-4-slot mode instead of two separate stereo instances, ist it even possible since i receive PCM?

  • Any best practices for reliably interfacing four digital MEMS mics with an STM32H7 over I²S/PCM?

  • I need the Data from all Microphones at the same time.

Thanks in advance for any suggestions or insights!

 

This topic has been closed for replies.
chikenJoe1Best answer
Associate II
July 2, 2025

Update: I fixed this issue, with setting pull ups on WS and Clock and Pull Downs on the SD, which might not be necessary tho.

 

I still had some Artifacts on the SD Line which looked much better after applying 470 ohms. 

1 reply

chikenJoe1AuthorBest answer
Associate II
July 2, 2025

Update: I fixed this issue, with setting pull ups on WS and Clock and Pull Downs on the SD, which might not be necessary tho.

 

I still had some Artifacts on the SD Line which looked much better after applying 470 ohms.