HAL Library 20- FATFS for STM32Fxxx
FATFS library (HAL LIB 20) is a “generic” library for all FAT related implementations, such as SDCARD, USB FLASH, SPI FLASH and also SDRAM can be used with proper FAT initialization.
My FATFS library currently supports only SDCARD communication with SDIO (STM32F4xx) or SDMMC (STM32F7xx) or SPI on both families. There is no big difference between them and you can treat them as the same peripheral with only different name.
In case you are interested for FATFS based on STD libraries for F4xx series, check here.
Library
Features
- Interface to SDCARD using FATFS by Chan, version 0.11
- Use SDIO for communication
- Use SPI for communication
- Support for CARD DETECT pin
- Interface with USB MSC HOST
- Interface with SDRAM (Coming)
Dependencies
- HAL
- TM
- STM32Fxxx HAL
- defines.h
- FATFS
- TM SPI when SPI is used as SDCARD interface
- TM DELAY when SPI is used as SDCARD interface
- TM GPIO
FATFS
First a little bit about FATFS library and its configuration. I’ve reconfigure some of default settings for FATFS, which can be set in ffconf.h file for fatfs. Main changes are these:
- Dynamic allocation is used when new file should be created. You need at least 512 bytes of free memory in HEAP region for malloc to allocate data, otherwise, f_open function will return FR_NOT_ENOUGH_CORE result. You can force FATFS to use static buffer for all files (not thread safe) or to use stack for files, but you have to increase stack to allow that or you will have stack overflow. Settings can be changed in ffconf.f file from FATFS library.
- Instead of numbers for logical drivers (which will come in future with USB and other settings), I’ve configured FATFS in settings for nice logical drives name. So, instead of mount SDCARD with
- f_mount(&fatfs, “0:”, 1), you can do it now with
- f_mount(&fatfs, “SD:“, 1), which increases transparency between multiple FATFS related low level devices. Other implementations are listed below.
- For USB MSC: f_mount(&fatfs, “USBHS:“, 1); for USB HOST in HS mode.
- For USB MSC: f_mount(&fatfs, “USBFS:“, 1); for USB HOST in FS mode.
- For SDRAM: f_mount(&fatfs, “SDRAM:”, 1); for SDRAM implementation. This option does not work yet.
- Check example for more info how to use this aliases.
SDCARD
Library supports 2 modes of communication with SDCARD. First, which is faster and better is SDIO/SDMMC, or second, slower communication with SPI. You can see default pinouts in table below for SDCARD.
NR | SDIO Interface | SPI Interface | |||||
---|---|---|---|---|---|---|---|
Name | STM32Fxxx | Description | Name | STM32Fxxx | Description | ||
4-bit | 1-bit | ||||||
1 | CD/DAT3 | PC11 | Connector data line 3 | CS | PB5 | Chip select for SPI | |
2 | CMD | PD2 | PD2 | Command/Response line | MOSI | PA7 | Data input for SPI |
3 | VSS1 | GND | GND | GND | VSS1 | GND | GND |
4 | VDD | 3.3V | 3.3V | 3.3V Power supply | VDD | 3.3V | 3.3V Power supply |
5 | CLK | PC12 | PC12 | Clock | SCK | PA5 | Clock for SPI |
6 | VSS2 | GND | GND | GND | VSS2 | GND | GND |
7 | DAT0 | PC8 | PC8 | Connector data line 0 | MISO | PA6 | Data output for SPI |
8 | DAT1 | PC9 | Connector data line 1 | ||||
9 | DAT2 | PC10 | Connector data line 2 |
There is also CARD detect pin on SDCARD connector if you use it. By default, this feature is disabled in library, but can easily be enabled. In case, you want CARD DETECT pin in your project, you can open defines.h file and define your settings for CARD DETECT pin. Default CD pin is PB6 when pin is active, but can easily be changed.
1 2 3 4 5 6 |
/* Enable Card detect pin */ #define FATFS_USE_DETECT_PIN 1 /* Overwrite default CARD DETECT pin */ #define FATFS_DETECT_PORT GPIOB #define FATFS_DETECT_PIN GPIO_PIN_6 |
SDIO/SDMMC implementation
Default SDCARD communication is SDIO/SDMMC and is automatically enabled if settings are not overwritten. For getting SDIO/SDMMC properly to work, you have to add these files in your project.
1 2 3 4 5 6 7 8 9 10 11 12 |
- tm_stm32_fatfs.h - tm_stm32_fatfs.c - fatfs/ff.h - fatfs/ff.c - fatfs/diskio.h - fatfs/diskio.c - fatfs/ffconf.h - fatfs/integer.h - fatfs/option/syscall.c - fatfs/option/unicode.c - fatfs/drivers/fatfs_sd_sdio.h - fatfs/drivers/fatfs_sd_sdio.c |
Default mode for SDIO/SDMMC is 4-bit mode, but in case you want to save some GPIO pins, you can use 1-bit also. For configuration, open defines.h file and add/edit settings you need.
1 2 |
/* Enable SDIO/SDMMC with 1-bit communication */ #define FATFS_SDIO_4BIT 0 |
SPI implementation
If you need (for come case) SPI implementation instead of SDIO (I don’t prefer SPI when SDIO can be used), you have to manually enable SPI for FATFS. To do this, open defines.h file and add following lines.
1 2 3 4 5 6 7 8 9 10 |
/* Enable SPI communication, disable SDIO/SDMMC */ #define FATFS_USE_SDIO 0 /* Overwrite default SPI settings if needed */ #define FATFS_SPI SPI1 #define FATFS_SPI_PINSPACK TM_SPI_PinsPack_1 /* Set your CS pin for SPI */ #define FATFS_CS_PORT GPIOB #define FATFS_CS_PIN GPIO_PIN_5 |
To get SPI into working state, you will have to add these files into project.
1 2 3 4 5 6 7 8 9 10 11 12 |
- tm_stm32_fatfs.h - tm_stm32_fatfs.c - fatfs/ff.h - fatfs/ff.c - fatfs/diskio.h - fatfs/diskio.c - fatfs/ffconf.h - fatfs/integer.h - fatfs/option/syscall.c - fatfs/option/unicode.c - fatfs/drivers/fatfs_sd.h - fatfs/drivers/fatfs_sd.c |
USB MSC HOST
USB MSC Host is also supported with FATFS. The 2 things are there you need to know in order to use FATFS with MSC host:
- You need to add low_level driver, from fatfs/drivers folder, driver is fatfs_usb.c
- Check examples for USB MSC Host on Github to see how to use it when you have HS mode and when you have FS mode.
Note: if you won’t include low level driver file, you will not get any compile errors, because I have defined functions for low-level driver with __weak parameter. You will just always get errors from FATFS related functions.
To run USB MSC Host, you will also need my USB library with HOST stack.
SDRAM
Not in working state yet. Coming soon!
SPI FLASH
Not in working state yet. Coming soon!
Functions and enumerations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
/** * @brief FATFS size structure */ typedef struct { uint32_t Total; /*!< Total size of memory */ uint32_t Free; /*!< Free size of memory */ } TM_FATFS_Size_t; /** * @} */ /** * @defgroup TM_FATFS_Functions * @brief Library Functions * @{ */ /** * @brief Gets total and free memory sizes of any drive * @param *str: Pointer to string for drive to be checked * @param *SizeStruct: Pointer to empty @ref TM_FATFS_Size_t structure to store data about memory * @retval FRESULT structure members. If data are valid, FR_OK is returned * @example Get memory sizes of USB device: * TM_FATFS_GetDriveSize("USB:", &SizeStruct); */ FRESULT TM_FATFS_GetDriveSize(char* str, TM_FATFS_Size_t* SizeStruct); /** * @brief Truncates beginning of file * * Example: * - You have a file, its content is: "abcdefghijklmnoprstuvwxyz", * - You want to truncate first 5 bytes, * - Call @ref TM_FATFS_TruncateBeginning(&opened_file, 5); * - You will get new file data: "fghijklmnoprstuvwxyz" * @param *fil: Pointer to already opened file * @param index: Number of characters that will be truncated from beginning * @note If index is more than file size, everything will be truncated, but file will not be deleted * @retval FRESULT struct members. If everything ok, FR_OK is returned */ FRESULT TM_FATFS_TruncateBeginning(FIL* fil, uint32_t index); /** * @brief Checks card detect pin (if activated) if card is inserted * @note Pin must be set low in order to get card inserted, otherwise card is not inserted * @note Card detect pin must be activated in order to get this functionality to work * @param None * @retval Card detected status: * - 0: Card is not inserted * - > 0: Card is inserted */ uint8_t TM_FATFS_CheckCardDetectPin(void); /** * @} */ |
Example
Example below is basic and shows how to write data to SDCARD. Example was tested with STM32F7-Discovery board and STM32F429-Discovery board and I got expected result!
In this example, default configuration is used, so:
- SDIO/SDMMC interface
- Interface has 4-bit mode
- Card detect pin is disabled
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
/** * Keil project for SDCARD reader using SDIO example * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * @conf PLL parameters are set in "Options for Target" -> "C/C++" -> "Defines" * @packs STM32F4xx/STM32F7xx Keil packs are requred with HAL driver support * @stdperiph STM32F4xx/STM32F7xx HAL drivers required */ /* Include core modules */ #include "stm32fxxx_hal.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32_disco.h" #include "tm_stm32_delay.h" #include "tm_stm32_fatfs.h" #include "tm_stm32_lcd.h" #include "stdio.h" /* Fatfs structure */ FATFS FS; FIL fil; FRESULT fres; /* Size structure for FATFS */ TM_FATFS_Size_t CardSize; /* Buffer variable */ char buffer[100]; int main(void) { /* Init system clock for maximum system speed */ TM_RCC_InitSystem(); /* Init HAL layer */ HAL_Init(); /* Init leds */ TM_DISCO_LedInit(); /* Try to mount card */ if (f_mount(&FS, "SD:", 1) == FR_OK) { /* Try to open file */ if ((fres = f_open(&fil, "SD:first_file.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE)) == FR_OK) { /* Read SDCARD size */ TM_FATFS_GetDriveSize("SD:", &CardSize); /* Format string */ sprintf(buffer, "Total card size: %u kBytes\n", CardSize.Total); /* Write total card size to file */ f_puts(buffer, &fil); /* Format string for free card size */ sprintf(buffer, "Free card size: %u kBytes\n", CardSize.Free); /* Write free card size to file */ f_puts(buffer, &fil); /* Close file */ f_close(&fil); /* Turn led ON */ TM_DISCO_LedOn(LED_ALL); } /* Unmount SDCARD */ f_mount(NULL, "SD:", 1); } /* Do nothing */ while (1) { } } |
Project is available on my Github account, download all libraries below.
STM32 libraries based on STM32Fxxx HAL drivers.
Recent comments