AnsweredAssumed Answered

Need help with STM32F7 SDMMC DMA READ

Question asked by David Harrison on Dec 31, 2016
Latest reply on Mar 31, 2017 by avi_crak.videocrak

Hi, all, I have a STM32F7 Discovery board (chip is STM32F746NGH6 ). I have implemented my own SDMMC layer  (bare metal, no HAL or ported STD peripheral libraries. It is working very nicely using polled mode for SD card reads, but I want to use DMA reads. I cannot get it to work, more specifically it hangs in the SDWaitRead() function after the DMA transfer has been set up. I have established that the SDIO_IRQHandler() and DMA2_Stream3_IRQHandler() interrupt handlers are never being fired so there is some issue with the interrupts.

 

I have attached my code here. And also, for comparison, I have attached my working SDReadBlocksPolled() function as well, so I know my basic SDMMC access technique works well. As an aside you may note that in order to send a Command to the SD card, I have boiled all the superfluous bloated HAL code down to two lines only using direct register access as per this example :

   SDMMC1->ARG = (U32)BLOCK_SIZE;
   SDMMC1->CMD = SDMMC_CMD_SHORT_NOWAIT_NOWAIT_CPSMENABLE(SD_CMD_SET_BLOCKLEN_CMD16);

 

where SDMMC_CMD_SHORT_NOWAIT_NOWAIT_CPSMENABLE is a simple macro thus:

#define SDMMC_CMD_SHORT_NOWAIT_NOWAIT_CPSMENABLE(CMD)  (0x440 | CMD)  // 0b10001000000 | CMD

 

I have similar macros for

#define SDMMC_CMD_NORESP_NOWAIT_NOWAIT_CPSMENABLE(CMD) (0x400 | CMD)  // 0b10000000000 | CMD and

#define SDMMC_CMD_LONG_NOWAIT_NOWAIT_CPSMENABLE(CMD)   (0x4C0 | CMD)  // 0b10011000000 | CMD

 

Similarly I have boiled the Datapath State Machine setting code down to three lines thus:

   // Configure the SD DPSM (Data Path State Machine)
   // Set the SDIO Data TimeOut and DataLength and DCTRL (Data Control) values
   SDMMC1->DTIMER = SD_DATATIMEOUT;
   SDMMC1->DLEN   = NumberOfBlocks * BLOCK_SIZE;
   SDMMC1->DCTRL |= SDMMC_DCTRL_TOSDIO_512_BLOCK_MODE_DTEN;

 

These simple techniques lead to much easier to write and read SDMMC code, in my opinion. I might add that I have the luxury of not being under any deadline, so I can take the time to really understand how the registers work and also don't have to worry about portability, so this coding technique is very efficient, now I have figured it out. And the best part it doesn't depend on the HAL bloatware, or any other libraries.

 

Any help you can give to identify the problems I am having with my DMA version of SDReadBlocks() would be much appreciated. Thanks.

Outcomes