Skip to main content
Visitor II
July 2, 2025
Solved

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

  • July 2, 2025
  • 1 reply
  • 479 views

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.
    Best answer by chikenJoe1

    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

    chikenJoe1AuthorAnswer
    Visitor 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.