Files
ruvnet--ruview/docs/adr/ADR-045-amoled-display-support.md
wehub-resource-sync 9740bc64c9
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier1) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (full-adr060) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (tdm-3node) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / Swarm Test (ADR-062) (push) Has been skipped
npm packages / tools/ruview-mcp (node 22) (push) Failing after 1s
nvsim-server → ghcr.io / build-and-publish (push) Failing after 1s
ruview-swarm CI guard / tests (full+train) (push) Failing after 2s
Bench Regression Guard / bench compile-verify (--no-run) (push) Failing after 0s
Bench Regression Guard / bench fast-run (informational, non-gating) (push) Has been skipped
Firmware CI / Verify version.txt matches release tag (push) Has been skipped
Dashboard a11y + cross-browser / a11y (push) Failing after 0s
nvsim Dashboard → GitHub Pages / build-and-deploy (push) Failing after 2s
Firmware CI / Build firmware (esp32s3 / 4mb) (push) Failing after 15s
Firmware QEMU Tests (ADR-061) / Build Espressif QEMU (push) Failing after 1s
Firmware QEMU Tests (ADR-061) / Fuzz Testing (ADR-061 Layer 6) (push) Failing after 1s
Continuous Deployment / Pre-deployment Checks (push) Has been skipped
Firmware CI / Build firmware (esp32c6 / c6-4mb) (push) Failing after 15s
Firmware CI / Build firmware (esp32s3 / 8mb) (push) Failing after 15s
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-max) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (boundary-min) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (default) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / QEMU Test (edge-tier0) (push) Has been skipped
Firmware QEMU Tests (ADR-061) / NVS Matrix Generation (push) Failing after 1s
Security Scanning / Security Policy Compliance (push) Failing after 0s
Security Scanning / Dependency Vulnerability Scan (push) Failing after 0s
Security Scanning / Static Application Security Testing (push) Failing after 1s
Security Scanning / Infrastructure Security Scan (push) Failing after 1s
Security Scanning / Secret Scanning (push) Failing after 1s
npm packages / harness/ruview (node 22) (push) Failing after 17s
Security Scanning / License Compliance Scan (push) Failing after 1s
Security Scanning / Container Security Scan (push) Failing after 4s
three.js demos → GitHub Pages / build-and-deploy (push) Failing after 1s
Verify Pipeline Determinism / Verify Pipeline Determinism (3.11) (push) Failing after 1s
Fix-Marker Regression Guard / Verify fix markers (push) Failing after 1s
ADR-115 MQTT integration tests / mqtt-integration (push) Failing after 1s
npm packages / harness/ruview (node 20) (push) Failing after 1s
npm packages / tools/ruview-mcp (node 20) (push) Failing after 1s
npm packages / tools/ruview-cli (node 20) (push) Failing after 1s
npm packages / tools/ruview-cli (node 22) (push) Failing after 1s
BFLD MQTT Integration / cargo test --features mqtt (live mosquitto) (push) Failing after 29s
ruview-swarm CI guard / build train_marl bin (push) Failing after 2s
ruview-swarm CI guard / clippy (-D warnings, --no-deps) (push) Failing after 3s
ruview-swarm CI guard / tests (ruflo) (push) Failing after 1s
ruview-swarm CI guard / tests (train) (push) Failing after 2s
ruview-swarm CI guard / tests (default) (push) Failing after 2s
Point Cloud Viewer → GitHub Pages / build-and-deploy (push) Failing after 8s
ruview-swarm CI guard / ITAR / publish guard (push) Failing after 0s
wifi-densepose sensing-server → Docker Hub + ghcr.io / build · push · smoke-test (push) Failing after 1s
Continuous Deployment / Deploy to Production (push) Has been cancelled
Continuous Deployment / Rollback Deployment (push) Has been cancelled
Continuous Deployment / Post-deployment Monitoring (push) Has been cancelled
Continuous Deployment / Notify Deployment Status (push) Has been cancelled
Continuous Deployment / Deploy to Staging (push) Has been cancelled
Security Scanning / Security Report (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 11:59:54 +08:00

3.9 KiB

ADR-045: AMOLED Display Support for ESP32-S3 CSI Node

Status

Proposed

Context

The ESP32-S3 board (LilyGO T-Display-S3 AMOLED) has an integrated RM67162 QSPI AMOLED display (536x240) and 8MB octal PSRAM that were unused by the CSI firmware. Users want real-time on-device visualization of CSI statistics, vital signs, and system health without relying on an external server.

Constraints

  • Binary was 947 KB in a 1 MB partition — needed 8MB flash + custom partition table
  • SPIRAM was disabled in sdkconfig despite hardware having 8MB PSRAM
  • Core 1 is pinned to DSP (edge processing) — display must use Core 0
  • Existing CSI pipeline must not be affected

Available APIs

Thread-safe edge APIs already exist (edge_get_vitals(), edge_get_multi_person()) — the display task only reads from these, no new synchronization needed.

Decision

Add optional AMOLED display support with the following architecture:

Hardware Abstraction Layer

  • display_hal.c/h: RM67162 QSPI panel driver + CST816S capacitive touch via I2C
  • Auto-detect at boot: probe RM67162 and check SPIRAM; log warning and skip if absent

UI Layer

  • display_ui.c/h: LVGL 8.3 with 4 swipeable views via tileview widget
  • Dark theme (#0a0a0f) with cyan (#00d4ff) accent for three.js-like aesthetic
  • Views: Dashboard (CSI amplitude chart + stats), Vitals (breathing + HR line graphs), Presence (4x4 occupancy grid), System (CPU, heap, PSRAM, WiFi, uptime, FPS)

Task Layer

  • display_task.c/h: FreeRTOS task on Core 0, priority 1 (lowest)
  • LVGL pump loop at configurable FPS (default 30)
  • Double-buffered draw buffers allocated in SPIRAM

Compile-Time Control

  • CONFIG_DISPLAY_ENABLE=y (default): compiles display code, auto-detects hardware at boot
  • CONFIG_DISPLAY_ENABLE=n: zero-cost — no display code compiled
  • CONFIG_SPIRAM_IGNORE_NOTFOUND=y: boots fine on boards without PSRAM

Flash Layout

8MB partition table (partitions_display.csv):

  • Dual OTA partitions: 2 x 2MB (supports larger binaries with LVGL)
  • SPIFFS: 1.9MB (for future font/asset storage)
  • NVS + otadata + phy: standard sizes

Core/Task Layout

Task Core Priority Impact
WiFi/LwIP 0 18-23 unchanged
OTA httpd 0 5 unchanged
display_task 0 1 NEW — lowest priority
edge_task (DSP) 1 5 unchanged

Dependencies

  • LVGL ~8.3 (via ESP-IDF managed components)
  • espressif/esp_lcd_touch_cst816s ^1.0
  • espressif/esp_lcd_touch ^1.0

Consequences

Positive

  • Real-time on-device stats without network dependency
  • Zero impact on CSI pipeline (display reads thread-safe APIs, runs at lowest priority)
  • Graceful degradation: works on boards without display or PSRAM
  • SPIRAM enabled for all boards (benefits WASM runtime too)
  • 8MB flash + dual OTA 2MB partitions give headroom for future features

Negative

  • Binary size increase (~200-300 KB with LVGL)
  • SPIRAM + 8MB flash config is specific to T-Display-S3 AMOLED boards
  • Boards with only 4MB flash need CONFIG_DISPLAY_ENABLE=n and the old partition table

Risks

  • RM67162 init sequence is board-specific; other AMOLED panels may need different commands
  • QSPI bus conflicts if other peripherals use SPI2_HOST (currently unused)

New Files

File Purpose
main/display_hal.c/h RM67162 QSPI + CST816S touch HAL
main/display_ui.c/h LVGL 4-view UI
main/display_task.c/h FreeRTOS task, LVGL pump
main/lv_conf.h LVGL compile config
partitions_display.csv 8MB partition table
idf_component.yml Managed component deps

Modified Files

File Change
sdkconfig.defaults 8MB flash, SPIRAM, custom partitions
main/CMakeLists.txt Conditional display sources + deps
main/main.c +1 include, +5 lines guarded init
main/Kconfig.projbuild "AMOLED Display" menu