Rust sibling of pico-scroll/app.py — the PM_G-1 'Grid' 17x7 LED metronome on a plain RP2040 Pico (thumbv6m, not the Pico 2). LED-first milestone: - IS31FL3731 driver: vendored bulk 144-byte framebuffer, one I2C block write per frame (port of the CircuitPython Matrix; the is31fl3731 crate isn't used). - Polymeter scheduler driven by track-format::schedule::lane_durs (the cross-impl contract) + per-lane step clocks + tempo ramp + gap-trainer. - 4-button input (A play/stop·hold=view, B next-track·hold=next-setlist, X/Y tempo). - Built-in set lists; 3 views: Ticker (default), Grid, Pendulum. - Ticker (user-designed): name infinite-scrolls left; BPM pinned right rotated 90 CCW = hundreds dot-bar (1 dot/100) + last 2 digits rotated. 130 -> 1 dot + '30'. - Build scaffolding: rp2040-hal 0.10 + boot2, memory.x, build.sh + uf2.py (RP2040 family id). thumbv6m-none-eabi added to rust/Containerfile. Excluded from the host workspace like pm-kit. Compiles clean -> 48 KB pm-grid.uf2. Audio (USB-MIDI; the board has no speaker), live-sync, firmware push, practice log and playback-flow auto-advance are deferred to the next milestone (as on pm-kit). Also: delete COORDINATION.md (solo now); docs/rust-port.md updated with pm-grid status + corrected Grid driver-matrix row. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
27 lines
921 B
Python
27 lines
921 B
Python
#!/usr/bin/env python3
|
|
"""Pack a raw RP2040 flash image (objcopy -O binary output) into a UF2.
|
|
|
|
Family rp2040 (0xe48bff56), flash base 0x10000000. Usage:
|
|
python3 uf2.py pm-grid.bin pm-grid.uf2
|
|
"""
|
|
import struct
|
|
import sys
|
|
|
|
BASE = 0x10000000
|
|
FAMILY = 0xE48BFF56 # rp2040
|
|
|
|
src = sys.argv[1] if len(sys.argv) > 1 else "pm-grid.bin"
|
|
out = sys.argv[2] if len(sys.argv) > 2 else "pm-grid.uf2"
|
|
|
|
data = open(src, "rb").read()
|
|
chunks = [data[i:i + 256] for i in range(0, len(data), 256)] or [b""]
|
|
n = len(chunks)
|
|
with open(out, "wb") as f:
|
|
for i, c in enumerate(chunks):
|
|
c = c.ljust(256, b"\x00")
|
|
blk = struct.pack("<IIIIIIII", 0x0A324655, 0x9E5D5157, 0x00002000,
|
|
BASE + i * 256, 256, i, n, FAMILY)
|
|
blk += c + b"\x00" * (476 - 256) + struct.pack("<I", 0x0AB16F30)
|
|
assert len(blk) == 512
|
|
f.write(blk)
|
|
print(f"{out}: {n} blocks, {len(data)} bytes payload")
|