Noureddine RAMDI / Waveshare Watch Rust firmware: efficient no_std embedded Rust for ESP32-S3 AMOLED smartwatch

Created Mon, 04 May 2026 10:23:02 +0000 Modified Sat, 23 May 2026 20:41:27 +0000

infinition/waveshare-watch-rs

The Waveshare ESP32-S3-Touch-AMOLED-2.06 smartwatch runs on a surprisingly complex hardware platform, yet the original firmware shipped with a layered C/C++ stack mixing ESP-IDF, Arduino graphics, and LVGL UI components. This repo rewrites the entire firmware in Rust, targeting a no_std environment with a single binary that handles display, input, sensors, power management, and apps. What stands out is its event-driven architecture that keeps the CPU asleep over 99% of the time on the watchface, a significant win for battery life on a smartwatch.

Firmware architecture and hardware stack

This project replaces the original mixed C/C++ firmware with a pure Rust codebase built on the esp-hal 1.0 hardware abstraction layer, esp-rtos, and the Embassy async runtime. The no_std environment is critical here — it means the firmware runs without the standard Rust library, which is typical for embedded systems to reduce footprint and avoid dynamic memory.

The display is a 410x502 QSPI AMOLED driven at 80MHz using DMA, with PSRAM-backed double-buffered framebuffers to smooth graphics rendering without blocking the CPU. This is a demanding setup, especially with the need to balance power and responsiveness.

Custom drivers are implemented for all peripherals: the AXP2101 power management IC, FT3168 touch controller, QMI8658 IMU, PCF85063A real-time clock, ES8311 audio codec, and an SD card interface. Managing all these devices in Rust with no_std and async runtime requires careful hardware abstraction and concurrency control.

The event-driven design utilizes GPIO interrupts and adaptive timer ticks, which let the CPU sleep most of the time. This is crucial for battery-powered wearables, as it reduces power consumption drastically compared to polling or busy loops.

The firmware includes a launcher with several mini-applications such as games, a T9 keyboard, an MP3 player UI, a SmartHome HTTP app, and an Apple Watch-inspired Always-On Display mode that leverages AMOLED pixel-off capabilities for power savings.

What distinguishes the firmware: async no_std design and power management

The firmware’s core strength lies in combining no_std Rust with the Embassy async runtime to create an event-driven system that avoids CPU wakeups except when necessary. Achieving >99% CPU sleep on the watchface is a notable benchmark in embedded firmware.

This is accomplished by using GPIO interrupts to wake the CPU only on input or peripheral events, and adaptive timer ticks to schedule work without wasting cycles. The display pipeline uses DMA to offload rendering transfers, freeing the CPU.

The power management is sophisticated: it implements four levels of display power states including an AMOLED pixel-off Always-On Display (AOD) mode, which helps extend battery life while keeping the display readable.

The codebase is opinionated, focusing on zero dependencies beyond essential HALs and runtime. It avoids the complexity and memory overhead of the original C/C++ stack by consolidating everything into a single binary written in idiomatic Rust.

The custom peripheral drivers demonstrate deep hardware knowledge, with drivers for power management, touch sensing, motion sensors, audio, and storage all written to work seamlessly in an async environment without blocking.

Tradeoffs include the steep learning curve of embedded async Rust and the hardware-specific nature of the code, which makes it less reusable for other platforms without significant adaptation. However, for ESP32-S3 based smartwatches, it offers a cleaner, more maintainable alternative to traditional firmware stacks.

Quick start

Prerequisites

  • Xtensa ESP Rust toolchain (installed via espup):
cargo install espup
espup install

rust-toolchain.toml pins channel = "esp".

  • MSVC linker (Windows): needed for host build scripts. Install “Desktop development with C++” via Visual Studio Installer. The link.exe must be in the PATH when running cargo. On this project typically:
export PATH="/c/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64:$PATH"
  • espflash:
cargo install espflash

WiFi credentials

SSID and password are read at compile-time via env!(). They must be defined before building.

verdict

This repo is a solid example of what embedded Rust can achieve on a complex MCU like the ESP32-S3 with an AMOLED display. Its event-driven async architecture and power management deliver impressive battery efficiency, making it relevant for embedded Rust developers aiming to build low-power wearable firmware.

The tradeoff is the significant complexity of no_std async Rust and hardware-specific drivers, which may limit reuse outside this particular board. It’s not a beginner-friendly project but offers valuable insights and code patterns for those committed to Rust embedded ecosystems.

Overall, if you want to build or understand efficient Rust firmware for resource-constrained smart devices, this repo is worth studying and experimenting with.


→ GitHub Repo: infinition/waveshare-watch-rs ⭐ 204 · Rust