cancel
Showing results for 
Search instead for 
Did you mean: 

FatFS on SDMMC not working with DMA on STM32L4A6ZGT6U

CKugl.1
Senior II

I'm on STM32CubeIDE Version: 1.9.0 Build: 12015_20220302_0855 (UTC), MCU STM32L4A6ZGTx, Firmware STM32Cube FW_L4 V1.17.1. I'm using a NUCLEO-L4A6ZG.

I'm trying to get FatFS working on SDMMC, with DMA, and having problems.

First, the bundled version of FatFS seems to be ancient. It is so old that it doesn't resemble the documented API at http://elm-chan.org/fsw/ff/00index_e.html. Is there a way I can update it such that my changes won't be wiped out each time I run or update the Device Configuration tool?

The big problem is that it won't work if I select "Use dma template" in Device Configuration Tool/Pinout & Configuration/FATFS/Advanced Settings. If I disable "Use dma template", it works OK (with polling).

With DMA enabled, it gets hung up here:

SD_write() at sd_diskio.c:351 0x80081c8

disk_write() at diskio.c:104 0x800837c

f_mkfs() at ff.c:5,661 0x8008af0

test() at test.c:23 0x80011fc

main() at main.c:103 0x8000914

where I see

if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
                              (uint32_t)(sector),
                              count) == MSD_OK)
    {
      /* Wait that writing process is completed or a timeout occurs */
 
      timeout = HAL_GetTick();
      while((WriteStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))
      {
      }
      /* in case of a timeout return error */
      if (WriteStatus == 0)
      {
        res = RES_ERROR;
      }

(SD_write() at sd_diskio.c:351 is line 8 in the snippet).

Apparently, it is waiting for BSP_SD_WriteCpltCallback (or HAL_SD_TxCpltCallback, HAL_SD_IRQHandler, SDMMC1_IRQHandler) which is never called:

void BSP_SD_WriteCpltCallback(void)
{
 
  WriteStatus = 1;
}

At this point, if I look at hsd1, I see:

Instance SDMMC_TypeDef * 0x40012800 (Hex)

POWER volatile uint32_t 0x3 (Hex)

CLKCR volatile uint32_t 0x4900 (Hex)

ARG volatile uint32_t 0x3f (Hex)

CMD volatile uint32_t 0x458 (Hex)

RESPCMD const volatile uint32_t 0x18 (Hex)

RESP1 const volatile uint32_t 0x900 (Hex)

RESP2 const volatile uint32_t 0x5b590000 (Hex)

RESP3 const volatile uint32_t 0x76b27f80 (Hex)

RESP4 const volatile uint32_t 0xa404012 (Hex)

DTIMER volatile uint32_t 0xffffffff (Hex)

DLEN volatile uint32_t 0x200 (Hex)

DCTRL volatile uint32_t 0x99 (Hex)

DCOUNT const volatile uint32_t 0x200 (Hex)

STA const volatile uint32_t 0x145000 (Hex)

ICR volatile uint32_t 0x0 (Hex)

MASK volatile uint32_t 0x1a (Hex)

RESERVED0 uint32_t [2] 0x40012840 (Hex)

FIFOCNT const volatile uint32_t 0x80 (Hex)

RESERVED1 uint32_t [13] 0x4001284c (Hex)

FIFO volatile uint32_t 0x4d90feeb (Hex)

I find it interesting that the MASK is Binary:11010, so only bits 1, 3, and 4 are set, which are:

  • Bit 1 DCRCFAILIE: Data CRC fail interrupt enable
  • Bit 3 DTIMEOUTIE: Data timeout interrupt enable
  • Bit 4 TXUNDERRIE: Tx FIFO underrun error interrupt enable

so this list does not include Bit 8 DATAENDIE: Data end interrupt enable.

STA is Binary:101000101000000000000, which is bits 12, 14, 18, and 20:

  • Bit 20 TXDAVL: Data available in transmit FIFO
  • Bit 18 TXFIFOE: Transmit FIFO empty
  • Bit 14 TXFIFOHE: Transmit FIFO half empty: at least 8 words can be written into the FIFO
  • Bit 12 TXACT: Data transmit in progress

It's trying to send a 512 byte block:

  • DLEN volatile uint32_t 0x200 (Hex)
  • DCOUNT const volatile uint32_t 0x200 (Hex)

Since DCOUNT has not decremented, it looks like no data has been transferred.

What could be the problem?

I put the project on GitHub: https://github.com/carlk3/STM32L4A6ZGTx_SDMMC. It should be complete enough to build. (Is that the best way to share code here? It's fairly painless with EGit: the Git integration for Eclipse).

40 REPLIES 40