Sintra: drive the scan-bay illuminator LED during QR scanning #69

Open
opened 2026-06-24 22:34:08 +00:00 by padreug · 0 comments
Owner

Goal

Drive the Sintra's scan-bay illuminator during QR capture (pairing wizard today, all scan flows later), the way lamassu-machine does. It is a fill light for scanning, not decoration — it lifts the dark surround toward the brightness of a presented phone screen, shrinking scene contrast so the camera's auto-exposure can expose the QR correctly instead of blowing it out.

Why this matters (observed)

During on-machine pairing tests (PR #68), a phone QR would only decode after the operator manually lowered the phone's screen brightness — classic over-exposure: dark bay + bright phone → AE meters the surround → the QR washes out. A dim fill light is the engineered fix, and lamassu set it to a dimmed white precisely to avoid glaring reflective phones/glass. Scanning works now without it (1280×960 capture, see PR #68), but the light should make it first-try and robust across ambient conditions and for printed/paper QR.

How lamassu-machine drives it (provenance: v8.1.5, ≤8.1.5 OK)

  • Brain.hasNewScanBay() is true for sintra → emits scanBayLightOn / scanBayLightOff around scans (lib/brain.js).
  • lib/upboard/sintra/board-manager.js → lib/ssuboard/led-manager.js: scanBayLightOn ⇒ solidUp(scanBayLeds, COLORS.dimmed).
  • Addressing (lib/ssuboard/led-addresses.js): scanBayLeds = [0, 15] — first 16 LEDs of a 26-LED addressable RGB chain (validator [16,20], dispenser [21,25], door [16,25]).
  • Color: COLORS.dimmed = 0x666666 (dim white).
  • Transport: lib/leds/led-control.js execs /opt/leds <pulse> <rHex> <gHex> <bHex> <start> <end> — scan-bay solid-on is effectively /opt/leds 0 66 66 66 0 15. Raw layer (lib/ssuboard/leds.js) is APA102/SK9822 over SPI: mode 3, 256 kHz, frame [0,0,0,0] + per-LED bytes + [0xff,0,0,0]. lamassu opens spidev1.0. The /opt/leds binary itself is not in the repo (deployed to /opt), but the protocol above is fully recoverable.

Hardware findings on our NixOS Sintra (2026-06-24)

Two image/kernel-level blockers — a runtime test frame is not currently possible:

  1. HAT pins not muxed to SPI. upboard-fpga, pinctrl-upboard, leds-upboard are not in our kernel (not loadable). Without the UP board FPGA pinctrl, LPSS SPI signals don't reach the physical HAT header the strip is wired to. → needs the out-of-tree upboard drivers built into the NixOS kernel.
  2. No spidev node on the LPSS bus. Peripheral SPI controller is present (spi2 → 8086228E:01, ACPI \_SB_.PCI0.SPI2) but has no child device; instantiating spidev needs an ACPI SSDT overlay (CONFIG_ACPI_CONFIGFS=m, CONFIG_SPI_SPIDEV=m available). spi0 is the BIOS flash controller — off-limits.

Plan

  1. Image/kernel: add upboard-fpga + pinctrl-upboard (out-of-tree) to the Sintra kernel in deploy/nixos; expose spidev on the LPSS SPI (ACPI SSDT, or via the upboard pinctrl once present).
  2. Empirical go/no-go: once /dev/spidevX.Y exists, send an APA102 frame to segment [0,15] @ 0x666666 and confirm the physical bay strip lights (validates wiring + correct bus/CS).
  3. Driver: port the framing into a small scanBayLight(on/off) helper in Electron main (via spi-device, mirroring lib/ssuboard/leds.js).
  4. Wire into UX: call it from the pairing wizard scanning phase (on at scan start, off on stop/success), mirroring lamassu's scanBayLightOn/Off lifecycle; later extend to the main scan flows.
  5. Persist: bake spidev/pinctrl enablement into the disk image so it survives rebuilds.

Notes

  • Separate workstream from the QR-pairing wizard (PR #68, functionally complete).
  • Keep the light dim (0x666666) — bright illumination glares phone screens; the whole point is contrast reduction, not flooding.

Refs: lamassu-machine v8.1.5 — lib/brain.js, lib/upboard/sintra/board-manager.js, lib/ssuboard/{led-manager,leds,led-addresses}.js, lib/leds/led-control.js.

## Goal Drive the Sintra's **scan-bay illuminator** during QR capture (pairing wizard today, all scan flows later), the way lamassu-machine does. It is a *fill light for scanning*, not decoration — it lifts the dark surround toward the brightness of a presented phone screen, shrinking scene contrast so the camera's auto-exposure can expose the QR correctly instead of blowing it out. ### Why this matters (observed) During on-machine pairing tests (PR #68), a phone QR would only decode after the operator **manually lowered the phone's screen brightness** — classic over-exposure: dark bay + bright phone → AE meters the surround → the QR washes out. A dim fill light is the engineered fix, and lamassu set it to a *dimmed* white precisely to avoid glaring reflective phones/glass. Scanning works now without it (1280×960 capture, see PR #68), but the light should make it first-try and robust across ambient conditions and for printed/paper QR. ## How lamassu-machine drives it (provenance: v8.1.5, ≤8.1.5 OK) - `Brain.hasNewScanBay()` is true for `sintra` → emits `scanBayLightOn` / `scanBayLightOff` around scans (`lib/brain.js`). - `lib/upboard/sintra/board-manager.js` → `lib/ssuboard/led-manager.js`: `scanBayLightOn` ⇒ `solidUp(scanBayLeds, COLORS.dimmed)`. - **Addressing** (`lib/ssuboard/led-addresses.js`): `scanBayLeds = [0, 15]` — first 16 LEDs of a 26-LED addressable RGB chain (validator `[16,20]`, dispenser `[21,25]`, door `[16,25]`). - **Color**: `COLORS.dimmed = 0x666666` (dim white). - **Transport**: `lib/leds/led-control.js` execs `/opt/leds <pulse> <rHex> <gHex> <bHex> <start> <end>` — scan-bay solid-on is effectively `/opt/leds 0 66 66 66 0 15`. Raw layer (`lib/ssuboard/leds.js`) is **APA102/SK9822 over SPI**: mode 3, 256 kHz, frame `[0,0,0,0] + per-LED bytes + [0xff,0,0,0]`. lamassu opens `spidev1.0`. The `/opt/leds` binary itself is not in the repo (deployed to `/opt`), but the protocol above is fully recoverable. ## Hardware findings on our NixOS Sintra (2026-06-24) Two image/kernel-level blockers — **a runtime test frame is not currently possible**: 1. **HAT pins not muxed to SPI.** `upboard-fpga`, `pinctrl-upboard`, `leds-upboard` are **not in our kernel** (not loadable). Without the UP board FPGA pinctrl, LPSS SPI signals don't reach the physical HAT header the strip is wired to. → needs the out-of-tree upboard drivers built into the NixOS kernel. 2. **No spidev node on the LPSS bus.** Peripheral SPI controller is present (`spi2 → 8086228E:01`, ACPI `\_SB_.PCI0.SPI2`) but has no child device; instantiating spidev needs an ACPI SSDT overlay (`CONFIG_ACPI_CONFIGFS=m`, `CONFIG_SPI_SPIDEV=m` available). **`spi0` is the BIOS flash controller — off-limits.** ## Plan 1. **Image/kernel**: add `upboard-fpga` + `pinctrl-upboard` (out-of-tree) to the Sintra kernel in `deploy/nixos`; expose `spidev` on the LPSS SPI (ACPI SSDT, or via the upboard pinctrl once present). 2. **Empirical go/no-go**: once `/dev/spidevX.Y` exists, send an APA102 frame to segment `[0,15]` @ `0x666666` and **confirm the physical bay strip lights** (validates wiring + correct bus/CS). 3. **Driver**: port the framing into a small `scanBayLight(on/off)` helper in Electron main (via `spi-device`, mirroring `lib/ssuboard/leds.js`). 4. **Wire into UX**: call it from the pairing wizard `scanning` phase (on at scan start, off on stop/success), mirroring lamassu's `scanBayLightOn/Off` lifecycle; later extend to the main scan flows. 5. **Persist**: bake spidev/pinctrl enablement into the disk image so it survives rebuilds. ## Notes - Separate workstream from the QR-pairing wizard (PR #68, functionally complete). - Keep the light **dim** (`0x666666`) — bright illumination glares phone screens; the whole point is contrast reduction, not flooding. Refs: lamassu-machine v8.1.5 — `lib/brain.js`, `lib/upboard/sintra/board-manager.js`, `lib/ssuboard/{led-manager,leds,led-addresses}.js`, `lib/leds/led-control.js`.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/bitspire#69
No description provided.