2 Commits
Author SHA1 Message Date
prosolis 59bd3b4cea Add boot self-test and idle indicator; target the Waveshare RP2350-Plus
The board arriving is a Waveshare RP2350-Plus (4MB, USB-C), which is now the
default BOARD. Its pico-sdk header defines neither PICO_DEFAULT_LED_PIN nor
PICO_DEFAULT_WS2812_PIN - it has no onboard indicator at all - so a bare board
gives no sign of life. The status-LED support added for boards that do have one
(zero, one, tiny, usb_a on GPIO16; eth on GPIO25) is kept and compiles out here.

That makes feedback on the strip itself the useful path, and it turns out to be
the better one anyway:

- Boot self-test sweeps one pixel from index 0 to the far end once at startup.
  It answers in a single glance whether the firmware runs, PIO drives the line,
  the strip is the length LED_COUNT claims, the far end holds voltage, and -
  because you see which end it starts from - whether STRIP_REVERSED is right.
  It runs before USB, so the first test needs nothing but 5V.
- Idle indicator holds one dim pixel lit while no host is connected, separating
  "powered and waiting" from "no power" and from "crashed".

Both are platform-independent, so the Circle build gets them too.

Verified: tests pass across seventeen configurations, now including the
self-test and idle paths on and off. Both platforms build clean with no
warnings from project sources.

Note on the previous commit's verification: a filtered build log hid a real
compile error in the Pico target (sleep_ms takes uint32_t, which is unsigned
long here, and did not match the portable void(*)(unsigned) delay callback).
The build script now gets an explicit success check rather than a grep.

Claude-Session: https://claude.ai/code/session_01TVCB25LBsmeteWvaSMz4Ne
2026-08-27 23:22:56 -07:00
prosolis 469b321a40 Port to RP2040/RP2350, extract the shared logic
Raspberry Pi supply is unreliable, and Circle is Broadcom-only - there is no
Allwinner or Rockchip support anywhere in its tree, so an Orange Pi is not a
board swap but a restart on an unproven base. RP2040/RP2350 is the better
answer: available, ~$4, and a better fit for this job than the Zero ever was.

Structure. All the visualizer logic moves to src/ and is now
platform-independent, depending only on ILEDStrip (four methods) with MIDI
pushed in via OnMIDIPacket(). Each platform supplies a backend and a main
loop. The Circle build is unchanged in behaviour and still produces both
kernel images.

Pico backend:
- WS2812B from a PIO state machine, which clocks the 1.25us bit cell directly
  rather than faking it with 8 SPI bytes per data bit as the Circle build must.
- TinyUSB MIDI 1.0 device. Enumerates as an ordinary ALSA port, as the Circle
  gadget does. Packet framing comes from the USB MIDI Code Index Number rather
  than being re-derived.
- Mount, unmount, suspend and resume all clear held notes, so a chord held when
  the host goes away cannot stay lit.
- Latch spacing is enforced against a timestamp, so a caller cannot start a
  frame inside the WS2812B reset window.

Verified: builds clean for both pico (RP2040, 30052 bytes) and pico2 (RP2350,
28284 bytes), no warnings from project sources, and the Circle build still
produces kernel.img and kernel7.img. Tests pass across nine configurations.

Incidental findings. PIO frees both hardware SPI blocks; on a Pi Zero Circle
exposes only one SPI master (DEVICES=1 for RASPPI<4) and the WS2812B driver
monopolises it, so a display and the strip could not coexist there. RP2040/
RP2350 also support USB host and, on the W variants, BLE via btstack - both
of which section 3a records as impossible on Circle.

Also documents a known limitation found while looking at calibration: the
note-to-LED map is linear in semitone index, but a keybed is not. 52 white
keys span the same 1222mm, making one white key ~3.38 LEDs rather than 2. The
error drifts within each octave, worst at F, by up to ~0.87 LEDs (~6mm) even
after an optimal offset and scale. A geometric map would remove it. Not yet
implemented.

Claude-Session: https://claude.ai/code/session_01TVCB25LBsmeteWvaSMz4Ne
2026-08-27 22:53:00 -07:00