I tested accessing exFAT-formatted microSDXC cards with the Raspberry Pi Pico.
![]() |
| Raspberry Pi Pico microSD access test scene |
FatFs Module
Since I wanted to support not only FAT and FAT32 but also exFAT, I did not use the sample in pico-examples but instead used theFatFs Module. FatFs can be freely used, modified, and distributed at one's own risk regardless of purpose, and has abundant implementation examples, making it invaluable for DIY microcontroller users. Since I had already verified exFAT operation with the FatFs module on the Sipeed Longan Nano, I modified from that implementation. The version used wasR0.14a_p2.Wiring Diagram / Pin Configuration
The wiring diagram is as follows.A 10K ohm pull-up resistor on the DAT0 line is required; without it, the card will not be recognized properly.
![]() |
| Wiring Diagram |
The connection table is also provided below.
Notes
The wiring between Raspberry Pi Pico and the microSD card slot is very sensitive, and stable operation could not be achieved with a typical breadboard microSD card module and pin wiring (especially with SDXC cards). I added functions to adjust the output pad drive strength and slew rate, which exist in the registers but are not in the Raspberry Pi Pico GPIO library, and tried various adjustments including frequency changes and inserting damping resistors, but saw little improvement. Ultimately, I confirmed stable operation by creating a direct-insertion connection module as shown in the photo below. There appears to be room for future improvement regarding SPI access timing margin.![]() |
| microSD card direct-insertion module |
Verified Cards
Below is information about the cards used for verification. microSD cards use FAT, microSDHC cards use FAT32, and microSDXC cards use exFAT. None of my cards failed to be recognized; all errors were due to the access timing issues mentioned above.- PQI microSD 1GB
- Memorex microSD 2GB
- Transcend microSDHC 32GB (C4)
- Toshiba microSDXC 64GB (UHS-I C10)
- SanDisk microSDXC Ultra A1 64GB (UHS-I C10/U1)
- SanDisk microSDXC Ultra A1 512GB (UHS-I C10/U1)
- SanDisk microSDXC Ultra A2 1TB (UHS-I U3/V30)
pico_fatfs_test Project
https://github.com/elehobica/pico_fatfs_test I have published the project. The features are as follows.- Starts when any key is pressed in the serial terminal
- Mounts and recognizes the card. Displays the file system type (FAT, FAT32, exFAT) and capacity
- Measures and displays Write/Read access speeds (two runs each)
![]() |
| Serial terminal output example |
Below is a brief explanation of the code.
ffconf.h
FatFs functional configuration is performed inffconf.h. For this benchmark, I used a relatively broad configuration, but when using it in actual projects, you may want to consider the following parameters.Current settings and considerations for other projects
- FF_FS_READONLY 0: Can be set to 1 for read-only use
- FF_FS_MINIMIZE 0: Can be set to 1, 2, etc. depending on the range of APIs used
- FF_USE_EXPAND 1: Can be 0 if PreAllocation is not used
- FF_USE_LFN 1: Can be 0 if Long File Name is not used
- FF_FS_RPATH 1: Can be 0 if relative paths are not used or managed externally
- FF_FS_EXFAT 1: Can be 0 if exFAT is not used
- FF_FS_NORTC 1: Set to 0 and implement required functions to reflect timestamps via RTC
tf_card.c / tf_card.h
The device-dependent part of the FatFs module is described entirely intf_card.c / tf_card.h.- SPI0 pin assignments are defined in tf_card.h
- SPI card initialization clock is set to 100KHz, high-speed clock to 50MHz (adjust as needed)
- SPI access mode is 8-bit, CPOL = 0, CPHA = 0, MSB First
For reference, the SPI access implementation is excerpted below. Single-byte bidirectional access, multi-byte read access, and multi-byte write access are implemented using pico-sdk hardware/spi.h functions.
/* Exchange a byte */
static
BYTE xchg_spi (
BYTE dat /* Data to send */
)
{
uint8_t *buff = (uint8_t *) &dat;
spi_write_read_blocking(spi0, buff, buff, 1);
return (BYTE) *buff;
}
/* Receive multiple byte */
static
void rcvr_spi_multi (
BYTE *buff, /* Pointer to data buffer */
UINT btr /* Number of bytes to receive (even number) */
)
{
uint8_t *b = (uint8_t *) buff;
spi_read_blocking(spi0, 0xff, b, btr);
}
...
/* Transmit multiple byte */
static
void xmit_spi_multi (
const BYTE *buff, /* Pointer to data buffer */
UINT btx /* Number of bytes to transmit (even number) */
)
{
const uint8_t *b = (const uint8_t *) buff;
spi_write_blocking(spi0, b, btx);
}
hardware_gpio_ex
Although not used in this project, functions for setting GPIO output pad drive strength, slew rate, and input pad Schmitt trigger were implemented in thehardware_gpio_ex directory below.By adding the following to the project's CMakeLists.txt
add_subdirectory(hardware_gpio_ex)
// ... (other settings)
target_link_libraries(${bin_name} PRIVATE
pico_stdlib
// ... (other libraries)
hardware_gpio_ex
)
and including the following in the source file, #include "hardware/gpio_ex.h"
the following three functions become available. (See commented-out sections in tf_card.c for usage examples)
void gpio_set_drive_strength(uint gpio, uint value); void gpio_set_schmitt(uint gpio, uint value); void gpio_set_slew_rate(uint gpio, uint value);
Access Speed Measurement Results
The access speed figures are rather unimpressive. Of course, many applications work fine at this level, so whether to use it as-is or tune for higher performance would be decided on a case-by-case basis.- PQI microSD 1GB
Type is FAT16 Card size: 1.02 GB (GB = 1E9 bytes) FILE_SIZE_MB = 5 BUF_SIZE = 512 bytes Starting write test, please wait. write speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 72.8148, 188153, 3175, 7028 72.7216, 188240, 3177, 7037 Starting read test, please wait. read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 740.6934, 1591, 665, 690 740.8031, 1589, 665, 690 - Memorex microSD 2GB
Type is FAT16 Card size: 2.00 GB (GB = 1E9 bytes) FILE_SIZE_MB = 5 BUF_SIZE = 512 bytes Starting write test, please wait. write speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 79.2543, 222555, 2452, 6456 78.1408, 229029, 2457, 6549 Starting read test, please wait. read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 757.2978, 2044, 533, 675 757.4125, 2039, 533, 675 - Transcend microSDHC 32GB (C4)
Type is FAT32 Card size: 31.90 GB (GB = 1E9 bytes) FILE_SIZE_MB = 5 BUF_SIZE = 512 bytes Starting write test, please wait. write speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 273.3709, 209797, 947, 1871 287.3379, 208416, 968, 1780 Starting read test, please wait. read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 851.7343, 1192, 539, 600 851.8794, 1189, 539, 600 - Toshiba microSDXC 64GB (UHS-I C10)
Type is EXFAT Card size: 61.89 GB (GB = 1E9 bytes) FILE_SIZE_MB = 5 BUF_SIZE = 512 bytes Starting write test, please wait. write speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 149.3869, 180241, 2065, 3424 155.4869, 173010, 2069, 3291 Starting read test, please wait. read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 620.7698, 960, 621, 824 620.4617, 959, 621, 824 - SanDisk microSDXC Ultra A1 64GB (UHS-I C10/U1)
Type is EXFAT Card size: 63.83 GB (GB = 1E9 bytes) FILE_SIZE_MB = 5 BUF_SIZE = 512 bytes Starting write test, please wait. write speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 464.5679, 19560, 881, 1101 471.6234, 19881, 761, 1084 Starting read test, please wait. read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 1238.1575, 422, 394, 412 1238.1575, 422, 399, 412 - SanDisk microSDXC Ultra A1 512GB (UHS-I C10/U1)
Type is EXFAT Card size: 511.80 GB (GB = 1E9 bytes) FILE_SIZE_MB = 5 BUF_SIZE = 512 bytes Starting write test, please wait. write speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 430.8212, 24998, 951, 1187 428.5318, 24974, 953, 1193 Starting read test, please wait. read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 1195.5237, 443, 413, 427 1195.5237, 444, 415, 427 - SanDisk microSDXC Ultra A2 1TB (UHS-I U3/V30)
Type is EXFAT Card size: 1023.74 GB (GB = 1E9 bytes) FILE_SIZE_MB = 5 BUF_SIZE = 512 bytes Starting write test, please wait. write speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 426.9217, 6290, 963, 1198 427.0676, 32321, 958, 1197 Starting read test, please wait. read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 1192.9563, 445, 409, 428 1192.9563, 445, 413, 428





No comments:
Post a Comment