Skip to main content
Associate II
July 22, 2025
Solved

SAI4 Receiving, DMA Busy, No Buffer Update? (STM32H747I-DISCO)

  • July 22, 2025
  • 10 replies
  • 905 views

Hello,

I'm slowly losing my sanity so I figure I'd make a post here. I set up SAI4 to interface with BDMA, hoping to retrieve data from the onboard MEMS microphone and store it in a buffer in RAM_D3. Ideally I'd like for that data to be processed by the CPU, but I can't even get the buffer to fill up.

The following code produces the output below:

audio_buffer[0] = 5;
audio_buffer[1] = 6;
audio_buffer[2] = 7;
audio_buffer[3] = 8;

// ...
// Inside main loop:
printf("SAI State: %d \r\n", HAL_SAI_GetState(&hsai_BlockA4));
printf("SAI Error: %lu \r\n", HAL_SAI_GetError(&hsai_BlockA4));
printf("SAI Buffer Address: 0x%08lx\r\n", SAI4_Block_A->DR); 
printf("DMA State: %d \r\n", HAL_DMA_GetState(&hdma_sai4_a));
printf("DMA Error: %lu \r\n", HAL_DMA_GetError(&hdma_sai4_a));
printf("Pointer location: %p \r\n", audio_buffer);
printf("Audio Buffer Data:\r\n");
for (int i = 0; i < 10; i++) {
	printf("[%d]: %d\r\n", i, audio_buffer[i]);
}

miloa_1-1753220830572.png

 

As you can see, SAI4 is in HAL_SAI_STATE_BUSY_RX and BDMA is in HAL_DMA_STATE_BUSY. However, audio_buffer is not being filled. It's worth mentioning that there doesn't even seem to be zeroes coming into the buffer, as the values I set manually are never changed.

Does anyone know what may be causing this? I'll drop my CubeMX configuration, in case it is useful:

miloa_2-1753221044535.png

miloa_3-1753221057415.png

miloa_4-1753221072094.png

miloa_5-1753221083533.png

 

Thanks in advance :(

 

Best answer by miloa

I did eventually find the solution. To my original problem: I forgot to enable the active slot. It was that simple. Just go to CubeMX > SAI4 > Configuration > Active Slot and enable one or all of them.

To the zeroes problem: It was the peripheral clocks. I found this answer by JW which gave me an idea of what clock frequency I should aim for. From there I just messed around with the clock dividers until I got something very close, and now am getting a proper signal on PE2. Notably, it seems like there's something weird about the way the HAL calculates MCKDIV, so I just set the audio frequency to the one that's dependent on MCKDIV and the kernel clock and just calculated it myself with some help from the aforementioned post.

Thanks to everyone for your help!

10 replies

waclawek.jan
Super User
July 23, 2025

Does SAI output clocks as expected?

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

JW

miloaAuthor
Associate II
July 23, 2025

Hi JW! Yes, I'm seeing a 6.690kHz clock signal on PE2 (designated CK1 pin for SAI4)

miloa_0-1753296631391.png

Registers are stuck in this state whenever I pause the debugger:

miloa_1-1753296808798.png

miloa_2-1753296852184.png

miloa_3-1753296907782.png

(DMAMUX1 is all zeroes)

 

LCE
Principal II
July 23, 2025

In the H723+ family the BDMA for SAI4 can only access certain internal SRAM spaces, maybe that's also the case here?

So you might have to place the buffers in that particular SRAM.

Check your ref manual, probably chapter "2 memory and bus architecture" might have an overview (which is hopefully correct...).

miloaAuthor
Associate II
July 23, 2025

Already checked this, following this thread, and I can confirm my memory seems to be in the right spot. If you look at my serial screenshot, you'll see that the pointer for the buffer is at 0x380010000, which is within SRAM4 in STM32H747I-DISCO. DCache is disabled.

AScha.3
Super User
July 23, 2025

Hi,

as shown in rm :

AScha3_0-1753266708693.png

-> using BDMA , your data has to be in sram4 .

If not , use other DMA .

"If you feel a post has answered your question, please click ""Accept as Solution""."
LCE
Principal II
July 23, 2025

Ah, same as in H723.

And I love ST's numbering logic:

SAI4 and SRAM4 in domain 3 

:facepalm: :D

waclawek.jan
Super User
July 24, 2025

DMA/DMAMUX registers look good, the only strange thing is, that SAI_ASR is completely zero - I'd expect nonzero FIFO level, and maybe even overflow indicated, since DMA does not pull the data. So I'd suspect SAI being mis-configured.

I'm not much of a SAI expert to judge from registers whether it's OK. One thing which IMO is suspicious is SAI_ASLOTR.SLOTEN being entirely zero, IMO that means that all received data are to be discarded.

Nevertheless, in this case I'd recommend starting with some very rudimentary polled SAI implementation until it works, and only after that going for DMA. 

JW

miloaAuthor
Associate II
July 24, 2025

Ok, you were right! It turns out I had not set any of the slots active. I have a different issue, likely related now. The SAI4 and BDMA are busy, and the transfer callbacks are being called, but the data written to the buffers is all zeroes... I imagine this could be a hardware issue, but I was wondering if there was some way to debug this?

Thanks again

What I changed, for anyone with the same problem: CubeMX > SAI4 > Slot Active > User Setting > Slot 0 on

LCE
Principal II
July 24, 2025

Although I'm using the H7 SAI with direct register setup for regular I2S ADCs, I have no idea about the required settings with PDM.

I suggest you go through the RM again and find out about each and every register setting required for PDM.

You can't always trust CubeMX & HAL ...

miloaAuthor
Associate II
July 24, 2025

More info: HAL_SAI_Receive_DMA() triggers all FIFO callbacks but fills the buffer with zeroes. DCache is disabled. HAL_SAI_Receive_IT() triggers the full callback once and then gives a transfer error, does not even touch the buffer.

miloaAuthor
Associate II
July 24, 2025

Getting a 63.3kHz signal from the clock on PE2, absolutely nothing on the PC1 data pin. I'm convinced the mic is defective.

LCE
Principal II
July 25, 2025

Getting a 63.3kHz signal ...

Does that frequency make sense? Just curious, I would have assumed it should be higher.

miloaAuthor
Associate II
July 25, 2025

I'm not entirely sure. I am admittedly a little confused on the SAI clocks. When I wrote this reply I had the mux on CubeMX configured to send a 4.096 MHz to SAI4, since I thought that met the specs for 16kHz audio with oversampling on and no internal clock divider. Then I switched it to 50 MHz since I read that CubeMX automatically adjusts the prescalers (therefore, higher frequency = better?). Neither of them work.

AScha.3
Super User
July 25, 2025

The SAI needs typ. Fs x 2048 as clock; so for 44k1 stereo I2S mode audio i use 90.333MHz sai clk.

For PDM mode - i dont know, but with 16 or 32 bit /sample it should be same.

"If you feel a post has answered your question, please click ""Accept as Solution""."
miloaAuthorBest answer
Associate II
July 26, 2025

I did eventually find the solution. To my original problem: I forgot to enable the active slot. It was that simple. Just go to CubeMX > SAI4 > Configuration > Active Slot and enable one or all of them.

To the zeroes problem: It was the peripheral clocks. I found this answer by JW which gave me an idea of what clock frequency I should aim for. From there I just messed around with the clock dividers until I got something very close, and now am getting a proper signal on PE2. Notably, it seems like there's something weird about the way the HAL calculates MCKDIV, so I just set the audio frequency to the one that's dependent on MCKDIV and the kernel clock and just calculated it myself with some help from the aforementioned post.

Thanks to everyone for your help!