Portenta H7: SD card not working - story - know your system

My SD card function was not working in another sub-system (Pico-C), even it was fine on UART command shell.

FYI:
more like a story to share nothing to ask, nothing to respond.

Also, there was a question: why CM4 cannot do WiFi/BT.
(because the bus fabric does not allow to access CM4 the SDMMC1 needed for it).

I had a similar issue with my SD Card.
It was implemented (in a bare-metal, CubeIDE, plain C-project) as:

unsigned char *PlatformReadFile(const char *FileName)
{
	FIL MyFile;     				/* File object, should not be on stack (DTCM) */
	unsigned char scriptBuf[1024];	/* buffer for the script - size is limited, access-able for DMA! */
	unsigned int numRd;

	if(f_open(&MyFile, FileName, FA_READ) != FR_OK)
		return 0;

	f_read(&MyFile, scriptBuf, 1024 -1, &numRd);
	*(scriptBuf + numRd) = '\0';

	f_close(&MyFile);

	if (numRd)
		return scriptBuf;

	return 0;
}

At the end: it was not working.
I scratched my head - why? Similar code works fine on another place (UART command shell, reading files from SD card), but not here.

Conclusion

  • Know your system! In my case: know where all these memories used are located, e.g. here the local variables MyFile and/or scriptBuf.

  • my stack region (used for local variables as those above) is on DTCM memory (0x20000000).
    I have moved my RTOS stack for threads to DTCM.

  • It cannot work: I provide MyFile on DTCM and also the buffer where the SD Card read command should place the result (data read from SD card) on DTCM memory.

What I have seen: my SD card read command, here done via f_read(...); ended up in a timeout. The SD card operation has not finished, the BSP functions have timed out.

Why?
Pretty obvious at the end:
The SD Card should use a file descriptor MyFile and also a buffer scriptBuf which are both located on DTCM RAM (0x20000000), via my linker script.
But the SDMMC2 (used here) cannot access DTCM. There is not a bus fabric path for DMA (or SDMMC DMA) to read or write this memory.
The DMA needed for SDMMC2 could not access my local variables (DTCM not access-able).

So, the DMA hang and has timed out because of the involved memories were not access-able by SDMMC2 interface/peripheral.

Solution
After I came up with idea: "the memories involved here are not access-able for SDMMC2" and I have changed to use dynamic memories (from my MEM_Pool) where another memory (RAM D1 or D2) is used (not DTCM) - all was fine.

So, "know your system" : which memories are used, is it possible to transfer data to/from it?(here via DMA), what is the bus matrix for this data path (and can it work)?
You need still a bit of understanding of the system, details from datasheet. If something does not work, potentially it is due to fact that you try something which is not possible by the hardware (and software does not tell you).

In my case: pretty obvious at the end: I tried to let a DMA transfer data where the path to/from the memory is not available (for the DMA engine itself). But there are no errors on API, nobody tells you on comments in source code - it just hang.
But checking again the datasheet, to think which resources (memories) are used and where they are located helped me to fix my issue.

Final Conclusion
Programming Portenta H7 even with a high level API (Arduino, mbed), does not mean: you do not need to understand the chip, you would never need the datasheet, you do not need any system overview knowledge.
If you divert like me a bit from the "intended path how to use" of the API - it can be broken.

Unfortunately, Arduino does not provide Full Source Code, so, you are a bit lost why it does not work.

Therefore, I prefer to go only with a project as Full Source Code (here my own CubeIDE project, with all lines of code involved with full visibility - a really Open Source project).
If such a case happens, a function does not work as expected - I can check the memory locations, the datasheet and make sure this data path can work.
But modifying anything on a system where I do not have full control, I am not able to see really all lines of code involved (not really an Open Source system) - it makes it almost impossible to understand the system and to fix issue (without help from the provider, Arduino, which I have never seen responding really to issues).

As a system engineer I like to understand the entire system. Open Source is the key!

I could fix my issue because I could understand the entire system and I have full control over any single line of code.
But imagine, you use a system where part of it is disclosed, at least not provided all as Open Source code. It would be a nightmare for me, esp. not knowing whom to blame. How much can I trust a "closed system"? Is the "black-box code" designed and intended for my use case ...?

Please, Arduino team: go really fully Open Source, and respond more actively on your established forums. Be pro-active instead to let users figure out what (and why - tough) is not working.
If Portenta H7 is promised as "professional platform" - Arduino, please act in a professional way (esp. for professional users).
Sorry.

Good bye to the forum and "good bye" Arduino.

1 Like

Those access questions are solved within the MDMA datasheet from STM32 , typical method is DMA forma memory or peripheral to SRAM and MDMA from SRAM to ITCM/DTCM (access table below).

"hmmm", MDMA can transfer data to/from TCMs, but the issue was here: there is no path on bus fabric to transfer data from SDMMC1 by CM4 (the slave MCU, sure: the CM7 master MCU can).

Check the next page in the same manual: you will see: "CM4 does not have access to SDMMC1". Right?

Sure, even the DMA, MDMA could be kicked-off by CM7 but CM4 CANNOT configure SDMMC1!
So, it looks like: CM4 could setup a DMA data path but it cannot configure SDMMC1 and launch a data transfer.

I still take it as: "CM4 cannot use SDMMC1"