Skip to main content
Graduate
August 23, 2022
Question

FATFS + SDMMC, internal eMMC on STM32745I-DISCO doesn't work

  • August 23, 2022
  • 1 reply
  • 1103 views

I configured SDMMC1 as follows:

hmmc1.Instance = SDMMC1;
hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hmmc1.Init.BusWide = SDMMC_BUS_WIDE_8B;
hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hmmc1.Init.ClockDiv = 1;

Here's my FATFS configuration:

#define _FS_READONLY 0
#define _FS_MINIMIZE 0
#define _USE_STRFUNC 2
#define _USE_FIND 1
#define _USE_MKFS 1
#define _USE_FASTSEEK 1
#define	_USE_EXPAND		 1
#define _USE_CHMOD		 1
#define _USE_LABEL 1
#define _USE_FORWARD 1
#define _CODE_PAGE 852
#define _USE_LFN 2 
#define _MAX_LFN 255 
#define _LFN_UNICODE 0 
#define _STRF_ENCODE 3
#define _FS_RPATH 0
#define _VOLUMES 2
#define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
#define _MULTI_PARTITION 1
#define _MIN_SS 512
#define _MAX_SS 512
#define	_USE_TRIM 1
#define _FS_NOFSINFO 0
#define _FS_TINY 1
#define _FS_EXFAT	 1
#define _FS_NORTC	 0
#define _NORTC_MON	 6
#define _NORTC_MDA	 4
#define _NORTC_YEAR	 2015
#define _FS_LOCK 2 
#define _FS_REENTRANT 1
#define _USE_MUTEX 1
#define _FS_TIMEOUT 1000
#define _SYNC_t osMutexId_t

When I try to execute f_disk on the chip, i get F_DISK_ERR.

My test:

void formatMMC()
{
 debug("Formatting MMC...");
 osDelay(20);
 static TCHAR workBuffer[_MIN_SS];
 DWORD plist[] = { 100, 0 };
 FRESULT fr = f_fdisk(retMMC, plist, workBuffer);
 fr = f_mkfs(MMCPath, FM_ANY, 0, workBuffer, sizeof(workBuffer));
 if (fr == FR_OK)
 debug("eMMC formatted successfully.");
 else
 debug("ERROR: eMMC f_mkfs().");
}

And here's the f_disk code until the line that fails:

FRESULT f_fdisk (
	BYTE pdrv,			/* Physical drive number */
	const DWORD* szt,	/* Pointer to the size table for each partitions */
	void* work			/* Pointer to the working buffer */
)
{
	UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl;
	BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
	DSTATUS stat;
	DWORD sz_disk, sz_part, s_part;
 
 
	stat = disk_initialize(pdrv);
	if (stat & STA_NOINIT) return FR_NOT_READY;
	if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
	if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR;

As you can see, GET_SECTOR_COUNT fails.

But anyway, I try to use just f_mkfs and...

...
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) return FR_DISK_ERR;

Again, GET_SECTOR_COUNT fails.

Of course I tried to disable multi partition feature from FATFS. Doesn't help either.

I also tried using different clock dividers, from 0 to 8. For 0 and 8 initialization fails, for values from 1 to 7 it passes and the code fails as described.

UPDATE:

Multi partition feature disabled, I traced where exactly f_mkfs() fails. Here:

 /* Get error state */
 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
 {
 /* Clear all the static flags */
 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
 hmmc->State = HAL_MMC_STATE_READY;
 return HAL_ERROR;
 }
 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
 {
 /* Clear all the static flags */
 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
 hmmc->State = HAL_MMC_STATE_READY;
 return HAL_ERROR;
 }
 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
 {
 /* Clear all the static flags */
 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
 hmmc->State = HAL_MMC_STATE_READY;
 return HAL_ERROR;
 }

It's stm32h7xx_hal_mmc.c file.

But why it that?

What else can I do?

    This topic has been closed for replies.

    1 reply

    Graduate II
    August 23, 2022

    I have definitely had this board working. Will look for the built demo later.

    Pretty sure polling will not work due to speed/bandwidth on the STM32 side.

    Would start with the application examples under CubeH7 trees

    HTDAuthor
    Graduate
    August 24, 2022

    I changed the clock for MMC to 25MHz and it passes through that point, but fails on next writes. It actually does a lot of writing without errors, but eventually fails every time. I also tried to change mmc_diskio.c to use BSP_MMC_WriteBlocks_DMA() instead of BSP_MMC_WriteBlocks(). Of course it didn't work.