The following article describes the SPI interface of an SD card to a STM32F0 Discovery board with FAT filesystem support.
Having successfully interfaced the ILI9341 TFT display to STM32F0 Discovery board I felt the need for a bigger data memory, so I thought about using a SD Memory Card because they are popular and have big memory capacities compared to their cost. Another advantage is that they can be easily be connected to the computer.
The best scenario would have been that the embedded system were to be able to read and write files on the card. In this case, for example in a data logging application, data can be saved in files which can be easily viewed on the computer (plot graphs / examine data). Image files can be copied onto the SD card on the computer and then read by the embedded system and displayed on the TFT.
To do this I needed a SW module for the embedded system that could correctly read and write data to files organised by a filesystem. After a quick search on Google I found this: FatFs - Generic FAT File System Module. After a bit of research I found out that many people have successfully used this module so I wanted to try it myself too.
It's nice that the FatFs module is completely separated from the disk I/O layer which you have to write yourself. This disk I/O layer provides the necessary function interfaces to the upper FatFs layer.
I decided to have a SPI interface to the SD card mainly because I already had an SD card adapter with pinout for SPI and because it has fewer wires.
At the bottom of FatFs page there is a link to implementations on various platforms: FatFs sample projects for various platforms. Among these, there was an implementation for STM32F100 series which I used as base for my implementation of the disk I/O layer for STM32F051 microcontroller. The example had also a SPI interface to the SD card like I had.
There are some changes between the disk I/O layers of STM32F100 and STM32F051 microcontrollers because the SPI peripheral of these MCUs is a little bit different. These two SPI peripherals have different handling of 8bit/16bit SPI data and the one on STM32F051 has FIFO buffers for RX and TX.
With SPI configured at maximum speed (24MHz clock) I measured a read speed of 800KB/s from a 1.2MB file which was read in 512B blocks from the SD card. This was achieved without benefiting of the FIFO capabilities of the SPI peripheral on STM32F051. It's to be researched if the performance of the disk I/O layer for STM32F051 SPI can be increased by taking advantage of the SPI RX and TX 4 level FIFO.
SPI2 Config for SD Card
void Config_SPI2()
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIO configuration */
//PB11 CD
//PB12 NSS
//PB13 SCK
//PB14 MISO
//PB15 MOSI
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //CD
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //NSS
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //SCK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; //MISO
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //MOSI
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_0);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_0);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_0);
/* SPI2 configuration -------------------------------------------------------*/
/* Enable the SPI2 periph */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_I2S_DeInit(SPI2);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; //128: 375kHZ, 8: 6MHz, 4: 12MHz, 2: 24MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);
}
FatFs is completely separated from the disk I/O layer and therefore it is independent of the platform. It can be freely downloaded from: http://elm-chan.org/fsw/ff/00index_e.html
The disk I/O layer for STM32F051 with SPI interface to SD card can be downloaded here: