nesso
nesso is a Rust-native no_std SDK for the Arduino Nesso N1, an ESP32-C6
based device with display, touch, IMU, Wi-Fi, BLE, LoRa, audio, and
battery/power-management hardware plus 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.
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, orientation, text rendering, and partial sprite updates
- orientation-aware touch mapping and generic input event helpers
- FT6336U touch reads
- BMI270 IMU live axis reads
- KEY1/KEY2 button events
- Passive buzzer tone output with blocking and non-blocking queued playback
- BQ27220/AW32001 battery and charger status reads
- Heapless settings storage
- ESP32-C6 Wi-Fi scan/connect/disconnect lifecycle and
embassy-netinterface handoff usingesp-radio - ESP32-C6 BLE controller lifecycle with a connectable GATT peripheral example and notification-mirroring GATT surface
- SX1262 LoRa construction, safe no-TX bring-up, receive mode, and explicitly gated transmit example
- Motion/context helpers derived from BMI270 acceleration samples
- Lightweight layout, text, progress, transition, shape, and sprite helpers
- M5Stack Unit ENV Pro BME688 environmental reads over I2C/Qwiic
- Board information display
Installation
Add the public facade crate:
[]
= "0.2.1"
Enable Wi-Fi only for applications that use the ESP32-C6 radio:
[]
= { = "0.2.1", = ["wifi"] }
= "0.10"
Enable ENV Pro support only for applications that use the external unit:
[]
= { = "0.2.1", = ["env"] }
Enable BLE only for applications that use the ESP32-C6 Bluetooth controller:
[]
= { = "0.2.1", = ["ble"] }
= "0.10"
Enable onboard SX1262 LoRa support only for applications that use the LoRa transceiver:
[]
= { = "0.2.1", = ["lora"] }
Enable defmt formatting only for applications that use defmt logging:
[]
= { = "0.2.1", = ["defmt"] }
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 withembedded-graphicsintegration.nesso::env: external environmental unit support, gated behind theenvfeature.nesso::ble: ESP32-C6 BLE controller lifecycle and HCI handoff, gated behind theblefeature.nesso::lora: onboard SX1262 LoRa transceiver support, gated behind thelorafeature.nesso::runtime: explicit ESP radio runtime startup helpers for Wi-Fi/BLE async applications.nesso::touch: FT6336U touch controller support.nesso::input: button event and touch gesture 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 with blocking and queued non-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 thewififeature.nesso::storage: heapless settings storage primitives andesp-storageflash-backed persistence.nesso::sprite: caller-owned RGB565 sprite/framebuffer support, sprite region iterators, and dirty-region flushing.nesso::ui: smallembedded-graphicslayout, label, progress, and transition helpers plus generic shape primitives.
Examples
Public modules have focused hardware or module-validation examples:
| Module | Example |
|---|---|
nesso::Nesso |
hello_world |
| composed facade usage | dashboard |
nesso::bsp |
board_info |
nesso::display |
display_test, display_orientation |
nesso::touch |
touch_test |
nesso::input |
input_test, input_events |
nesso::imu |
imu_test |
nesso::motion |
motion_test, motion_status |
nesso::audio |
audio_test, queued_audio |
nesso::power |
battery_test, power_status |
nesso::wifi |
wifi_scan, wifi_net_stack |
nesso::ble |
ble_peripheral, ble_beacon, ble_notifications, ble_notification_mirror |
nesso::lora |
lora_info, lora_receive, lora_send |
nesso::storage |
storage_test, storage_settings |
nesso::ui |
ui_test |
nesso::sprite |
dirty_regions |
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. This example initializes the display,
enables battery charging, initializes the IMU, and renders live board state.
use ;
use DelayNs;
use ;
use ;
!
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.
Async applications that use Wi-Fi, BLE, or both can call
nesso.start_async_runtime() before creating radio controllers so task startup
ordering is explicit.
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.
LoRa is behind the optional lora feature. When enabled, nesso.lora is
available alongside nesso.display; the BSP shares the documented SPI bus using
embedded-hal-bus with separate chip-select pins. Nesso::new does not start
transmission or place the SX1262 in TX mode. Attach the external LoRa antenna
before using Sx1262::transmit. The lora_send example is compile-time gated
and will not transmit unless built with NESSO_LORA_ALLOW_TX=1.
Build
Install Rust with the target specified in rust-toolchain.toml, then run:
( && )
( && )
The host test harness exercises reusable logic that does not require hardware: notification parsing, Wi-Fi credential validation, settings serialization and checksum handling, dirty-region coalescing, touch orientation mapping, input events, touch and power I2C parsing, queued audio behavior, motion classification, power helpers, and generic graphics helpers.
Flashing Examples
Build and flash an example with espflash:
Change the serial port for your host.
Documentation
Hardware and architecture notes are kept in docs/:
docs/hardware.mddocs/architecture.mddocs/m5gfx-analysis.mddocs/gap-analysis.mddocs/roadmap.mdHARDWARE_VALIDATION.md
Release maintainers should also use HARDWARE_VALIDATION.md before publishing
a new release. It is the board-run checklist for examples and peripherals that
cannot be fully validated by CI.
Release Process
Releases are published from GitHub Releases.
- Merge through a pull request to
main. - Run the software validation commands from the build section.
- Run the board checklist in
HARDWARE_VALIDATION.mdon a connected Nesso N1. - Create and push the release tag.
- 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.