Skip to main content
Yaroslav Kirillov
Associate II
August 3, 2017
Question

STM32L4 DMA read write multiple blocks problem

  • August 3, 2017
  • 12 replies
  • 3077 views

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.

This topic has been closed for replies.

12 replies

Tesla DeLorean
Guru
August 3, 2017
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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
Yaroslav Kirillov
Associate II
August 3, 2017
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? 

Tesla DeLorean
Guru
August 3, 2017
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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
Poonam Deoghare
Associate II
March 23, 2018
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

Tesla DeLorean
Guru
March 23, 2018
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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
Poonam Deoghare
Associate II
March 26, 2018
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);

    }
Nikolay Brinken
Associate III
March 29, 2018
Posted on March 29, 2018 at 11:22

After invoked 

__SDMMC_DMA_DISABLE(SDMMC1);

I test is SD busy

while(!LL_GPIO_IsInputPinSet(GPIOC, LL_GPIO_PIN_8)){};

where port C pin 8 - SD data 0 pin