docs(rust-port): correct display driver story + flag ST7796 tearing
- Split Kit (ST7796/SPI, custom port — mipidsi dropped) from Explorer
(ST7789V/8080 parallel) — they were wrongly lumped as 'ST7789 via mipidsi'.
- Add researched display-driver matrix (crates + status per controller).
- Mark Milestone 2 display 🟡: draws but TEARS; mipidsi confirmed to have
no TE/vsync/double-buffer support, module exposes no TE pin -> open item.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f564b75b1e
commit
713770232d
1 changed files with 41 additions and 6 deletions
|
|
@ -38,8 +38,39 @@ then doesn't care whether the target is a 17×7 mono matrix or a 320×480 colour
|
||||||
**Per-board binary crates — `pm-kit`, `pm-explorer`, `pm-grid`:** a thin `main.rs` BSP that
|
**Per-board binary crates — `pm-kit`, `pm-explorer`, `pm-grid`:** a thin `main.rs` BSP that
|
||||||
instantiates the right concrete drivers and hands them to the generic core:
|
instantiates the right concrete drivers and hands them to the generic core:
|
||||||
- **Grid** (Scroll Pack): IS31FL3731 over I²C (a `DrawTarget` for a 17×7 mono frame) + 4 GPIO buttons.
|
- **Grid** (Scroll Pack): IS31FL3731 over I²C (a `DrawTarget` for a 17×7 mono frame) + 4 GPIO buttons.
|
||||||
- **Explorer / Kit:** ST7789 via `mipidsi` + `embedded-graphics`; GT911 touch (Kit) over I²C; WS2812
|
- **Kit:** ST7796 320×480 over **SPI** — driven by a **custom `St7796` struct** (direct port of
|
||||||
via `ws2812-pio`; I²S to the PCM5102A via PIO.
|
`pico/main.py`), **not** mipidsi, which fought the panel's geometry/CS (see [[rust-st7796-cs-gotcha]]);
|
||||||
|
UI still renders through an `embedded-graphics` framebuffer. GT911 touch over I²C; WS2812 via
|
||||||
|
`ws2812-pio`; I²S to the PCM5102A via PIO.
|
||||||
|
- **Explorer:** ST7789V 320×240 over an **8-bit parallel (8080) bus** via `mipidsi`'s
|
||||||
|
`ParallelInterface` — a different driver story from the Kit's SPI (see the matrix below).
|
||||||
|
|
||||||
|
### Display driver matrix (researched 2026-06-03)
|
||||||
|
|
||||||
|
Displays are not the gate — every controller has a real Rust path; the buses differ:
|
||||||
|
|
||||||
|
| Form factor | Controller | Bus | Rust driver | Status |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| Kit (`pm-kit`) | ST7796 320×480 | SPI | **custom `St7796`** (port of `pico/main.py`) + `embedded-graphics` framebuffer; **mipidsi dropped** | ✅ on hardware — **but tearing** (see below) |
|
||||||
|
| Explorer (`pm-explorer`) | ST7789V 320×240 | 8-bit parallel 8080 | `mipidsi` `ParallelInterface` *(start here; be ready to port directly if geometry fights, as on the Kit)* | path proven upstream; not yet built |
|
||||||
|
| Grid (`pm-grid`) | IS31FL3731 17×7 mono | I²C | `is31fl3731` crate | 🟡 crate works (setup/fill/pixels); **no** `embedded-graphics` — write a ~30-line `DrawTarget` |
|
||||||
|
| Kit touch | GT911 | I²C | `gt911` or `gt9x` crate | ✅ mature (blocking + async, 5-point) |
|
||||||
|
|
||||||
|
**ST7796 (Kit) — only *partially* working: tearing.** Pixels are correct and the panel boots, but the
|
||||||
|
image tears badly. The cause is structural, not a bug: `mipidsi` has **no TE-pin / vsync / partial-update
|
||||||
|
/ double-buffer support** (confirmed against the upstream repo `github.com/almindor/mipidsi` — it offers
|
||||||
|
only optional draw *batching*), and this ST7796 module doesn't break out the TE (tearing-effect) line to
|
||||||
|
sync writes against scan-out. So writes race the panel's refresh. Mitigations available to us, none from
|
||||||
|
the crate: (a) redraw only changed full-width row-bands to shrink the tear window — already done; (b) DMA
|
||||||
|
each band as one tight burst; (c) sync to a TE GPIO *only if* a module that exposes that pin is sourced.
|
||||||
|
Treat tearing as an **open hardware/firmware item**, not "display done." See [[rust-st7796-cs-gotcha]].
|
||||||
|
|
||||||
|
**Explorer parallel bus — correctness and performance are decoupled.** `mipidsi`'s `ParallelInterface`
|
||||||
|
drives the data pins through an `OutputBus` *trait*. The shipped `Generic8BitBus` is plain GPIO bit-bang
|
||||||
|
(`embedded-hal` `OutputPin`s) — works immediately, just CPU-bound. For speed, implement `OutputBus` over
|
||||||
|
**RP2350 PIO** (the PIO supports 8080/6800 bus timing; the C/TFT_eSPI world hits ~4 ms for a full 320×480
|
||||||
|
clear this way) — a drop-in swap that leaves mipidsi + `embedded-graphics` + `pm-ui` untouched. Worst case
|
||||||
|
is "slow but functional," never "impossible," so the bit-bang fallback de-risks the whole Explorer bring-up.
|
||||||
|
|
||||||
**The honest caveat (what the Grid prototype is teaching us):** a 17×7 mono grid and a 320×480
|
**The honest caveat (what the Grid prototype is teaching us):** a 17×7 mono grid and a 320×480
|
||||||
touch TFT are too different for *one* pixel-identical UI. So the clean split is **core engine +
|
touch TFT are too different for *one* pixel-identical UI. So the clean split is **core engine +
|
||||||
|
|
@ -83,10 +114,14 @@ this timeline against the wall clock.
|
||||||
|
|
||||||
### Stage 3 — drivers (hardware) 🔧 IN PROGRESS (`rust/pm-kit/`)
|
### Stage 3 — drivers (hardware) 🔧 IN PROGRESS (`rust/pm-kit/`)
|
||||||
**✅ Milestone 1 (boot) — confirmed on Pico 2:** GP25 blink. Toolchain + RP2350 boot block + flash work.
|
**✅ Milestone 1 (boot) — confirmed on Pico 2:** GP25 blink. Toolchain + RP2350 boot block + flash work.
|
||||||
**✅ Milestone 2 (display) — confirmed on Pico 2:** ST7796 320×480 over SPI0 via `rp235x-hal` +
|
**🟡 Milestone 2 (display) — draws correctly on Pico 2, but TEARS:** ST7796 320×480 over SPI0 via
|
||||||
`mipidsi` + `embedded-graphics`, drawing the shared `pm-ui`. Key fix: **hold CS low for the whole
|
`rp235x-hal`, drawing the shared `pm-ui` through an `embedded-graphics` framebuffer. Driver is a
|
||||||
session** (`NoCs`) — mipidsi toggles CS mid-command and the ST7796 needs it continuous (see
|
**custom `St7796` struct** ported from `pico/main.py` — mipidsi was tried first and **dropped**: its
|
||||||
[[rust-st7796-cs-gotcha]]). Diagnosed off-bench with host tools in `rust/uisim`: `uisim` renders
|
split-transaction CS and orientation/offset math mangled the geometry; the port uses correct
|
||||||
|
per-command CS framing (CS low → cmd → params → CS high) and full-width row bands (see
|
||||||
|
[[rust-st7796-cs-gotcha]]). **Not done:** the image tears badly — no TE/vsync sync is possible because
|
||||||
|
this module exposes no TE pin, so writes race scan-out (no crate fixes this; see the tearing note in
|
||||||
|
the display driver matrix above). Open item before the display can be called finished. Diagnosed off-bench with host tools in `rust/uisim`: `uisim` renders
|
||||||
pm-ui to PNG; `--bin panelsim` decodes mipidsi's real command/pixel stream into a PNG (proved the
|
pm-ui to PNG; `--bin panelsim` decodes mipidsi's real command/pixel stream into a PNG (proved the
|
||||||
protocol correct → bug was physical); `--bin initdump` dumps the init + CASET/RASET sequence.
|
protocol correct → bug was physical); `--bin initdump` dumps the init + CASET/RASET sequence.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue