FatFs library on Raspberry Pi Pico / Pico 2. This library supports:
- FatFs R0.15 (http://elm-chan.org/fsw/ff/00index_e.html)
- Applicable for two types of SPI master functions
- SPI function applied for compliant pin assignment with native SPI interface of Raspberry Pi Pico series
- Otherwise, SPI PIO function applied for more flexible pin assignment
- SD, SDHC, SDXC card types
- FAT16, FAT32, exFAT format types
- Test projects for write / read speed benchmark
- Raspberry Pi Pico / Pico W
- Raspberry Pi Pico 2 / Pico 2W
| Pico Pin # | Pin Name | Function | microSD connector | microSD SPI board |
|---|---|---|---|---|
| 4 | GP2 | SPI0_SCK | CLK (5) | CLK |
| 5 | GP3 | SPI0_TX | CMD (3) | MOSI |
| 6 | GP4 | SPI0_RX | DAT0 (7) | MISO |
| 7 | GP5 | GPIO (Out) | CD/DAT3 (2) | CS |
| 8 | GND | GND | VSS (6) | GND |
| 36 | 3V3(OUT) | 3.3V | VDD (4) | 3V3 |
- Pin configuration by user is available. See Configuration section.
- Wire length between Pico and SD card is very sensitive. Short wiring as possible is desired, otherwise errors such as Mount error, Preallocation error and Write fail will occur.
| Pico Pin # | Pin Name | Function | CP2102 module |
|---|---|---|---|
| 1 | GP0 | UART0_TX | RXD |
| 2 | GP1 | UART0_RX | TXD |
| 3 | GND | GND | GND |
Configure function, clock and pin assignment by pico_fatfs_set_config() with pico_fatfs_spi_config_t
pico_fatfs_spi_config_t config = {
spi0, // spi_inst (spi0, spi1 or NULL)
CLK_SLOW_DEFAULT, // clk_slow
CLK_FAST_DEFAULT, // clk_fast
PIN_SPI0_MISO_DEFAULT, // pin_miso (SPIx_RX)
PIN_SPI0_CS_DEFAULT, // pin_cs
PIN_SPI0_SCK_DEFAULT, // pin_sck (SPIx_SCK)
PIN_SPI0_MOSI_DEFAULT, // pin_mosi (SPIx_TX)
true // pullup
};
bool spi_configured = pico_fatfs_set_config(&config);
- Choose
spi0,spi1for SPI function orNULLexplicitly for SPI PIO function - Note that SPI PIO function could be implicitly configured for the case of incompliant pin assignment for SPI function.
- The return value of
pico_fatfs_set_config()indicates finally configured function (true: SPI, false SPI PIO).
- By default,
clk_slowas100 * KHZandclk_fastas50 * MHZare used for the configuration. - For SPI function, the actual SPI clock frequency is set to clk_peri / 2N, which is determined by spi_set_baudrate() in 'pico-sdk/src/rp2_common/hardware_spi/spi.c'.
- For rp2040, 125 MHz / 4 is applied. SCK frequency is 31.25 MHz.
- For rp2350, 150 MHz / 4 is applied. SCK frequency is 37.50 MHz.
- For SPI PIO funciton, the maximum SCK frequency is limited up to the system frequency divided by 6.
- For rp2040, SCK freq <= 125 MHz / 6 is applied. SCK frequency is 20.83 MHz.
- For rp2350, SCK freq <= 150 MHz / 6 is applied. SCK frequency is 25.00 MHz.
- The actual operating SCK frequency is available by
pico_fatfs_get_clk_fast_freq()afterf_mount().
- For SPI function configuration, the pin assignment needs to satisfy the below constraints, otherwise SPI PIO function will be configured implicitly even though
spi0orspi1is designated.
| SPI role | Pico pin category | GPx for SPI0 | GPx for SPI1 |
|---|---|---|---|
| MISO | SPIx_RX | 0, 4, 16, 20, (32, 36) | 8, 12, 24, 28, (40, 44) |
| SCK | SPIx_SCK | 2, 6, 18, 22, (34, 38) | 10, 14, 26, (30, 42, 46) |
| MOSI | SPIx_TX | 3, 7, 19, 23, (35, 39) | 11, 15, 27, (31, 43, 47) |
(): rp2350 only
- Set
trueto use internal pullup for MISO and MOSI (recommended), otherwise, setfalsewhen external pullup resistors attached for MISO and MOSI as shown in external pullup
- Configure PIO and state machine by
pico_fatfs_config_spi_pio()for the case of SPI PIO function. - Default is PIO0 (
SPI_PIO_DEFAULT_PIO) and state machine 0 (SPI_PIO_DEFAULT_SM). - Only effective when SPI PIO function configured. No impact when SPI function is configured.
bool spi_configured = pico_fatfs_set_config(&config);
if (!spi_configured) {
pico_fatfs_config_spi_pio(pio0, 0); // PIO, sm
}
User can also override following functions as they are defined with weak attribute.
DWORD get_fattime()in tf_card.c
- See "Getting started with Raspberry Pi Pico"
- Put "pico-sdk", "pico-examples" and "pico-extras" on the same level with this project folder.
- Set environmental variables for PICO_SDK_PATH, PICO_EXTRAS_PATH and PICO_EXAMPLES_PATH
- Confirmed with Pico SDK 2.1.1
> git clone -b 2.1.1 https://github.com/raspberrypi/pico-sdk.git
> cd pico-sdk
> git submodule update -i
> cd ..
> git clone -b sdk-2.1.1 https://github.com/raspberrypi/pico-examples.git
>
> git clone -b sdk-2.1.1 https://github.com/raspberrypi/pico-extras.git
>
> git clone -b main https://github.com/elehobica/pico_fatfs.git
- Build is confirmed with Developer Command Prompt for VS 2022 and Visual Studio Code on Windows environment
- Confirmed with cmake-3.27.2-windows-x86_64 and gcc-arm-none-eabi-10.3-2021.10-win32
- Lanuch "Developer Command Prompt for VS 2022"
> cd pico_fatfs\tests\xxxx
> mkdir build && cd build
> cmake -G "NMake Makefiles" .. ; (for Raspberry Pi Pico 1 series)
> cmake -G "NMake Makefiles" -DPICO_PLATFORM=rp2350 .. ; (for Raspberry Pi Pico 2)
> nmake
- Put "*.uf2" on RPI-RP2 or RP2350 drive
- Build is confirmed with pico-sdk-dev-docker:sdk-2.1.1-1.0.0
- Confirmed with cmake-3.22.1 and arm-none-eabi-gcc (15:10.3-2021.07-4) 10.3.1
$ cd pico_fatfs/tests/xxxx
$ mkdir build && cd build
$ cmake .. # (for Raspberry Pi Pico 1 series)
$ cmake -DPICO_PLATFORM=rp2350 .. # (for Raspberry Pi Pico 2)
$ make -j4
- Download "*.uf2" on RPI-RP2 or RP2350 drive
- Board: Raspberry Pi Pico / Pico 2
- Inrerface function: SPI / SPI PIO
- SPI clock frequency: clk_fast = 50 MHz (See logs for actual operating frequency)
- Click the number for the logs in detail
| # | Image | Vendor | Name | Capacity | P/N | Standard | Format |
|---|---|---|---|---|---|---|---|
| 1 | ![]() |
Memorex | - | 2GB | - | microSD | FAT16 |
| 2 | ![]() |
SanDisk | - | 16GB | - | microSDHC C4 | FAT32 |
| 3 | ![]() |
Sansung | EVO Plus | 32GB | MB-MC32GA | microSDHC UHS-I U1 | FAT32 |
| 4 | ![]() |
Sandisk | High Endurance | 64GB | SDSQQNR-064G | microSDXC UHS-I C10 U3 V30 | exFAT |
| 5 | ![]() |
Sandisk | Ultra | 64GB | SDSQUAC-64G-GN6MN | microSDXC UHS-I A1 C10 U1 | exFAT |
| 6 | ![]() |
Sandisk | Ultra | 128GB | SDSQUNR-128G | microSDXC UHS-I C10 | exFAT |
| 7 | ![]() |
Sandisk | Extreme | 128GB | SDSQXAA-128G-GN6MN | microSDXC UHS-I A2 U3 V30 | exFAT |
| 8 | ![]() |
Samsung | EVO Plus | 256GB | MB-MC256KA | microSDXC UHS-I A2 U3 V30 | exFAT |
| 9 | ![]() |
Xioxia | Exceria G2 | 256GB | LMEX2L256GG2 | microSDXC UHS-I U3 V30 | exFAT |
| 10 | ![]() |
Sandisk | Extreme PRO | 256GB | SDSQXCD-256G-GN6MA | microSDXC UHS-I A2 U3 V30 | exFAT |
| 11 | ![]() |
Samsung | PRO Plus | 256GB | MB-MD256SA | microSDXC UHS-I A2 U3 V30 | exFAT |
- For Samsung PRO Plus, benchmark tests are measured every time after power cycle, otherwise the write performance becomes illegally high due to internal cache? in case of same contents writing.
- The speed in KB/s (1 KB = 1000 bytes) for the case of writing total 5MB file divided by 512 byte accesses.
- The maximum / minimum / average latency in microseconds to get the response from single
f_write()for 512 bytes. - The latency of the first time call of
f_write()is excluded to ignore the time required for the initialization.
- The speed in KB/s (1 KB = 1000 bytes) for the case of reading total 5MB file divided by 512 byte accesses.
- The maximum / minimum / average latency in microseconds to get the response from single
f_read()for 512 bytes. - The latency of the first time call of
f_read()is excluded to ignore the time required for the initialization.
















