Commit Graph
5 Commits
Author SHA1 Message Date
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
prosolis 138efc28ca BOM: confirm the plain Zero and Zero W as verified fallbacks
The BOM claimed "Zero W also works" as an aside. Checked it: Circle's
CHANGELOG gives gadget support for "Zero (2) (W)", the parentheses including
the plain Zero, and the README lists Raspberry Pi Zero as Tested with no
caveat. build.sh already emits kernel.img for RASPPI=1, and the MIDI gadget's
string descriptors are present in that image, so no build change is needed
for either board.

Keeping the Zero 2 W as the specified part on availability grounds. Records
that a plain Zero would permanently close the WiFi option in section 3a,
since it has no radio silicon at all.

Claude-Session: https://claude.ai/code/session_01TVCB25LBsmeteWvaSMz4Ne
2026-08-27 22:28:15 -07:00
prosolis 6a59766b79 Record Bluetooth/WiFi findings and Phase 1 status in the plan
Checked against the pinned Circle tree after the question of supporting
Bluetooth and WiFi on the Pi alongside USB.

Bluetooth is not possible on Circle, for two independent reasons: the stack
was removed for legal reasons and was classic Bluetooth in any case, with no
BLE or GATT anywhere in the tree, while MIDI over BLE is GATT; and the
remaining HCI transport would need a USB dongle in host mode, which the
gadget-only constraint already rules out.

That costs nothing. The WU-BT10 does GATT MIDI to the PC, and the PC is the
hub, so Bluetooth MIDI works today with no firmware change - it just
terminates one hop earlier. Section 3 now describes it that way rather than
as a spare part.

WiFi is possible via addon/wlan but is a project rather than a flag: Circle
lists WLAN as unknown on the Zero 2 W, ships no RTP-MIDI (only mDNS
advertisement of _apple-midi._udp), needs firmware blobs off the card at
boot, and its coexistence with gadget mode is unproven. Deferred, not
rejected; that last point is what to settle first.

Also marks Phase 1 done-but-unverified, and records that Phase 0 should bench
rpi_ws281x in SPI mode on GPIO10, since the stock examples use GPIO18 over
PWM and would prove the wrong wiring.

Claude-Session: https://claude.ai/code/session_01TVCB25LBsmeteWvaSMz4Ne
2026-08-27 22:19:18 -07:00
prosolis 3904703de1 Add Phase 1 Circle firmware
Greenfield bare-metal firmware for a Pi Zero that lights a WS2812B strip
above an 88-key keybed. The Pi is a USB MIDI gadget; the PC is the host and
owns the piano connection and everything else. No network stack, no
filesystem, no shell.

Circle is a submodule pinned to Step51. Builds kernel.img (RASPPI=1, Zero /
Zero W) and kernel7.img (RASPPI=2, Zero 2 / Zero 2 W); both coexist on one
card, so either model runs from the same SD.

Resolves two open assumptions from the plan against the Circle sources
rather than by guessing:

- CWS28XXStripe clocks the waveform out over SPI at a fixed 6.4MHz, one SPI
  byte per LED bit. On device 0 that puts data on MOSI = GPIO10 = physical
  pin 19. The implied 5.28ms frame time matches the plan's arithmetic.
- The USB gadget lifecycle follows sample/29-miniorgan, which already
  carries a USB_GADGET_MODE path.

Three details the hardware forces:

- The gadget destroys and recreates its CUSBMIDIDevice across a USB
  suspend, so the kernel re-fetches it and clears notes held at that
  moment. Otherwise a chord would stay lit forever when the PC sleeps.
- Rendering blocks for ~5.3ms of SPI traffic, so the MIDI packet handler
  only records state and the main loop draws.
- MAX_LIT_KEYS complements the global brightness ceiling. 176 LEDs at full
  white would draw ~10.5A against a 6A supply; together the two clamps make
  that unreachable rather than merely unlikely.

Every Phase 0 product decision has a named slot in firmware/config.h, all
overridable at build time via EXTRADEFINE.

tests/run.sh compiles the real pianoleds.cpp against stubbed Circle headers
and checks the mapping, note-off paths, range clamping and both power
clamps across nine configuration variants. It verifies arithmetic, not
wiring, and does not replace bench-testing on real hardware.

Claude-Session: https://claude.ai/code/session_01TVCB25LBsmeteWvaSMz4Ne
2026-08-27 22:09:47 -07:00
prosolis e5b92de3e6 Add project plan
Architecture, bill of materials, electrical notes and phasing for an LED
strip above a Casio PX-S7000, driven as a USB MIDI gadget from the PC.

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