AnsweredAssumed Answered

How to enable DMA mode to transfer data using SDIO

Question asked by mao on May 26, 2017
Latest reply on Jul 21, 2017 by Radek R



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 as BSP_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 */
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 4, 0);
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 4, 0);
/* 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;
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;


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;
return MSD_OK;