<p align="center">
<img src="https://i.imgur.com/gAPf1TI.png" width="50" alt="uFerris logo"/>
<br/>
</p>
<h1 align="center">µFerris Board Support Package</h1>
<p align="center">
<strong>A flexible, hardware-agnostic BSP crate for the µFerris Xiao carrier board</strong>
</p>
<p align="center">
<img src="https://i.imgur.com/KcvXhPw.png" width="250" alt="µFerris board photo"/>
</p>
<br/>
<div align="center">
[](https://crates.io/crates/uferris-bsp)
[](https://docs.rs/uferris-bsp)
</div>
**µFerris** is a Rust embedded learning/experimentation kit that can accept various **[Seeed Studio Xiao](seeedstudio.com/xiao-series-page)** controllers.
The `uferris-bsp` crate provides a **generic Board Support Package** that aims to be mostly MCU-agnostic, allowing the same high-level board API to work across different supported Xiao controllers (ESP32-C3, RP2040, etc.).
Controller-specific support is enabled via **feature flags**.
µFerris is an open-source hardware project. The hardware source is available on the **[uferris-hw](https://github.com/uFerris-rs/uferris-hw)** repo. µFerris can also be acquired from **[The Embedded Rustacean Store](http://shop.theembeddedrustacean.com/)**.
## Architecture Overview
The crate adopts the following layered approach:
<p align="center">
<img src="https://i.imgur.com/SD77pGl.png" width="520" alt="µFerris BSP architecture diagram"/>
</p>
The architechture adds two layers on top of existing community crates:
- **µFerris Board Logic Layer**: This layer implments the hardware-agnostic µFerris board API.
- **µFerris Board Adapter Layer**: This layer maps the generic logic to concrete MCU HALs (uses `embedded-hal` traits where possible).
## `async` Support
This BSP supports `async` operation. This is enabled by activating the `async` feature flag which enables the `async` BSP API. The different modes are handled by using mode type parameters: `Uferris<.., Blocking>`, and `Uferris<.., Async>`, built against the `embedded-hal` and `embedded-hal-async` traits, respectively.
The runtime, such as embassy, is provided by the application, not the BSP. The crate starts no executor and installs no time driver. The BSP initialization hands back a board handle whose methods are futures, and the program brings its own executor (`embassy-executor`) and its own delay (`embassy-time`).
Note that not all board functions might have async methods or support. However, the blocking functions would still be available in `async` mode.
## Support Status
| [Xiao ESP32-C3](https://www.seeedstudio.com/Seeed-XIAO-ESP32C3-p-5431.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-esp32c3` | ✅ | ✅ |
| [Xiao ESP32-C5](https://www.seeedstudio.com/Seeed-Studio-XIAO-ESP32C5-p-6609.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-esp32c5` | ✅ | ✅ |
| [Xiao ESP32-C6](https://www.seeedstudio.com/Seeed-Studio-XIAO-ESP32C6-p-5884.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-esp32c6` | ✅ | ✅ |
| [Xiao ESP32-S3](https://www.seeedstudio.com/XIAO-ESP32S3-p-5627.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-esp32s3` | ✅ | ✅ |
| [Xiao ESP32-S3 Sense](https://www.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-esp32s3` | ✅ | ✅ |
| [Xiao nRF52840](https://www.seeedstudio.com/Seeed-XIAO-BLE-nRF52840-p-5201.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-nrf52840` | ✅ | ✅ |
| [Xiao nRF52840 Sense](https://www.seeedstudio.com/Seeed-XIAO-BLE-Sense-nRF52840-p-5253.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-nrf52840` | ✅ | ✅ |
| [Xiao nRF54L15](https://www.seeedstudio.com/XIAO-nRF54L15-p-6493.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-nrf54l15` | ✅ | ✅ |
| [Xiao nRF54L15 Sense](https://www.seeedstudio.com/XIAO-nRF54L15-Sense-p-6494.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-nrf54l15` | ✅ | ✅ |
| [Xiao RP2350](https://www.seeedstudio.com/Seeed-XIAO-RP2350-p-5944.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-rp2350` | ✅ | ✅ |
| [Xiao RP2040](https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | `xiao-rp2040` | ✅ | ✅ |
| [Xiao SAMD21](https://www.seeedstudio.com/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | - | ❌ | ❌ |
| [Xiao RA4M1](https://www.seeedstudio.com/Seeed-XIAO-RA4M1-p-5943.html?utm_source=blog&utm_medium=TER&utm_campaign=uFerris) | - | ❌ | ❌ |
| Xiao MG24 | - | ❌ | ❌ |
| Xiao MG24 Sense | - | ❌ | ❌ |
## Adding Support for a New Xiao Controller
Adding support for a new Xiao board entails two parts:
1. **Adding a Device Feature Flag in `Cargo.toml`**: A feature flag that imports the new device HAL needs to be added.
2. **Adding a Device Board Adapter**: This entails adding a new board definition (adapter layer) under the crate `boards/` folder.
The rest of the crate files should not need to change.
## Feature Flags
Available Cargo features:
- `xiao-esp32c3` — Xiao ESP32-C3 Device Support
- `xiao-esp32c5` — Xiao ESP32-C5 Device Support
- `xiao-nrf52840` — Xiao nRF52840 Device Support
- `xiao-nrf54l15` — Xiao nRF54L15 Device Support
- `xiao-rp2040` — Xiao RP2040 Device Support
- `xiao-rp2350` — Xiao RP2350 Device Support
- `powerboard` — µFerris Megalops Power Board Extension Support
- `async` — `async` Support Feature Flag (enables the `Uferris<.., Async>` board API; the executor and time driver are the application's)
## Quick Start / Usage
Generally, you need to:
- Enable the correct feature flags in your `Cargo.toml`
- Pass the correct HAL peripherals struct to `uferris_init()`
Everything else should stay the same regardless of which Xiao is mounted. A simple example is presented below.
```rust
#![no_std]
#![no_main]
use uferris_bsp::uferris_init;
#[entry]
fn main() -> ! {
// 1. Get your HAL peripherals (depends on MCU)
let peripherals = your_hal::take().unwrap();
// 2. Initialize the µFerris board abstraction
let mut uferris = uferris_init(peripherals);
// 3. Use the board API
uferris.led1_on();
loop {}
}
```
## Examples
Each supported board has a self-contained example project under [`examples/`](examples/).
Each board directory is a self-contained Cargo project with its own target, toolchain, and runner configuration.
See each board's README for the full list of examples it supports.
The demos themselves are written once, in [`examples/uferris-demos/`](examples/uferris-demos/): every board runs the same code against the generic board API.
A board's `src/bin/*.rs` only brings the controller up, opens whatever console it has, and hands both to the shared demo.
| Xiao ESP32-C3 | [`examples/xiao-esp32-c3/`](examples/xiao-esp32-c3/) |
| Xiao ESP32-C5 | [`examples/xiao-esp32-c5/`](examples/xiao-esp32-c5/) |
| Xiao ESP32-C6 | [`examples/xiao-esp32-c6/`](examples/xiao-esp32-c6/) |
| Xiao ESP32-S3 | [`examples/xiao-esp32-s3/`](examples/xiao-esp32-s3/) |
| Xiao nRF52840 | [`examples/xiao-nrf52840/`](examples/xiao-nrf52840/) |
| Xiao nRF54L15 | [`examples/xiao-nrf54l15/`](examples/xiao-nrf54l15/) |
| Xiao RP2040 | [`examples/xiao-rp2040/`](examples/xiao-rp2040/) |
| Xiao RP2350 | [`examples/xiao-rp2350/`](examples/xiao-rp2350/) |
## Running Examples
Run any example with:
```
cd examples/<board>
cargo run --bin <example>
```
For example, to run `blinky.rs` on a Xiao ESP32-C3:
```bash
cd examples/xiao-esp32-c3
cargo run --bin blinky
```
Use `cargo build --bin <example>` if you only want to compile without flashing.
## AI use
This project accepts AI-assisted contributions under conditions. Before opening a
pull request, read [AI_POLICY.md](AI_POLICY.md). To summarize, AI as a tool is
fine, but you must understand and be able to explain everything you submit; a
human must be the interface for all contributions; disclosure is required in the
PR template, and every change must state how it was verified. Autonomous agent
submissions will be closed.
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
---
Made with 🦀