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.