velxio/test/test_epaper/autosearch/07_emulation_plan.md

5.9 KiB
Raw Blame History

07 — Phased emulation plan

North-star architecture

One Web Component, one simulation hook, one state machine — parameterised by panel kind. The state machine internally branches per controller family (SSD168x, UC81xx, Spectra6) but exposes a single metadataId = 'epaper-<panel-kind>' for ComponentRegistry.

┌─────────────────── frontend/src/components/velxio-components ──────────────┐
│                                                                             │
│   EPaperElement.ts          (Web Component <velxio-epaper panel-kind=…>)    │
│   EPaper.tsx                (React wrapper — thin)                          │
│                                                                             │
└──────────────────────────────────┬──────────────────────────────────────────┘
                                   │ pinInfo + canvas
                                   ▼
┌────────────────── frontend/src/simulation/parts/EPaperPart.ts ─────────────┐
│                                                                             │
│   const familyDecoders = {                                                  │
│     'ssd168x': new SSD168xDecoder(panel),                                   │
│     'uc81xx':  new UC81xxDecoder(panel),                                    │
│     'spectra6': new Spectra6Decoder(panel),                                 │
│   }                                                                         │
│                                                                             │
│   spi.onByte = (b) => decoder.feed(b, dcState)                              │
│   onActivate() → composeAndFlush() → pulseBusy(REFRESH_MS)                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Phase 1 — SSD168x mono (1.54", 2.13", 2.9", 4.2", 7.5")

Smallest scope that ships something useful. Five metadata IDs, one decoder, one Web Component.

Deliverables:

  1. EPaperElement.ts — Web Component supporting panel-kindepaper-1in54-bw | epaper-2in13-bw | epaper-2in9-bw | epaper-4in2-bw | epaper-7in5-bw. SVG body + active area canvas + FPC pins.
  2. EPaper.tsx — React wrapper, forwards canvas readiness via canvas-ready custom event (mirrors ILI9341).
  3. EPaperPart.ts — registers all 5 metadata IDs with the same ssd168x decoder + a per-panel resolution + bezel config.
  4. ComponentRegistry.ts — wire the IDs.
  5. Library auto-install: ensure GxEPD2 + Adafruit_GFX trigger via the sketch's #include.
  6. Pixel-buffer fingerprint test (one per panel size).

Decoder scope: the 17 SSD168x commands listed in 02_controllers.md × two RAM planes × the 0x20 ACTIVATION trigger. Anything else (LUT writes 0x32, gate driving voltage 0x03, etc.) is silently consumed so the init sequence completes without warnings.

Acceptance test:

  • Compile GxEPD2_HelloWorld.ino for the 1.54" panel against ESP32, Pi Pico, and Arduino Uno. Compile success on all three.
  • Run on ESP32 + Pi Pico in the simulator. After ~50 ms BUSY pulse the canvas shows "Hello World" with a sharp 200×200 buffer.

Phase 2 — Tri-colour SSD168x (B/W/Red 2.13" + 2.9")

Reuses 90% of Phase 1. Adds:

  • Two-plane composition (0x24 black + 0x26 red).
  • Two new metadata IDs: epaper-2in13-bwr, epaper-2in9-bwr.
  • Web Component palette change.

Phase 3 — UC81xx (4.2" UC8176, 7.5" UC8179, 5.65" 7-colour ACeP UC8159c)

New decoder. Different command set (0x10 DTM1, 0x12 DRF, etc.) but same wiring + same Web Component. Scope:

  • UC81xxDecoder.ts for mono 4.2" / 7.5".
  • ACePDecoder.ts for 7-colour 5.65" (4 px / byte palette).

Phase 4 — Spectra 6 (the user's 13.3" 1200×1600)

New decoder; different command set again. Slowest refresh (12 s real, emulator default 200 ms). Massive framebuffer (1.2 MB raw at 6 colours; ~470 KB packed) — make sure the canvas downscales properly for gallery preview thumbnails.

Phase 5 — IT8951 (Carta 6"10.3" greyscale)

Different beast. Command-packet protocol over SPI. Deferred until a concrete user asks.

Out-of-scope forever (probably)

  • LUT-driven custom waveforms — accept silently, never validate.
  • Real-time partial-window updates — Phase 1 just full-frames.
  • Capacitive touch overlay — different component (EPD has no touch panel built in; touch is an upper layer in some bundles like Waveshare's CFAF).

Risk register

Risk Mitigation
GxEPD2 + Adafruit_GFX too big for AVR (Uno) at 4.2"+ Ship the small panels (1.54", 2.13") for AVR; the rest get an "AVR not supported" hint in the Library Manager modal.
Spectra 6 reverse-engineering may be incomplete Ship Phase 13 first; Spectra 6 can land after we capture real SPI traces from a Seeed EE02 via Saleae and adjust.
BUSY emulation timing too short → firmware loops never see HIGH Default to 50 ms refresh. Add a refresh-ms attribute on the Web Component.
Controller silently differs across panel revisions Fingerprint commands: log to chip_log events whenever an unknown opcode is seen so users can report panel quirks.

What can ship today

Just the dossier (this folder), a couple of pure-state-machine Python unit tests (next file), and one canonical sketch in sketches/. Real emulator code is a separate PR — explicitly deferred until the user greenlights phase 1.