2025-07-10 5:15 PM
Hello,
I am trying to fill a buffer from the on-board MEMS microphone using the BSP_AUDIO_IN_RecordPDM() function. However, execution pauses around HAL_SAI_Receive_DMA() and the BSP_AUDIO_IN_IRQHandler() is called. The stack trace is as follows:
Checking the hdma variable on the debugger, I can see the error code is 1, corresponding (I believe) to a transfer error. I tried looking at the relevant registers with breakpoints, but they were at 0x0 at every point:
I've tried almost everything under the sun. I disabled the D-Cache and allocated all the memory to RAM_D1, I tried allocating my buffer (copied below) to each of RAM_D1, D2, and D3
ALIGN_32BYTES (uint16_t recordPDMBuf[AUDIO_IN_PDM_BUFFER_SIZE]) __attribute__((section(".RAM_D1")));My linker script looks like this:
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of "RAM_D1" Ram type memory */
_Min_Heap_Size = 0x800 ; /* required amount of heap */
_Min_Stack_Size = 0x800 ; /* required amount of stack */
/* Memories definition */
MEMORY
{
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* Memory is divided. Actual start is 0x08000000 and actual length is 2048K */
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
}
/* ... */
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM_D1 AT> FLASH
/* Uninitialized data section into "RAM" Ram type memory */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM_D1
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM_D1
At this point, I'm not entirely sure what to do. Any help is greatly appreciated. Lastly, in case it is useful, here are all the configured peripherals in main.c:
MX_GPIO_Init();
MX_SAI1_Init();
MX_DMA2D_Init();
MX_DSIHOST_DSI_Init();
MX_LTDC_Init();
MX_FMC_Init();
MX_USART1_UART_Init();
MX_SPI2_Init();
MX_X_CUBE_AI_Init();
2025-07-11 10:05 AM
Okay! So the issue in this case was that DMA uses SAI4 and not SAI1. After fixing the issue with CubeMX I'm still reaching the error handler but at least it's a different error now: an SAI ErrorCode 2 (underrun)
2025-07-17 3:30 PM
I've been running in circles for a few days now... I tried loading in the BSP SAI audio playback example and the buffer was still just getting filled with zeroes. I'm convinced my microphones are somehow broken.
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.