# RPi Pico SD Card SPI Connections and FatFs Integration in rpi_pico_wav_player

> Discover RPi Pico SD card SPI connections using SPI 0 (GPIO 4-7) and explore FatFs integration with the pico_fatfs library in the rpi_pico_wav_player firmware. Learn how to implement file system support.

- Repository: [Elehobica/rpi_pico_wav_player](https://github.com/elehobica/rpi_pico_wav_player)
- Tags: how-to-guide
- Published: 2026-03-01

---

**The rpi_pico_wav_player firmware uses the RP2040's SPI 0 peripheral (GPIO 4-7) to communicate with the micro-SD card and integrates the FatFs filesystem through the pico_fatfs wrapper library.**

The `rpi_pico_wav_player` project by elehobica implements a WAV audio player on the Raspberry Pi Pico, requiring reliable SD card access for media storage. Understanding the **SD card SPI connections** and **FatFs integration** is essential for developers modifying the hardware or adapting the filesystem layer to custom boards.

## SPI 0 Hardware Connections for the SD Card Interface

The firmware configures **SPI 0** as the dedicated communication bus for the micro-SD card, utilizing the RP2040's default pin mapping provided by the pico-sdk.

### Default GPIO Pin Assignment

The SPI 0 signals connect to the following GPIO pins as defined by the `PIN_SPI0_*_DEFAULT` constants referenced in [`lib/file_menu/file_menu_FatFs.c`](https://github.com/elehobica/rpi_pico_wav_player/blob/main/lib/file_menu/file_menu_FatFs.c):

- **GPIO 4** — MISO (Master In Slave Out)
- **GPIO 5** — CS (Chip Select)
- **GPIO 6** — SCK (Serial Clock)
- **GPIO 7** — MOSI (Master Out Slave In)

### Physical Wiring and Level Shifting

According to the project schematic in `doc/schematic/RPi_Pico_WAV_Player_microsd_Schematic.png`, the SD card connects directly to these GPIOs without external level-shifters. The RP2040's 3.3V logic levels are compatible with standard micro-SD card interfaces, allowing a simplified hardware design.

## FatFs Integration Architecture

The project integrates the ChaN FatFs library through a custom RP2040 wrapper called **pico_fatfs**, included as a git submodule at `lib/pico_fatfs`.

### SPI Configuration Structure

In [`lib/file_menu/file_menu_FatFs.c`](https://github.com/elehobica/rpi_pico_wav_player/blob/main/lib/file_menu/file_menu_FatFs.c) (lines 353-362), the SPI bus parameters are configured using the `pico_fatfs_spi_config_t` structure before filesystem initialization:

```c
pico_fatfs_spi_config_t config = {
    spi0,                     // SPI controller instance
    CLK_SLOW_DEFAULT,         // Clock source selection
    40 * MHZ,                 // SPI clock frequency (40 MHz)
    PIN_SPI0_MISO_DEFAULT,    // MISO pin (GPIO 4)
    PIN_SPI0_CS_DEFAULT,      // Chip Select pin (GPIO 5)
    PIN_SPI0_SCK_DEFAULT,     // Serial Clock pin (GPIO 6)
    PIN_SPI0_MOSI_DEFAULT,    // MOSI pin (GPIO 7)
    true                      // Enable internal pull-ups
};
pico_fatfs_set_config(&config);

```

### Filesystem Mounting with Retry Logic

Following configuration, the code attempts to mount the SD card using the standard FatFs `f_mount` function. As implemented in [`lib/file_menu/file_menu_FatFs.c`](https://github.com/elehobica/rpi_pico_wav_player/blob/main/lib/file_menu/file_menu_FatFs.c) (lines 364-373), the system implements a robust retry mechanism:

```c
fr = f_mount(&fs, "", 1);     // Mount the volume immediately

if (fr != FR_OK) {
    // Retry logic: up to 5 attempts with SPI reset between tries
    for (int i = 0; i < 5 && fr != FR_OK; i++) {
        pico_fatfs_reboot_spi();   // Reset SPI0 peripheral
        fr = f_mount(&fs, "", 1);  // Retry mount
    }
}

```

## Practical Implementation Examples

### Initializing the SD Card from Application Code

High-level UI code in [`src/UIMode.cpp`](https://github.com/elehobica/rpi_pico_wav_player/blob/main/src/UIMode.cpp) (lines 268-270) initializes the storage subsystem through the file_menu wrapper:

```cpp
uint8_t fs_type;
FRESULT fr = file_menu_init(&fs_type);   // Configures SPI0 and mounts FatFs

if (fr != FR_OK) {
    printf("SD mount failed (code %d)\n", fr);
}

```

### Performing File Operations

Once mounted, the firmware accesses WAV files using standard FatFs APIs. The following pattern demonstrates opening and reading audio data:

```c
FIL fp;
char buffer[512];  // Audio data buffer
FRESULT fr = f_open(&fp, "track01.wav", FA_READ);

if (fr == FR_OK) {
    UINT bytes_read;
    f_read(&fp, buffer, sizeof(buffer), &bytes_read);
    // Process audio data...
    f_close(&fp);
}

```

### Recovering from Communication Errors

When SPI communication fails or the card becomes unresponsive, the driver can reinitialize the bus without a full system reset. The `pico_fatfs_reboot_spi()` function resets the SPI 0 peripheral to its default state:

```c
pico_fatfs_reboot_spi();   // Reset SPI0 and restore pin configuration
fr = f_mount(&fs, "", 1);  // Attempt remount

```

## Summary

- The rpi_pico_wav_player uses **SPI 0** (GPIO 4-7) for micro-SD card communication, configured in [`lib/file_menu/file_menu_FatFs.c`](https://github.com/elehobica/rpi_pico_wav_player/blob/main/lib/file_menu/file_menu_FatFs.c).
- **FatFs integration** occurs through the `pico_fatfs` submodule, which wraps low-level SPI transactions into standard filesystem APIs.
- The SPI configuration operates at **40 MHz** with internal pull-ups enabled, requiring no external level-shifters for 3.3V operation.
- Robust error handling includes **automatic retry logic** with `pico_fatfs_reboot_spi()` to recover from mount failures.
- Application code interacts with storage through `file_menu_init()` and standard FatFs functions like `f_open()` and `f_read()`.

## Frequently Asked Questions

### Which SPI bus does the rpi_pico_wav_player use for the SD card?

The firmware uses **SPI 0** of the RP2040 microcontroller, configured through the `pico_fatfs_set_config()` function in [`lib/file_menu/file_menu_FatFs.c`](https://github.com/elehobica/rpi_pico_wav_player/blob/main/lib/file_menu/file_menu_FatFs.c). This peripheral communicates at 40 MHz using the default GPIO pin mapping (GPIO 4-7).

### What are the specific GPIO pin numbers for the SD card interface?

The SPI 0 connections map to **GPIO 4 (MISO), GPIO 5 (CS), GPIO 6 (SCK), and GPIO 7 (MOSI)**. These pins are defined by the `PIN_SPI0_*_DEFAULT` constants from the pico-sdk and are referenced in the SPI configuration structure within [`file_menu_FatFs.c`](https://github.com/elehobica/rpi_pico_wav_player/blob/main/file_menu_FatFs.c).

### How is the FatFs library integrated into the project?

The project includes the **pico_fatfs** library as a git submodule at `lib/pico_fatfs`. This wrapper translates standard FatFs API calls (`f_mount`, `f_open`, `f_read`) into RP2040-specific SPI transactions, handling the low-level hardware communication automatically.

### Does the hardware require level-shifters for the SD card connection?

No, the design does not require level-shifters. As shown in the project schematic (`doc/schematic/RPi_Pico_WAV_Player_microsd_Schematic.png`), the SD card connects directly to the Pico's 3.3V GPIO pins. The RP2040's voltage levels are compatible with standard micro-SD card specifications.