Files
PianoLED-Circle-Edition/tests/run.sh
T
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

34 lines
1.0 KiB
Bash
Executable File

#!/bin/sh
# Host-side tests for the mapping and power-clamp logic.
# Compiles the real firmware sources against stubbed Circle headers, across
# every configuration variant that changes the rendering path.
set -e
cd "$(dirname "$0")/.."
OUT=$(mktemp -d)
trap 'rm -rf "$OUT"' EXIT
FAIL=0
for CFG in \
"default:" \
"reversed strip:-DSTRIP_REVERSED=1" \
"velocity insensitive:-DVELOCITY_SENSITIVE=0" \
"reversed + velocity insensitive:-DSTRIP_REVERSED=1 -DVELOCITY_SENSITIVE=0" \
"full brightness:-DGLOBAL_BRIGHTNESS=255" \
"tight key cap:-DMAX_LIT_KEYS=5" \
"single LED per key:-DLEDS_PER_KEY=1" \
"three LEDs per key:-DLEDS_PER_KEY=3" \
"hints disabled:-DHINT_MIDI_CHANNEL=MIDI_CHANNEL_NONE" \
; do
NAME=${CFG%%:*}
FLAGS=${CFG#*:}
printf '\n=== %s ===\n' "$NAME"
g++ -std=c++17 -Wall -Wextra -Wno-unused-parameter $FLAGS \
-o "$OUT/t" -Itests/stubs -Ifirmware \
tests/test_pianoleds.cpp firmware/pianoleds.cpp
"$OUT/t" || FAIL=1
done
printf '\n'
if [ $FAIL -ne 0 ]; then echo "SOME CONFIGURATIONS FAILED"; exit 1; fi
echo "all configurations passed"