Skip to main content

Crate uferris_bsp

Crate uferris_bsp 

Source
Expand description

§uFerris Board Support Package Crate

uFerris is a flexible Rust embedded learning kit that can accomodate several SeeedStudio Xiao controllers. uFerris is essentially a carrier board that can accomodate mutliple different controllers.

The uferris-bsp crate provides a generic Board Support Package for the uFerris carrier board. As such, uferris-bsp is architecture-agnostic and can support for several MCUs (ESP32, RP2040…etc.) Controller support is provided via feature flags.

In summary, this crate is meant to provide a software abstraction to easily drive the uFerris board with any supported Xiao Controller.

§Crate Architechture

The uFerris BSP architechture follows the layered scheme shown in the figure below. The upper uFerris board logic layer is meant to provide a hardware agnositc uniform interface across all Xiao controllers. The second adapter layer is introduced to create the mappings between the logic and the individual device HALs. The adapter layer also utilizes the embedded-hal traits where possible. In most cases the controller HALs provide implementations for embedded-hal traits.

§Currently Supported Xiaos:

  • Xiao ESP32-C3
  • Xiao ESP32-C5 (buzzer stubbed - no PWM driver in esp-hal yet)
  • Xiao ESP32-C6
  • Xiao ESP32-S3
  • Xiao nRF52840 (and nRF52840 Sense)
  • Xiao nRF54L15 (and nRF54L15 Sense)
  • Xiao RP2040
  • Xiao RP2350

§async Support

The async feature enables the async board API. Uferris carries a Mode type parameter that selects which set of methods it exposes: Blocking, the default, is the API described above and is what every existing program already gets, and Async is the same board with the I2C and ADC operations turned into async fns plus Uferris::wait_for_sw5, which suspends until button 5 is pressed instead of spinning on it.

The executor and the time driver are the application’s responsibility. The BSP starts neither: it hands back a board whose methods are futures, and the program decides what runs them and where its delays come from. A board opts in by exposing an uferris_init_async alongside its blocking uferris_init, and all eight supported Xiaos now have one.

The ESP boards differ in one respect, because their runtime does. esp-rtos is started from two peripherals — TIMG0 and SW_INTERRUPT — that live in the same esp_hal::Peripherals struct their uferris_init_async consumes whole, and its thread mode executor cannot suspend a task before the scheduler is running. Their init is therefore synchronous, and hands those two peripherals back next to the board so that the application can start the scheduler with them before its first .await. See any of the ESP board modules for the details.

§Contributing to the uFerris BSP - Adding a New Xiao Board Support:

Adding support for a new Xiao board entails two parts:

  1. Device Feature Flag in Cargo.toml: A feature flag that imports the new device HAL needs to be added.
  2. Device Board Adapter: This entails adding a new board definition (adapter layer) under the crate boards/ folder.

Other files in the crate should remain unchanged. It is recommended to view the existing board implementations for guidance on creating an adapter layer.

§Feature Flags

⚠️ At least one Xiao device feature must be enabled when building the crate.

  • xiao-esp32c3 — Xiao ESP32-C3 Device Support
  • xiao-esp32c5 — Xiao ESP32-C5 Device Support
  • xiao-esp32c6 — Xiao ESP32-C6 Device Support
  • xiao-esp32s3 — Xiao ESP32-S3 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
  • power-board — uFerris Megalops Power Board Extension Support
  • asyncasync Support Feature Flag. Enables the async board API — the Uferris<.., Async> mode, whose I2C and ADC operations are async fns. This is a pure code gate: the executor and the time driver are the application’s responsibility, the BSP starts neither. Every supported Xiao has an uferris_init_async next to its blocking uferris_init.

§Usage

The abstractions in this crate are designed in a way where they are common for any Xiao device. The only difference is that the correct controller board needs to be chosen as a feature. The steps to use this crate include the following:

1- Import the board init function:

use uferris_bsp::uferris_init;

2- Acquire the controller peripherals and pass them to initialize the board:

let mut uferris = uferris_init(peripherals);

3- Use the board methods:

// Turn on LED 1 on the board
uferris.led1_on();

If no device feature is enabled, only the generic board API is available — uferris_init requires selecting your Xiao’s feature. This is what code written against the board API alone, without a controller in the picture, builds against.

Re-exports§

pub use components::io_expander::SwPos;
pub use crate::components::io_expander::SevenSegDigit;
pub use boards::xiao_esp32c3::uferris_init;
pub use boards::xiao_esp32c3::uferris_init_async;

Modules§

boards
components

Structs§

Async
The async board API: the I2C and ADC operations are async fns.
Blocking
The blocking board API: every method returns its result directly.
Uferris
The uFerris Board Driver.

Enums§

InitError

Traits§

Mode
Which flavour of the board API a Uferris exposes.
PowerConstraints