cancel
Showing results for 
Search instead for 
Did you mean: 

f_mount fails using STM32L4 w/ SDMMC

Forest L
Associate III
Posted on July 13, 2018 at 16:44

I'm having a lot of difficulty getting FatFS working with SDMMC on my STM32L476 (RG-Nucleo) board. I'm working from code generated by CubeMX and have followed a number of forum posts suggesting alterations to get SDMMC working -- for instance, 

https://community.st.com/message/203639-sdmmc-on-stm32-l476-l4

 . Currently I'm getting an infinite loop when calling f_mount which I can trace back to

stm32l4xx_hal_sd.c:

while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))

{

This loop goes on infinitely -- it seems none of these flags are being set? What are some likely causes of this problem?

#hal #sdmmc #f_mount #stm32l4+ #fatfs
16 REPLIES 16
Posted on July 13, 2018 at 18:03

>> I'm working from code generated by CubeMX..

You need to stop doing that, the monkey inside is broken.

0690X0000060MAtQAM.jpg

I'll rebuild the demo in a minute.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 13, 2018 at 20:27

Thanks for the picture -- it seems our wiring is identical. 

Sadly I have 4-5 other peripherals that need configuration for my project so Cube seems like the path of least resistance. 

:(

I've tried adapting ST's non-Cube HAL example (for L476G, which has an onboard SD slot), but maybe I ought to try harder. So far, however, it seems I just can't get it working even without Cube.

If it's of note, I believe the one 'good' flag above is FLAG_DBCKEND, meaning a data block was received and the corresponding CRC passed. It hangs here until the timeout is reached, returning HAL_SD_ERROR_TIMEOUT. It's not failing the CRC either, so the data just isn't being received.

Posted on July 13, 2018 at 20:29

For attachment see Thread View

Outputs to VCP an 115200 8N1

________________

Attachments :

STM32L476RG_NUCLEO_TEST_SDMMC_001.hex.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HxQN&d=%2Fa%2F0X0000000axr%2F7.HYhfwPlWUXgEcqPQPVbRgwq_3Sz_u4rb_Sdr7on1E&asPdf=false
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 13, 2018 at 21:56

Thanks, that executable does seem to work, so at least it's not a hardware issue. Since you didn't use Cube, what was the basis of your program? The HAL example?

electronic tobi
Associate II
electronic tobi
Associate II

before stm locked the forum you wrote that it doesn't work and you get not_ready

this is because stm is inconsistent with the bsp files, in some files the bsp check if card detect is high, in some files it check if card detect is low.

So when you get not ready, you must change the line somewhere in sd init

Forest L
Associate III

Oh, I didn't realize this post got re-uploaded yet. Thanks, I'll try that.

EDIT: I can confirm you're on to something. For future readers, the issue is in bsp_driver_sd.c and bsp_driver_sd.h. I believe I already corrected the definitions to be consistent. The error comes where I'm checking the card detect pin -- it always reads as disconnected. I'll try tying this to Vcc through a pullup resistor... Can anyone confirm if this is right or if I'm insane?

EDIT 2: I tried the above and it didn't work -- I then just made BSP_SD_IsDetected() always return SD_PRESENT for testing purposes, and at least I get a different error. Now I'm getting FR_DISK_ERR.

This seems to follow from

    while((ReadStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))

in sd_diskio.c. Basically, ReadStatus is never set to 1 so we get a timeout here. Any advice?

EDIT 3: It seems the Cube generated code in sd_diskio.c didn't set a read or write bit for the functions

void BSP_SD_WriteCpltCallback(void)

and

void BSP_SD_ReadCpltCallback(void).

I changed this to set each appropriate bit to 1, and f_mount passes. I'm going to add in the other file operations and see if this fixed everything.

Forest L
Associate III

So, now it's failing on f_write, which returns FR_DISK_ERR. This seems to go back to Middlewares/Third_Party/FatFs/src/ff.c: 1410.

(here line 1= line 1400 in the file.)

Here, cs = 0xFFFFFFFF, which means....

"an error occured" ?

Any advice?

		ncl = scl;	/* Start cluster */
		for (;;) {
			ncl++;							/* Next cluster */
			if (ncl >= fs->n_fatent) {		/* Check wrap-around */
				ncl = 2;
				if (ncl > scl) return 0;	/* No free cluster */
			}
			cs = get_fat(obj, ncl);			/* Get the cluster status */
			if (cs == 0) break;				/* Found a free cluster */
			if (cs == 1 || cs == 0xFFFFFFFF) return cs;	/* An error occurred */
			if (ncl == scl) return 0;		/* No free cluster */
		}

>>Any advice?

Go down toward the failure, not up away from it.

The HAL SDMMC is called via the DISKIO layer. Instrument there to understand the nature of the error before it propagates up in a pass/fail type FR_DISK_ERR, which tells you nothing.

In disk_write() add instrumentation to exit path

 if (res != RES_OK)

   printf("W %5d %2d (%08X)\n", sector, count, uSdHandle.ErrorCode);

Then look a bit/error flags for HAL SDMMC, likely a TIMEOUT or OVERRUN

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..