cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 DMA read write multiple blocks problem

Yaroslav Kirillov
Associate II

Posted on August 03, 2017 at 12:36

I have a problem with DMA mode reading multiple blocks.

To simplify a problem i took an example from the

STM32Cube_FW_

L4_V1.8.0\Projects\STM32L476G_

EVAL\Applications\FatFs\FatFs_

uSD\ archive.

BSP_SD_ReadBlocks_DMA

is used.

Read blocks not worked good, it started to work after i separated rx and tx and added Init and Deinitto DMA each time that i use that channel.

The problem is witha write now. I can write only blocks that are less then 1k. from 1k to 4096 sometimes it can write and sometimes

f_writereturn 0x

It always fails to write blocks bigger then 4096, bsp_write_blocks always fails with MSD_ERROR .

The problem only in DMA mode, polling mode works great.

Note: this post was migrated and contained many threaded conversations, some content may be missing.

12 REPLIES 12
Posted on August 03, 2017 at 14:18

With write using SDIO+DMA, one problem is that the DMA completes long before the SDIO FIFO clears, so using the DMA TC as a completion indicator is problematic. So after confirming DMA TC signals, you then need to watch the FIFO depth zero out.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Yaroslav Kirillov
Associate II
Posted on August 03, 2017 at 15:36

Thank you for your fast reply. 

Do you know which function should we use to check the FIFO empty state? 

Posted on August 03, 2017 at 17:11

It will be the SDMMC_FIFOCNT register, you'll need to grep the library source to see how that is exposed/wrapped.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Poonam Deoghare
Associate III
Posted on March 23, 2018 at 13:01

Hi,

Even I am facing problem when trying to read/write in DMA mode.

Rewritten call back functions in my c file and checking the card status also.

I am working on f4 disco EVAL.

Kirillov.Yaroslav

please let me know if you got read/write DMA working with one and multiple blocks.

Thanks,

Poonam

Posted on March 23, 2018 at 13:34

He's using an L4, not an F4

STM32Cube_FW_F4_V1.19.0\Projects\STM32446E_EVAL\Applications\FatFs\FatFs_uSD_RTOS\Src\sd_diskio_dma.c

SDIO+DMA is workable on a number of F4 platforms

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 26, 2018 at 09:09

Hi Clive,

You are right that SDIO+DMA is workable on a number of F4 platforms but I have following issue.

When I read/write single block in DMA mode without file system , it is working fine.

But When I am writing/ reading multiple blocks (1000) blocks in loop , I am not sure what exactly is happening.

I am writing and trying to read same data in  buffer. That buffer (Rx), when I print, it is empty.

while(i++ < 1000)

    {

        txDone =  1;

        //printf(' Write_addr is 0x%x \n' ,addr);    

        HAL_SD_WriteBlocks_DMA(&hsd, Tx, addr, 1);

        while(txDone == 0 ){}   //it will be set in call back function                 

        while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER){}    

        addr += 0x200;

    }

while(i++ < 1000)

    {        

        rxDone = 1;        

        HAL_SD_ReadBlocks_DMA(&hsd, Rx, read_addr, 1);

        while(rxDone == 0 ){}       // it will be set in callback function

        while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER){}            

        read_addr += 0x200;        

        printf('RX is %s \n', Rx);

    }
Posted on March 26, 2018 at 14:46

How is rxDone/txDone going to work here? Apt to immediately drop through.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 26, 2018 at 15:10

Hi Clive,

Following are my callback functions where I am using these rxDone/txDone.

void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)

{

    if (hsd->Instance==SDIO)

  {

        txDone = 0;

    }

}

void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)

{

    if (hsd->Instance==SDIO)

  {

    rxDone = 0;

    }

}

Also,

I am able to write 1000- blocks with DMA write by adding following lines of code in HAL_SD_WriteBlocks_DMA()

/* Clear all the static flags */

    __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);   

    hsd->State = HAL_SD_STATE_READY;

Have also added these lines of code in HAL_SD_ReadBlocks_DMA(),  but its working only in debug mode.

Working on HAL_SD_ReadBlocks_DMA () to read multiple blocks.

Thanks.

Posted on March 26, 2018 at 16:17

The logic is broken.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..