nesso 0.0.5

Rust SDK facade for Arduino Nesso N1 on ESP32-C6.
Documentation

nesso-rs

nesso-rs is a Rust-native SDK for the Arduino Nesso N1, an ESP32-C6 based device with display, touch, IMU, Wi-Fi, audio, and battery/power-management hardware and optional external unit support for Nesso-compatible expansion sensors such as M5Stack Unit ENV Pro.

The public crate is nesso. The repository is a Cargo workspace for examples and validation, but only the nesso crate is published to crates.io.

Status

This project is an early hardware-validated SDK foundation.

This SDK targets only the Arduino Nesso N1. It intentionally does not provide a generic board abstraction layer, an M5Stack compatibility layer, or support for other ESP32-C6 boards.

Validated examples currently cover:

  • ST7789P3 display initialization and text rendering
  • FT6336U touch reads
  • BMI270 IMU live axis reads
  • KEY1/KEY2 button events
  • Passive buzzer tone output
  • BQ27220/AW32001 battery and charger status reads
  • Heapless settings storage
  • ESP32-C6 Wi-Fi scan/connect/disconnect lifecycle and embassy-net interface handoff using esp-radio
  • ESP32-C6 BLE controller lifecycle with a connectable GATT peripheral example and notification-mirroring GATT surface
  • Motion/context helpers derived from BMI270 acceleration samples
  • Lightweight layout, text, progress, transition, and sprite helpers
  • M5Stack Unit ENV Pro BME688 environmental reads over I2C/Qwiic
  • Board information display

Installation

Add the public facade crate:

cargo add nesso

Enable Wi-Fi only for applications that use the ESP32-C6 radio:

cargo add nesso --features wifi
cargo add esp-alloc

Enable ENV Pro support only for applications that use the external unit:

cargo add nesso --features env

Enable BLE only for applications that use the ESP32-C6 Bluetooth controller:

cargo add nesso --features ble
cargo add esp-alloc

Public Modules

  • nesso::Nesso: public facade and shared board ownership.
  • nesso::bsp: Nesso N1 board constants, GPIOs, I2C addresses, and board-specific setup helpers.
  • nesso::display: ST7789P3 display driver with embedded-graphics integration.
  • nesso::env: external environmental unit support, gated behind the env feature.
  • nesso::ble: ESP32-C6 BLE controller lifecycle and HCI handoff, gated behind the ble feature.
  • nesso::touch: FT6336U touch controller support.
  • nesso::input: button event state machine helpers.
  • nesso::imu: BMI270 initialization, config upload, and sensor reads.
  • nesso::motion: coarse motion and pose helpers built from accelerometer samples.
  • nesso::audio: passive buzzer output and blocking tone generation.
  • nesso::power: BQ27220 fuel gauge and AW32001 charger status support.
  • nesso::wifi: ESP32-C6 Wi-Fi station lifecycle support and network interface handoff for application-owned network stacks, gated behind the wifi feature.
  • nesso::storage: heapless settings storage primitives and esp-storage flash-backed persistence.
  • nesso::sprite: caller-owned RGB565 sprite/framebuffer support for flicker-free dirty-region rendering.
  • nesso::ui: small embedded-graphics layout, label, progress, and transition helpers.

Examples

Each public module has one focused hardware or module-validation example:

Module Example
nesso::Nesso hello_world
nesso::bsp board_info
nesso::display display_test
nesso::touch touch_test
nesso::input input_test
nesso::imu imu_test
nesso::motion motion_test
nesso::audio audio_test
nesso::power battery_test
nesso::wifi wifi_scan, wifi_net_stack
nesso::ble ble_peripheral, ble_beacon, ble_notifications
nesso::storage storage_test
nesso::ui ui_test
nesso::env env_pro_test

Example

The facade owns the fixed Nesso N1 wiring. Applications initialize ESP-HAL once, then hand the peripherals to Nesso::new.

#![no_std]
#![no_main]

use embedded_graphics::{pixelcolor::Rgb565, prelude::RgbColor};
use embedded_hal::delay::DelayNs;
use esp_hal::{clock::CpuClock, delay::Delay, main};
use nesso::Nesso;

#[main]
fn main() -> ! {
    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
    let peripherals = esp_hal::init(config);
    let mut delay = Delay::new();
    let mut nesso = match Nesso::new(peripherals) {
        Ok(nesso) => nesso,
        Err(_) => esp_hal::system::software_reset(),
    };

    if nesso.display.clear(Rgb565::BLACK).is_err()
        || nesso
            .display
            .print_centered("Hello from nesso-rs", 120, Rgb565::WHITE)
            .is_err()
    {
        esp_hal::system::software_reset()
    }

    loop {
        delay.delay_ms(1000);
    }
}

See examples/ for hardware-focused examples.

Wi-Fi is behind the optional wifi feature and is initialized lazily with nesso.init_wifi(). Only applications that enable Wi-Fi need to compile esp-radio/esp-rtos and provide an esp_alloc heap for the ESP radio stack. Applications that need TCP/IP create their own embassy-net stack by calling wifi.take_interfaces() and passing interfaces.station to embassy-net. The SDK continues to own station control through the same EspRadioWifi value. HTTP, NTP, DNS, weather APIs, and other protocols belong in application crates.

BLE is behind the optional ble feature and is initialized lazily with nesso.init_ble(). The SDK owns board/controller bring-up and can hand the HCI connector to a host stack. The ble_peripheral example uses Trouble to advertise as Nesso N1 and exposes a small custom GATT service that can be inspected with nRF Connect. The ble_beacon example rotates passive non-connectable advertising payloads using nesso::ble::BeaconSchedule. The ble_notifications example accepts app|title|body writes on the Nesso mirror characteristic and displays the latest mirrored phone/app notification.

Build

Install Rust with the target specified in rust-toolchain.toml, then run:

cargo metadata --no-deps --format-version 1
cargo fmt --check --all
cargo clippy --workspace --all-targets -- -D warnings
cargo check --workspace
cargo build --workspace
cargo build --workspace --release

Flashing Examples

Build and flash an example with espflash:

cargo build -p hello_world --release
espflash flash --chip esp32c6 -p /dev/cu.usbmodem1101 \
  target/riscv32imac-unknown-none-elf/release/hello_world

Change the serial port for your host.

Documentation

Hardware and architecture notes are kept in docs/:

  • docs/hardware.md
  • docs/architecture.md
  • docs/m5gfx-analysis.md
  • docs/gap-analysis.md
  • docs/roadmap.md

Release Process

Releases are published from GitHub Releases.

  1. Merge through a pull request to main.
  2. Create and push the release tag.
  3. Publish a GitHub Release for that tag.

The release workflow validates the workspace and publishes only the public nesso crate to crates.io.

The workflow uses crates.io trusted publishing and does not require a long-lived Cargo registry token.

License

Licensed under the MIT License. See the LICENSE file.