Repository navigation
fix(display): support the V2 board's CST3530 touch controller - #138
Babel36acl wants to merge 2 commits into
Conversation
Waveshare shipped two revisions of the reference board and the difference is the touch controller: V1 has a CST328 (7-bit 0x1A, two-byte register addresses, the report block at 0xD000), the V2 of 2026-10-14 a CST3530 (7-bit 0x58, four-byte register addresses, the report block at 0xD0070000). The display flavor hard-codes the CST328, so on a V2 board every read NAKs and `Touch::read` answers "no finger" forever: the panel draws, the first-run "Set a PIN?" prompt appears, and nothing on it responds — the key is unusable rather than merely degraded, because on this flavor the panel IS the presence gate. Neither address can be probed for at runtime (the wrong one simply fails), so the choice is compile-time: `DISPLAY_TP_CHIP=cst328|cst3530`, defaulting to the V1 part, plus a `firmware-display-v2` package that sets it. The bit-twiddling goes in `rsk-ui::touch::parse_cst3530` beside the CST328 parser, under host tests, for the same reason that one lives there: a wrong reconstruction maps a tap to the wrong button. The CST3530 reports nine bytes — point count in `[3]`'s low nibble, then x/y low bytes, strength, the two high nibbles packed into `[7]`, and the finger event in `[8]`'s high nibble — and every read has to write the bare 0xD00002AB address to ack the frame. The reset pulse and the panel pins are identical between revisions, so nothing else changes: no mode write (0xD109 is not a CST3530 register), same I2C bus, same axes. Verified on the NAS with a rustup toolchain (thumbv8m.main-none-eabihf, picotool 2.3.1 for the partition table and the UF2): `cargo test -p rsk-ui` green including five new CST3530 parser cases, `DISPLAY_TP_CHIP=cst3530` builds and produces a UF2 with the store fenced by scripts/pt.sh, the default CST328 path still builds, and docs/assurance-matrix.md is regenerated (a new `firmware-display-v2` column, its settling question recorded in assurance/configurations.toml).
cargo fmt --all -- --check flagged the blocking_write_read call: one line over the width. No behaviour change; check.sh's first row is fmt, so this is what turned CI red before anything else could run.
|
Filed #139 for the hardware-revision side of this (symptom + how to tell V1 from V2 + what I'm asking about flavor policy), so the design discussion stays here and the tracker has an entry other V2 owners can find. |
|
CI note, so the red does not get read as this patch's doing: 39 of 40 checks pass, including all fourteen Two vulnerabilities landed in the advisory database on 2026-10-23, both already in
This diff does not touch A lock-only fix exists and is small ( |
display: support the V2 board's CST3530 touch controller
What happens
On a V2 Waveshare RP2350-Touch-LCD-2.8 the display flavor draws, shows the
first-run Set a PIN? prompt — and no tap ever registers. The key is not
degraded, it is unusable: on this flavor the panel is the user-presence gate,
so every FIDO operation waits on a touch that can never arrive.
Why
Waveshare shipped two revisions of the board and the difference is the touch
part (their product page lists it per revision):
0x1A0xD000report)0x580xD0070000report)firmware/src/display.rstalks to the CST328, so on a V2 board every transferNAKs and
Touch::readreturnsNoneforever. The panel pins, the reset lineand the reset pulse are identical between revisions — only the controller is
different, and neither address can be probed for at runtime (the wrong one just
fails), so this has to be a compile-time choice.
What this does
rsk-ui::touch::parse_cst3530— pure parser besideparse_cst328, under hosttests: point count in
[3]'s low nibble, x/y low bytes in[4]/[5], thestrength, the two high nibbles packed into
[7], finger event in[8]'s highnibble (a lift frame carries the last coordinate and must not count as a tap).
firmware/src/display.rs—read_report()per chip behindcfg(display_tp = …): the CST3530 reads nine bytes at0xD0070000and acks bywriting the bare
0xD00002ABaddress; the CST328 path is unchanged, includingits
0xD109normal-mode write (not a CST3530 register, so it is CST328-only).firmware/build.rs—DISPLAY_TP_CHIP=cst328|cst3530(defaultcst328, alsosettable as
display.tp_chipin a board file), refused loudly on any othervalue.
nix/firmware.nix—tpChipknob + afirmware-display-v2package.docs/guides/display.md— the revision table, the symptom, and how to pick.docs/assurance-matrix.md+assurance/configurations.toml— regenerated withscripts/matrix_gate.py --write; the new column arrives asgapcells with asettling question (
settled_by = "evidence": whichcheck.shrows have to runon this image, and whether any of them reaches a presence gesture at all — a
suite that presses BOOTSEL proves nothing when presence is a panel read). I
deliberately did not invent an
equivalentdisposition: the closure isfirmware-display's, not the default build's, and the gate refuses that basis.
Testing
Rebuilt from source on x86_64 Linux with rustup (
thumbv8m.main-none-eabihf),arm-none-eabi-gcc12.2.1,flip-link, and picotool 2.3.1 built from source:cargo test -p rsk-ui— green, including five new CST3530 parser cases.LED_KIND=none FLASH_SIZE=16M DISPLAY_TP_CHIP=cst3530 cargo build --release -p firmware --features display— builds; the build script's cfg log confirms
display_tp="cst3530".scripts/pt.shfences the store (0x00e7f000..0x00fff000, NSBOOT denied) andpicotool uf2 convertproduces a 2.4 MB UF2.One warning shows up on both configurations and is not from this change: the
linker prints
address (0x1000013c) of section .text is not a multiple of alignment (8)— identical address on the untouched CST328 build, so it belongsto the toolchain/linker-script pair rather than to the touch driver. The
rsk-rsa"incorrect section attributes" assembler warnings are likewise from thedistro
arm-none-eabi-gccinstead of the pinnedgcc-arm-embedded.Hardware: verified on a V2 board (16 MB flash).
DISPLAY_TP_CHIP=cst3530image flashed over BOOTSEL; the panel's touch responds and the on-screen flow is
usable, where the same image with the CST328 driver drew the screen and ignored
every tap. No change was needed to the report layout or the axis mapping.