Skip to main content
Visitor II
May 26, 2017
Solved

How to enable DMA mode to transfer data using SDIO

  • May 26, 2017
  • 3 replies
  • 1925 views
Posted on May 26, 2017 at 06:18

Hello,

I am using STM32F411RET6 chip to access uSD card with SDIO 4bit. By default it uses polling mode to read/write data with SDIO, such asBSP_SD_ReadBlocks().

The problem is that I want to continuously write 128k bytes data to uSD at a time. Writing is often interrupted by other timers, which causes the failure of the writing. After timers are disabled, the writing is successful without problem.

I guess DMA mode wouldn't be interrupted by the timers.

In order to use DMA, i generate code using cubemx.MX_DMA_Init() has been defined and called at the beginning of main().

in hal_map.c, the DMA has been initialized.

If I simply replace HAL_SD_WriteBlocks

with HAL_SD_WriteBlocks_DMA, it doesn't work at all.

How to enable to use the DMA?

/** 
 * Enable DMA controller clock
 */
void MX_DMA_Init(void) 
{
 /* DMA controller clock enable */
 __DMA2_CLK_ENABLE();
/* DMA interrupt init */
 HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 4, 0);
 HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
 HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 4, 0);
 HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
}�?�?�?�?�?�?�?�?�?�?�?�?�?
/* Peripheral DMA init*/
 hdma_sdio_rx.Instance = DMA2_Stream3;
 hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4;
 hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
 hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
 hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
 hdma_sdio_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
 hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
 hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
 hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
 hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4;
 HAL_DMA_Init(&hdma_sdio_rx);
__HAL_LINKDMA(hsd,hdmarx,hdma_sdio_rx);
hdma_sdio_tx.Instance = DMA2_Stream6;
 hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4;
 hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
 hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE;
 hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
 hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
 hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
 hdma_sdio_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
 hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
 hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
 hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
 hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
 HAL_DMA_Init(&hdma_sdio_tx);
__HAL_LINKDMA(hsd,hdmatx,hdma_sdio_tx);�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
{
 if(HAL_SD_WriteBlocks(&hsd, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK) 
 {
 return MSD_ERROR;
 }
 else
 {
 return MSD_OK;
 }
}�?�?�?�?�?�?�?�?�?�?�?

#microsd #stm32f411-dma #sdio
    This topic has been closed for replies.
    Best answer by Radek RIPA
    Posted on July 21, 2017 at 14:57

    Please check this topic:

    https://community.st.com/0D50X00009bMM7JSAW

    Best regards

    Radek

    3 replies

    Technical Moderator
    May 26, 2017
    Posted on May 26, 2017 at 19:01

    Hi

    mao.rongwei

    ‌,

    Could you please share your .ioc file? I would like to check the issue with same settings as what you have.

    -Amel

    rwmaoAuthor
    Visitor II
    May 26, 2017
    ST Employee
    July 21, 2017
    Posted on July 21, 2017 at 14:57

    Please check this topic:

    https://community.st.com/0D50X00009bMM7JSAW

    Best regards

    Radek

    April 13, 2024

    Could you explain in few words, what is the problem, because I've got same issue, but for some reason don't have access to the link provided.