This post describes simple steps to make the STM32H7 work with SDCARD. I have used STM32Cube to set up the BSP for the project. It uses the library FatFS as its FAT files system at the top of the driver level. The firmware for drivers is also taken from the STM32Cube.
Emphasis for SDCARD setup
-
Select external transceiver to “yes” if the board has one. External transceivers are translating between 1.8V to 2.9V. For example, refer to TXS0206-29 and IP4856CX25_CZ.
-
The frequency of input clock to SDCARD should be at least lower three times than the AXI bus frequency, refer to RM0433 page 2431 (55.5.8).
-
It has to select the SDCARD detection pin on the FATFS configuration. Then, it has to configure the pin “Card Detection” as an input pin and ensure that it is wired correctly in the board to allow card insertion sense.
-
The FATFS is used without FreeRTOS functions. And the IRQ priority of the SDCARD is below the timer of the FreeRTOS. Otherwise, in high SDCARD frequency, the FreeRTOS is crashing (I set the SDCARD to maximum possible frequency 75MHz and the AXI bus to 240MHz).
-
The external transceiver, if it exists, has to be:
- power enabled
- The selection output between 1.8V and 2.9V has to be according to the Hardware design conditions.
FATFS
Here is a simple function to test file writing on SDCARD.
void WriteFile(char const* filename, char* buffer, size_t size)
{
FIL file;
FATFS fs;
UINT bw;
FRESULT fr;
fr = f_mount(&fs, "0:/", 3);
fr = f_open(&file, fileName, FA_WRITE | FA_CREATE_ALWAYS);
fr = f_write(&file, buffer, size, &bw);
fr = f_close(&file);
}
...
WriteFile("0:/test.txt", "hello", 5);
Cache
When working with enabled cache, the FATFS library will fail to work with SDCARD. So it has to make some changes to adapt it to work with the cache memory. In addition, the SDMMC1 controller of the STM32H743 has an internal DMA. Usually, working with cache and DMA requires a cache memory invalidate operation before reading the new data. That’s because DMA is not behind a cache memory, and after writing data using DMA, the data in the CPU’s cache is not relevant anymore. So to handle the problem in the STM32H743, I did the following:
- In the file, sd_diskio.c, enable the following definition:
#define ENABLE_SD_DMA_CACHE_MAINTENANCE 1
#define ENABLE_SCRATCH_BUFFER
Note that sd_diskio.c, s given by the CubeMX, which is specific for each architecture. This particular version for the STM32H743 supports the cache memory operation, and the definition above will enable it.
- I changed the win element in the struct FATFS to be a pointer to char array. In addition, accoring to cache memory requirements, the char array is allocated to be 32 bytes aligned.
static BYTE buffer[1024] __attribute__ ((aligned (32)));
I took a space of 512 to be on the safe side that invalidates cache operation won’t harm another data outside that array. To set the array in the new FATFS struct type:
FATFS fs
fs.win = buffer
References
[1] Getting started with STM32H7 Series SDMMC host controller
[2] FatFS and cache
[3] Cache Alignment
[4] Cache && DMA on STM32H7