You are on page 1of 14

Library 21- Read SD card with FatFs

on STM32F4
BY TILZ0R JULY 10, 2014
Finally I got it working properly. Reading SDcard was very awesome
for me for first time, so I decided to make a library for STM32F4xx
devices and post it to my website. Its basically just communication
interface between STM32F4 and FatFS library by Chan. It
supports SPI or SDIO communication. Library also supports USB
communication, but for that purpose you need USB stack too. USB is
available here.
Below Im showing how to setup everything with STM32F4 to get SD
card working with SPI or SDIO communication.

FATFS library can be used everywhere, but really, everywhere, not


just SDCARD or USB flash drive. Ive made an update to use source
for FATFS SDRAM on STM32F429-Discovery or STM32F4x9-EVAL
boards. Click here for more info.
Future updates will include also SPI FLASH (prototoype functions are
added to FATFS library but not implemented yet) and option for user
to add custom functions for FATFS low level.

FatFS Library
If you are interested for FATFS using HAL drivers, check here.

Features
Fatfs by Chan supported, version R0.11
Support for SDIO or SPI interface
SDIO works with 1- or 4-bit mode
Support for Card detect pin
Can be disabled
Support for Write protect pin
Can be disabled
Custom fat time
Enables you to implement your own time using RTC
Updates
Version 1.2 August 29, 2014
Supported for USB devices
Version 1.3 December 06, 2014
FatFs version R0.10C now implemented
Version 1.4 December 29, 2014
Added support for truncate file from beginning
Version 1.5 February 17, 2015
FatFs version R0.11 now implemented
Fixed problem which appers sometime using SDIO

Dependencies
CMSIS
STM32F4xx
STM32F4xx RCC
STM32F4xx GPIO
STM32F4xx SPI (only when SPI)
STM32F4xx DMA (only when SDIO)
STM32F4xx SDIO (only when SDIO)
MISC (only when SDIO)
TM
TM SPI (only when SPI)

TM STM32F4 SPI Library 34995 downloads 6.89 KB

Download
TM DELAY (only when SPI)
TM STM32F4 Delay Library 27840 downloads 10.12 KB

Download
TM GPIO

TM STM32F4 GPIO Library 44067 downloads 4.91 KB

Download
defines.h

defines.h configuration example 93480 downloads 0.70 KB

Download
attributes.h

attributes.h 15337 downloads 0.85 KB


Download
FatFs by Chan (included in library)

Pinout
SDCard pinout

Because different connections are possible, you have different


pinouts. They are in table below:

SDIO Interface SPI Interface

STM32F4x
x

4- 1- Nam STM32F4x
NR Name bit bit Description e x Description

Chip select for


1 CD/DAT3 PC11 Connector data line 3 CS PB5
SPI
Command/Response Data input for
2 CMD PD2 PD2 MOSI PA7
line SPI
3 VSS1 GND GND GND VSS1 GND GND
3.3V Power
4 VDD 3.3V 3.3V 3.3V Power supply VDD 3.3V
supply
5 CLK PC12 PC12 Clock SCK PA5 Clock for SPI
6 VSS2 GND GND GND VSS2 GND GND
Data output for
7 DAT0 PC8 PC8 Connector data line 0 MISO PA6
SPI
8 DAT1 PC9 Connector data line 1
9 DAT2 PC10 Connector data line 2

Card detect and write protect pins are not part of SD card, but part
of SDcard connector. They are listed below, and are same for both
communications:

Name STM32F4xx Description

WP PB7 Write protect pin. Pin low when write is enabled


CD PB6 Card detect pin. Pin low when card detected

By default, both pins are disabled in library. If you want to use them,
you have to enable them in defines.h file
1
2
/* Use detect pin */
3
#define FATFS_USE_DETECT_PIN 1
4
/* Use writeprotect pin */
5
#define FATFS_USE_WRITEPROTECT_PIN 1
6
7
/* If you want to overwrite default CD pin, then change this settings */
8
#define FATFS_USE_DETECT_PIN_PORT GPIOB
9
#define FATFS_USE_DETECT_PIN_PIN GPIO_PIN_6
1
0
/* If you want to overwrite default WP pin, then change this settings */
1
#define FATFS_USE_WRITEPROTECT_PIN_PORT GPIOB
1
#define FATFS_USE_WRITEPROTECT_PIN_PIN GPIO_PIN_7
1
2

SDIO Communication
STM32F4xx has internal SDIO peripheral to work with SD cards. Also,
SDIO communication is faster than SPI, but if you dont need speed
in your project, you can use SPI aswell. With default settings, SDIO
4-bit mode communication is used. It means, that you need all four
data lines. SDIO also supports 1-bit mode, where you need only
Data0, CMD and CLK pins. To activate 1-bit mode, add this to your
defines.h file:

1 /* Activate SDIO 1-bit mode */


2 #define FATFS_SDIO_4BIT 0
3
4 /* Activate SDIO 4-bit mode */
5 #define FATFS_SDIO_4BIT 1
To be able to get SDIO to work, you have to include these files:
tm_stm32f4_fatfs.h
tm_stm32f4_fatfs.c
fatfs/diskio.h
fatfs/diskio.c
fatfs/ff.h
fatfs/ff.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
And also make sure, that you include all STM32F4xx peripherals to
work with. What it needs is described under Dependencies
section.
SPI Communication
If you want to use SPI communication instead of SDIO on STM32F4xx
for any reason, you can do that. To enable SPI communication, open
your defines.h file and set constant

1 /* Use SPI communication with SDCard */


2 #define FATFS_USE_SDIO 0
Now, SPI is activated. Make sure, that you include dependencies
libraries, described in Dependencies section. By default SPI1 is
used with Pinspack 1, but you can set it to your own SPI
(in defines.h file) with

1 /* Select your SPI settings */


2 #define FATFS_SPI SPI1
3 #define FATFS_SPI_PINSPACK TM_SPI_PinsPack_1
Look here to see, which pins are associated with each SPI. For SPI is
also used CS (Chip select) pin. You can leave its settings as it is, or
change it to what you want. You can do this with (in defines.h)

1 /* Custom CS pin for SPI communication */


2 #define FATFS_CS_PORT GPIOB
3 #define FATFS_CS_PIN GPIO_Pin_5
To properly work with SPI communication, you need files below:

tm_stm32f4_fatfs.h
tm_stm32f4_fatfs.c
fatfs/diskio.h
fatfs/diskio.c
fatfs/ff.h
fatfs/ff.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

Fatfs
To work with files, you have to use fatfs library. In order to get it
work properly, you should check its manual here. My library is used
only for behind the scenes settings, to get communication with SD
card properly.
Custom get_fattime() function
Fatfs supports get_fattime() function, which returns time in integer
format. By default get_fattime() returns time 0. That means
1.1.1980 00:00:00 time. If you have any RTC library or you want to
set your own time, then you should set define in defines.h file:

1 //Use custom get_fattime() function


2 #define FATFS_CUSTOM_FATTIME 1
After you set this, you have to create your project function:

1
//Use custom get_fattime function
2
//Implement RTC get time here if you need it
3
DWORD get_fattime (void) {
4
return ((DWORD)(2014 - 1980) << 25) // Year 2014
5
| ((DWORD)7 << 21) // Month 7
6
| ((DWORD)10 << 16) // Mday 10
7
| ((DWORD)16 << 11) // Hour 16
8
| ((DWORD)0 << 5) // Min 0
9
| ((DWORD)0 >> 1); // Sec 0
1
}
0
My libraries for RTC

Internal on STM32F4xx
DS1307 I2C for STM32F4xx

Changelogs
Fixed error for SPI communication

.\FATFS\diskio.c(211): error: #167: argument of type "void *" is incompatible with


1
parameter of type "BYTE" .
My functions
I have also made some additional functions:

TM_FATFS_DriveSize
Get full drive size and free space on your disk
TM_FATFS_TruncateBeginning
Truncate file from beginning

1 /**
2 * Get SD card drive size
3 *
4 * Parameters:
5 * - uint32_t* total:
6 * Pointer to variable to store total size of card
7 * - uint32_t* free:
8 * Pointer to variable to store free space on card
9 *
1 * Returns FRESULT struct members. If data are valid, FR_OK is returned.
0 */
1 FRESULT TM_FATFS_DriveSize(uint32_t* total, uint32_t* free);
1
1 /**
2 * Get SD card drive size
1 *
3 * Parameters:
1 * - uint32_t* total:
4 * Pointer to variable to store total size of card
1 * - uint32_t* free:
5 * Pointer to variable to store free space on card
1 *
6 * Returns FRESULT struct members. If data are valid, FR_OK is returned.
1 */
7 FRESULT TM_FATFS_USBDriveSize(uint32_t* total, uint32_t* free);
1
8 /**
1 * Truncate beginning of file
9 *
2 * Parameters:
0 * - FIL* fil:
2 * Pointer to already opened file
1 * - uint32_t index:
2 * Number of characters that will be truncated from beginning.
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
* If index is more than file size, everything will be truncated, but file will not be
1
deleted
3
*
2
* Example
3
* - You have a file, it's content is: "abcdefghijklmnoprstuvwxyz",
3
* - You want to truncate first 5 bytes,
3
* - Call TM_FATFS_TruncateBeginning(&opened_file, 5);
4
* - You will get new file data: "fghijklmnoprstuvwxyz"
3
*
5
* Returns FRESULT struct members. If everything ok, FR_OK is returned.
3
*/
6
FRESULT TM_FATFS_TruncateBeginning(FIL* fil, uint32_t index);
3
7
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5

What could possibly go wrong?


You know, Murphys law In this section I will add possible

problems and (I hope) how to get it fixed.

Card not recognized by Fatfs


Is your card formatted in FAT16 or FAT32 format?

Example
I have test this example with SPI and SDIO interface. In both cases I
got the same result. I used 2 and 8GB cards in FAT16 format. In
example below, default settings are in use, so:

SDIO interface
Card detect OFF
Write protect OFF
Led status
No leds on: It has not been mounted ok
Check if pinout is correct, also make sure FAT16 is
selected
Only GREEN led on: mounted ok and opened ok, but data
could not be written
Only RED led on: mounted OK, but could not open file
Maybe you have enabled Write protect pin. Disable it
for this example
Both ON: everything OK

Example result with FatFS


1 /**
2 * Keil project example for FATFS
3 *
4 * @author Tilen Majerle
5 * @email tilen@majerle.eu
6 * @website http://stm32f4-discovery.com
7 * @ide Keil uVision 5
8 */
9 #include "defines.h"
1 #include "stm32f4xx.h"
0 #include "tm_stm32f4_delay.h"
1 #include "tm_stm32f4_disco.h"
1 #include "tm_stm32f4_fatfs.h"
1 #include <stdio.h>
2 #include <string.h>
1
3 int main(void) {
1 //Fatfs object
4 FATFS FatFs;
1 //File object
5 FIL fil;
1 //Free and total space
6 uint32_t total, free;
1
7 //Initialize system
1 SystemInit();
8 //Initialize delays
1 TM_DELAY_Init();
9 //Initialize LEDs
2 TM_DISCO_LedInit();
0
2 //Mount drive
1 if (f_mount(&FatFs, "", 1) == FR_OK) {
2 //Mounted OK, turn on RED LED
2 TM_DISCO_LedOn(LED_RED);
2
3 //Try to open file
2 if (f_open(&fil, "1stfile.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE) == FR_OK)
4 {
2 //File opened, turn off RED and turn on GREEN led
5 TM_DISCO_LedOn(LED_GREEN);
2 TM_DISCO_LedOff(LED_RED);
6
2 //If we put more than 0 characters (everything OK)
7 if (f_puts("First string in my file\n", &fil) > 0) {
2 if (TM_FATFS_DriveSize(&total, &free) == FR_OK) {
8 //Data for drive size are valid
2 }
9
3 //Turn on both leds
0 TM_DISCO_LedOn(LED_GREEN | LED_RED);
3 }
1
3 //Close file, don't forget this!
2 f_close(&fil);
3 }
3
3 //Unmount drive, don't forget this!
4 f_mount(0, "", 1);
3 }
5
3 while (1) {
6
3 }
7 }
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
8
4
9
5
0
5
1
5
2
5
3
5
4
5
5
5
6
5
7
5
8
5
9
6
0
6
1
6
2
6
3
6
4

View project on Github, download library below.

TM STM32F4 FATFS Library


Read SD card with SDIO or SPI on STM32F4xx using FatFS by Chan

Download
25317 downloads551.30 KB

You might also like