cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with RX OVERRUN when using SD card DMA

KWest.1
Associate II

I have an STM32H745 board and I am trying to use FatFS, SDIO, FreeRTOS and DMA.

I know this is a mix fraught with difficulties based on all the posts I have seen and all the things I have tried.

I have it working without DMA ... but it is flakey.

So I wanted to move to DMA but every attempt fails with the HAL_SD_ERROR_RX_OVERRUN error returned by the HAL_SD_IRQHandler(&hsd1) call.

This is failing before FreeRTOS even kicks in ... so I dont think that is a factor.

Reading suggests adding hardware flow control or slowing down the clock by increasing the clock divider ... but nothing seems to help.

This is my SDMMC initialisation code:

hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;

hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;

hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;

hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;

hsd1.Init.ClockDiv = 128;

HAL_StatusTypeDef err = HAL_SD_Init(&hsd1);

   HAL_NVIC_SetPriority(SDMMC1_IRQn, 0x01, 0);

   HAL_NVIC_EnableIRQ(SDMMC1_IRQn);

If i set the priority to a larger number the interrupt stops firing ... i dont really understand why but that will be a follow up question as that will be important to make it work well once the RTOS is running.

This is the code that actually kicks off the DMA read ...

if (BSP_SD_ReadBlocks_DMA((uint32_t*)alignedBuffer,

(uint32_t)(sector),

count) == MSD_OK)

{

timeout = HAL_GetTick();

while ((readStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT)) {

}

if (sdErr == 0 && readStatus == 0) {

SendDebug("  SD Card read timeout.\r\n");

Global_Error_Handler();

return RES_ERROR;

}

if (sdErr != 0) {

// this is where i end up because my DMA error handler is called

DebugSDCode(sdErr);

return RES_ERROR;

}

// at this point it is of course a success

...

This is my DMA error handler which gets called

void HAL_SD_ErrorCallback(SD_HandleTypeDef* hsd)

{

sdErr = hsd->ErrorCode;

}

and my read complete which doesnt

void BSP_SD_ReadCpltCallback(void)

{

readStatus = 1;

}

At this point i will take any hints anyone might have.

If I have missed anything you might need to see please just ask.

2 REPLIES 2
KWest.1
Associate II

Is it possible this problem could be caused by trying to use memory that is not in AXI memory? Ie AHB memory? I have moved the memory buffer i am reading/writing through to AXI ram and the underrun has disappeared.

So on to my second question. I am calling the FATFS functions from FreeRTOS tasks ... but of course the DMA takes time so i am thinking i should block and yield until the DMA completes and then release the task from the interrupt completion callback. So I build it that way and try it but it fails because my interrupt priority is set to 1 and and FreeRTOS requires anything calling FreeRTOS functions to be priority 5 or higher. No problem ... change the interrupt priority to 5 will solve that ... but when i do the interrupt never fires and my task waiting for the isr to release it times out.

What i dont understand is is there a priority you have to use with SDMMC and if so can I make it compatible with FreeRTOS?

KWest.1
Associate II

A further point I see an article on a different processor saying the SDMMC interrupt priority has to be higher than the DMA priority ... which is all well and good but how do i set the DMA priority seeing as it seems to be internally defined.