An open API service indexing awesome lists of open source software.

https://gitlab.com/jeancf/esp32c3-sd-fatfs

This crate provides a driver for use with FAT FS to access and manipulate file systems and files on an SD card on the ESP32C3 board (RISC-V).
https://gitlab.com/jeancf/esp32c3-sd-fatfs

SD driver embedded esp32 esp32c3 no-std rust

Last synced: 3 months ago
JSON representation

This crate provides a driver for use with FAT FS to access and manipulate file systems and files on an SD card on the ESP32C3 board (RISC-V).

Awesome Lists containing this project

README

        

# esp32c3-sd-fatfs

> This crate is built around **fatfs version 0.4** which is not released yet on crates.io.
> fatfs is therefore pulled from its github repository.
> Version 0.4 adds `fatfs::Read`, `fatfs::Write` and `fatfs::Seek` traits and use them
> to replace `Read`, `Write`, `Seek` traits from std::io (BREAKING CHANGE). Thanks to this change it is possible to use the fatfs crate in a `no-std` context like here.

## Purpose

This crate provides a driver for use with [FAT FS](https://crates.io/crates/fatfs) to access and manipulate file systems
and files on an SD card on the [**ESP32C3**](https://www.espressif.com/en/products/socs/esp32-c3) board (RISC-V).

## Usage

Refer to `examples/example.rs` for the full code.

Initialize MCU

```rust
let peripherals = Peripherals::take().unwrap();
let mut system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
```

Set up interface with the SD card reader (SPI)

```rust
// Take ownership of the SPI peripheral
let spi = peripherals.SPI2;

// initialize GPIO pins for SPI
let cs = io.pins.gpio4;
let sck = io.pins.gpio5;
let miso = io.pins.gpio6;
let mosi = io.pins.gpio7;

// Setup SPI host interface with the card
let mut card = Card::new(
&clocks,
spi,
cs,
sck,
miso,
mosi,
&mut system.peripheral_clock_control,
);
```

Establish connection with the card that must be inserted in the reader at this point

```rust
card.connect().unwrap();
```

Select primary partition to access (here, partition `0`) and wrap it in an FsSlice struct

```rust
let partition = FsSlice::primary_partition(card, 0).unwrap();
```

Initialize file system access to the partition

```rust
let fs = fatfs::FileSystem::new(partition, fatfs::FsOptions::new()).unwrap();
```

> From here onwards, all the functionalities of FAT FS are available. Check the [FAT FS documentation](https://docs.rs/fatfs) for details.
> The snippets below are just provided for completeness.

Write a file in the root directory

```rust
let root_dir = fs.root_dir();
let mut root_file = root_dir.create_file("rootfile.txt").unwrap();
// Empty file if it already exists
root_file.truncate().unwrap();
root_file.write_all(b"Hello root World!\n").unwrap();
root_file.flush().unwrap();

```

Read 18 bytes from a file and print the string to the serial console

```rust
let mut rf = root_dir.open_file("rootfile.txt").unwrap();
let mut content = [0_u8; 18];
let bytes_read = rf.read(&mut content).unwrap();
sprintln!(core::str::from_utf8(content.as_ref()).unwrap());
```

## Limitations of the driver

* The current implementation only supports cards with a Master Boot record (MBR)
* Only primary partitions can be accessed (i.e. not extended partitions)
* FAT FS supports FAT12, FAT16 and FAT32 partitions

*I wrote this driver as a learning exercise in bare-metal development. While the solution is performing as expected, the example.rs binary is ~100 kB large. As the Longan Nano only has 128 kB of flash memory, we are clearly over budget for only the SD card interface functionality. FAT FS is more appropriate for an MCU with more flash available. A barebones crate with minimal functionality (file create/read/write on FAT32) with the smallest possible footprint would be nice to have.*