feat: dig2go board support — profile pair + switched LED power rail - #397
Draft
Yona-Appletree wants to merge 18 commits into
Draft
feat: dig2go board support — profile pair + switched LED power rail#397Yona-Appletree wants to merge 18 commits into
Yona-Appletree wants to merge 18 commits into
Conversation
…tion Dig-Next-2 identified as ESP32-PICO-V3-02 from its published pinout (GPIO20 exists on no other ESP32; reserved flash/PSRAM pins 6/9/10/11/16/17 all avoided). Rules out both classic WROOM and S3. Adds the lineup matrix (Uno/Quad/Octa/Next/analog), per-board UART0 status, and notes Dig-Octa as the better 8-wire target. Co-Authored-By: Claude Fable 5 <[email protected]>
The dig-uno sidecar mapped Q1/Q2/Q4 to GPIO 1/2/4 — a label-equals-number assumption. The vendor pinout guide gives Q1=15, Q2=12, Q3=2, Q4=32; GPIO4 is unused on a Dig-Uno and GPIO1 is UART0 TX, so wire selection on 'Q1' drove the wrong pad. Corrected, with a support_note marking the values vendor-sourced and hardware-unverified. Adds docs/future/2026-08-06-quinled-board-metadata-prep.md: the complete QuinLED lineup, pin tables cross-checked against QuinLED's own platformio_override.ini, schema gaps the family exposes (socketed modules, mutually exclusive resources, edge ports, stacked boards), and the concrete questions only Quindor can answer. Co-Authored-By: Claude Fable 5 <[email protected]>
… power gate ESP32-D0WD-V3 rev v3.1, 4MB, CH340 1a86:7523. The esp32v3-4mb build already fits, so support is mostly profile authoring — except GPIO12, which gates LED power AND is the MTDI flash-voltage strap. We model no 'assert to enable an output rail' concept; same shape as Dig-Next-2's switched power outputs. Co-Authored-By: Claude Fable 5 <[email protected]>
Records the hardware requirements found by probing (gate pin must be asserted or the board reads as dead; GPIO12 is also the MTDI flash-voltage strap so it must be low at boot; polarity varies by install and belongs in metadata) and the two electrical constraints any implementation must respect (energise-settle- transmit, because data into an unpowered strip phantom-powers the first controller through its protection diode; and never cut mid-frame or chatter a mechanical relay). Proposes metadata plus driver with no project-model entity, and adds a 'Reading WLED safely' policy: WLED relicensed MIT -> EUPL-1.2, AGPL is on EUPL's compatible list but our commercial half is not, so read only the pinned MIT-era checkout at oss/wled-mit (44e28f96, one past v0.15.0-b6) and re-derive rather than port. Co-Authored-By: Claude Fable 5 <[email protected]>
…ED prior art The provider takes post-pipeline &[u16] and cannot see brightness, so the all-black scan is the right trigger after all — brightness is applied upstream (so 0 => all-black), and an early exit makes the lit-frame case ~free. Records WLED's calibration numbers (600ms trailing debounce, immediate on, ordering- based settle) with MIT attribution, and the two places we must differ: an explicit settle gate + queue drain because our pusher is on core 1, and a seconds-scale debounce because ours is content-driven. Also names the data-line parking hazard: a data pin left high into an unpowered WS281x phantom-powers it through the input protection diode. Co-Authored-By: Claude Fable 5 <[email protected]>
Optional board-level power_gate list on the hardware manifest: gpio, active_level, open_drain, settle_ms, off_debounce_ms (default 5000), feeds scoping, provenance note. Metadata only — the provider state machine lands next. Deliberately not a HwCapability: a capability says 'this resource can do X'; this says 'assert this pin or the outputs are dead' (the dig2go's GPIO12 LED relay, the Dig-Next-2's three switched rails). Absent block = empty slice, existing manifests byte-unchanged; schema regenerated. Plan: 2026-08-07-2336-dig2go-board-support Co-Authored-By: Claude Fable 5 <[email protected]>
Runtime manifest: LED=GPIO16 claimable; GPIO0 (touch+BOOT strap), GPIO1/3 (UART0/CH340 host link), GPIO12 (LED power gate + MTDI strap) reserved; one /rmt/ws281x0; power_gate on /gpio/12 (active-high, settle 25 ms, debounce 5 s — pre-walk placeholders, noted as such). Sidecar: esp32/4 MB (probed) => joins esp32v3-4mb; tier silver; ch340c with shared-VID:PID caveat; default wire LED. New drift gates: power-gate pins must be declared, reserved, and never display as wires; dig2go-named assertions; firmware-join expected- compatibility row + 0 MB-headroom test; rail-less drawing lays out. Facts from the 2026-08-06 desk probe + two agreeing vendor sources (docs/future/2026-08-06-quinled-board-metadata-prep.md). GPIO21/22/23/25 omitted as unverified — vendor shows a dupont header carrying them; confirm at the hardware walk. Plan: 2026-08-07-2336-dig2go-board-support Co-Authored-By: Claude Fable 5 <[email protected]>
PowerGateController in fw-esp32-common: rails off at construction (strap-safe — the dig2go's gate is GPIO12/MTDI), assert + explicit settle spin before the first lit frame stages, seconds-scale all-black trailing debounce, deassert only at the flush barrier after draining the gate's wires (background-safe ones included — cutting supply under a transmission is the failure this exists to avoid). All-black scan early-exits on the first lit value. Injected NowMicros clock per the sans-IO rule; polarity resolved in the shared machine so active-low is testable off-silicon. fw-esp32v3 supplies the two things common code cannot: an esp-hal Output pin (inactive from construction, open-drain honored) and Instant-based time. Data-line parking needs nothing here: wire pads are parked solid low at open and RMT idles Low — recorded at the wiring. Boards with no gates get a provider identical to before (esp32c6/s3 compile untouched). ADR: docs/adr/2026-08-08-switched-power-rail-mechanism.md Plan: 2026-08-07-2336-dig2go-board-support Co-Authored-By: Claude Fable 5 <[email protected]>
Reconcile P2's runtime finding with P1/P3: a gate's feeds must name the ENDPOINT address a wire resolves to (/gpio/N on the classic), because /rmt/ws281xK slots are acquired per transmission and are not stable identities. A feeds entry that matched nothing would leave the rail permanently down — a dark board misread as a driver bug. The dig2go's single gate switches the board's only LED supply, so it now declares no feeds (= gates every output); the named drift test pins that with the reasoning. Plan: 2026-08-07-2336-dig2go-board-support Co-Authored-By: Claude Fable 5 <[email protected]>
boards/README.md gains the power-gate section (descriptor semantics, reserved-pin rule, endpoint-address feeds, strap-pin warning, measured- records posture). fw-esp32-common/fw-esp32v3 READMEs note the new module split. The QuinLED prep doc records what shipped and the one correction (feeds = endpoint addresses). Plan: 2026-08-07-2336-dig2go-board-support Co-Authored-By: Claude Fable 5 <[email protected]>
…connect state
Two critical-path wizard fixes found live on the dig2go bench walk
(the board carried a pre-hello LightPlayer build):
StaleLightPlayer verdict: lpa-link already diagnosed
DeviceState::Incompatible ('one affordance: reflash') but the probe
evidence never carried it, so the wizard dead-ended at PROBE_FAILED
with irrelevant BOOT-hold advice. New ProbeEvidence.stale_lightplayer
-> BoardVerdict::StaleLightPlayer -> SetupState::StaleLp mirroring
WledFound: 'Running an older LightPlayer -> Update the firmware'
routes into BoardPick with the flash confirmation still guarding.
Deliberately never LightPlayer (the only-a-hello-adopts rule holds);
golden trace proves probe -> stale -> update -> pick -> flash ->
provision.
Honest connect boundary: PortGranted was emitted only after the whole
connect (open, reset, boot wait, hello deadline), so the UI showed
'The browser is asking which port…' through the entire attempt.
open_provider split into choose_provider_endpoint + connect_endpoint;
PortChosen fires between them -> new SetupState::Connecting with
truthful copy, and Connecting/Probing render the flash step's live
log terminal (card_op_terminal + pump_setup_console) so link/boot
lines are visible without the browser console. Terminal fills at
phase boundaries — streaming mid-connect needs a deeper pass, noted
in the design doc.
Validation: lpa-studio-core 1263 ok, lpa-studio-web 419 ok, clippy
-D warnings + fmt clean, wasm32 cfg-gated checks clean (caught a
second caller the native gate never compiles).
Plan: 2026-08-07-2336-dig2go-board-support (gate-time scope addition)
Co-Authored-By: Claude Fable 5 <[email protected]>
Captured in the pinned CI environment by run: https://github.com/PhotomancerArt/lightplayer/actions/runs/31269966650
Contributor
CI refreshed the story baselines on this branchThe Review every PNG in the PR's Files changed view (swipe / onion-skin). 1 more file(s)
|
…ts the connect's lines Two more setup-flow defects from the dig2go bench walk: Escalation verdict: read_setup_probe discarded probe_link_mode's return value — the ONE place a completed ROM/stub conversation is recorded, since every probe's rebuild_link replaces the boot-line classifier (the snapshot is structurally incapable of remembering). A silent stub-parked board (RTS reset does not exit download mode on CH340 classics) therefore re-classified Unresponsive after a probe that had just identified the chip. ProbeEvidence.bootloader_conversation now carries it; classify_board treats it as Blank-class evidence and routes to BoardPick. Pinned: successful-escalation evidence can never classify Unresponsive; it never outranks a named firmware. Terminal feed: the connect path recorded link_session_logs and the attach-failure drain into the GLOBAL log ring (violating the rule record_session_logs itself documents) right before pump_setup_console found the session buffers empty; and probeTarget's esptool lines were dropped at .map(|r| r.chip_name). Both now land on the session console tail the wizard renders; the probe replays its terminal through a real event sink instead of noop. Validation: lpa-studio-core 1268(+7) ok, lpa-studio-web 419 ok, lpa-link 27 ok, clippy -D warnings + fmt clean, wasm32 cfg-gated checks clean. Pre-existing native-clippy dead-code nit in lpa-link (probe_target, wasm-only caller) untouched — not in the repo gate. Plan: 2026-08-07-2336-dig2go-board-support (gate-time scope addition) Co-Authored-By: Claude Fable 5 <[email protected]>
…d3' into claude/dig2go-board-support-f6bbd3
getPorts()/requestPort() now surface getInfo()'s usbVendorId/usbProductId through BrowserSerialPortHandle and the provider's endpoint state, with discover_granted_endpoints_with_usb keeping the pair alongside each endpoint. Until now the VID:PID existed only inside the label's prose, which nothing can match a board's declared usb_bridge against — the D7 grant-aware picker needs it structurally. Co-Authored-By: Claude Fable 5 <[email protected]>
The problem: requestPort() always shows Chrome's native chooser by spec — grants only affect getPorts() — so every wizard walk cost a human click in a dialog no agent can drive, even when the origin already held the port. Ratified constraint: silent adoption is only safe when unambiguous. The ladder (plan_for_granted_ports, pure + host-tested), walked inside RequestPort before any chooser: - 0 grants → native chooser, as before - exactly 1 (AutoAdopt) → adopt visibly and reversibly: CONNECTING names the port and offers "Not this one? Pick a different port" - several → the in-app picker (GrantedPortsListed → PortPicking.grants), one row per grant, "Another port… (browser chooser)" last — and an honesty note when getInfo()'s VID:PID cannot tell two rows apart - board-first refinement: the pick narrows the sweep to the board's usb_bridge VID:PID; one match adopts, zero means only the chooser can grant the board's port Adopt only once: any return to CONNECT_INTRO demotes the next request to ListOnly (a failed adoption is what makes a grant ambiguous), with the new GrantConnectFailed hint naming the adopted port as the suspect. PickDifferentPort is honored across the port-holding pre-flash states because gestures queue behind the in-flight connect — the click lands after the wrong port has already probed. Design: docs/design/device-setup-flow.md §2/§2a; the transition-table test walks the full 16×30 product. Co-Authored-By: Claude Fable 5 <[email protected]>
Captured in the pinned CI environment by run: https://github.com/PhotomancerArt/lightplayer/actions/runs/31295211596
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.








Picked back up 2026-08-08 (evening). The D7 grant-aware port picker is now implemented; the remaining work is the plan's hardware-walk gate on the physical dig2go: the power rail's polarity (
active_level: high) andsettle_ms: 25are documented guesses until silicon confirms them.Handoff that scoped this pickup:
/Users/yona/.photomancer/planning/lp2025/2026-08-07-2336-dig2go-board-support/2026-08-08-1655-handoff.mdPlan: lp2025/2026-08-07-2336-dig2go-board-support
Path: ~/.photomancer/planning/lp2025/2026-08-07-2336-dig2go-board-support/plan.md
First-class QuinLED dig2go support: board profile pair (runtime manifest + display sidecar + catalog registration) and the general switched-power-rail mechanism its GPIO12 LED relay requires (manifest metadata + output-provider state machine).
Also carries 5 commits salvaged from the merged PR #357's branch (pushed post-merge, never reached main) — including the Dig-Uno aux-header GPIO fix (main shipped Q1=1/Q2=2/Q4=4; real values 15/12/32).
Status
usb_bridgeVID:PID filter, adopt-only-once demotion, identical-VID:PID honesty note. Design:docs/design/device-setup-flow.md§2a. This is what makes agent-driven walk retries possible at all —requestPort()always shows a native chooser, so before this every attempt cost a manual click.Resume notes: read plan.md + phase files in the planning dir above; design source of truth is docs/future/2026-08-06-quinled-board-metadata-prep.md (in-repo).
🤖 Generated with Claude Code