core-s3
Rust board support package for the M5Stack CoreS3 K128 (ESP32-S3) with optional support for an M5Stack Gateway H2 Thread/Zigbee co-processor.
The crate is intentionally #![no_std] and keeps the reusable BSP layer small:
- board metadata and pin/device maps for CoreS3 peripherals
- display constants and a dirty-region sprite framebuffer for efficient partial repainting
- power/battery status types ready for AXP2101 integration
- feature-gated Gateway H2 metadata and UART bring-up behind
gateway-h2 - example firmware crates and CI/release automation
Hardware note: pin maps are scaffolded from the supplied CoreS3 materials and should be validated on the exact CoreS3/base stack revision before relying on every peripheral in production.
Repository layout
crates/core-s3/ no_std BSP crate
examples/hello_world/ minimal ESP32-S3 firmware skeleton
examples/dirty_regions/ display sprite example
examples/dual_core/ PRO CPU + APP CPU example
examples/gateway_h2/ Gateway H2 UART + Matter/Thread scaffold example
.github/workflows/ PR validation and firmware release
Features
| Feature | Description |
|---|---|
defmt |
Enables defmt formatting for supported dependencies. |
gateway-h2 |
Exposes core_s3::gateway_h2, Gateway H2 metadata, BSP UART bring-up, and Matter-over-Thread configuration types. |
Display dirty-region sprite
core_s3::display::DirtySprite stores an off-screen framebuffer and tracks only changed rectangles. Drawing through embedded-graphics marks dirty regions automatically; flush_dirty / flush_dirty_at then blit only final pixels for the changed regions into the real display target, avoiding visible clear-then-redraw flashes.
use DirtySprite;
use ;
type FullscreenSprite = 320 * 240 }, 32>;
let mut sprite = new?;
new
.into_styled
.draw
.unwrap;
// Later, once a concrete LCD DrawTarget is configured:
// sprite.flush_dirty(&mut display)?;
# Ok::
For RAM-sensitive UI, prefer smaller per-widget sprites and compose them into the panel.
Building
Install the ESP Rust toolchain with espup, then:
Flash an example with cargo-embed:
# or, through the workspace alias:
Embed.toml is configured for the ESP32-S3 target and probe-rs flashing. If you have more than one compatible probe connected, set the probe VID/PID locally in Embed.toml.
Matter over Thread with Gateway H2
Enable gateway-h2 to use Gateway H2 metadata, the crate-owned CoreS3-to-H2 UART bring-up helper, and Matter-over-Thread setup configuration types. The BSP intentionally does not depend on or re-export a Matter stack: firmware crates should depend on rs-matter or another Matter implementation directly and own their concrete Matter server.
Gateway H2 firmware is commonly OpenThread RCP/Spinel, OpenThread CLI, or a standalone Thread/Zigbee application depending on what is flashed to the ESP32-H2. It is not assumed to be an AT-command modem. The BSP initializes the host UART transport; consumer firmware is responsible for the concrete H2 protocol driver, Thread joining/commissioning flow, Matter endpoints, persistence, and Home Assistant behavior.
For Home Assistant validation, a Raspberry Pi 5 running Home Assistant OS also needs a Thread Border Router/radio, such as Home Assistant Connect ZBT-1/SkyConnect or another supported OpenThread Border Router. This crate can provide the CoreS3 device side, but Home Assistant will only discover it once consumer firmware runs a real Matter server over a Thread network visible to Home Assistant.
[]
= { = "0.1", = ["gateway-h2"] }
use ;
let gateway = GROVE_UART;
let matter = new;
let thread = new;
let setup = new;
# let _ = setup;
Dual-core support
ESP32-S3 has two Xtensa LX7 cores: the PRO CPU starts main, and the APP CPU can be started by firmware. This BSP supports both cores through esp-hal's CpuControl API; see examples/dual_core for a minimal example that starts the APP CPU with its own stack and shares state through a critical-section mutex.
Release workflow
Pushing a tag like v0.1.0 runs .github/workflows/release.yml, builds release firmware, converts each example to an ESP32-S3 .bin image with espflash save-image, and publishes only .bin firmware artifacts.