Commit graph

7 commits

Author SHA1 Message Date
Me Here
88104e3d5c PM_K-1 0.0.7: perform tempo ramps + gap trainer, show their indicators, log bars
Device parser now reads the rmp<start>/<amt>/<every> and tr<play>/<mute> tokens it
previously ignored, and the firmware performs them:
- Tempo ramp: steps bpm by <amt> every <every> bars (resets to the start at each b<n>
  segment boundary). Shows an amber ramp arrow + "+amt/everyb" (up/down by sign; no
  starting bpm, per request).
- Gap trainer: cycles <play> audible bars then <mute> silent bars (no click/MIDI/LED;
  playheads keep moving). Shows a play|rest symbol + "play/muteb".
- Practice log entries now record + show bars played.

Verified in the CPython harness: ramp 92->96->100->104->108 (+4 every 2 bars), gap
mute cycle play,play,mute,mute, and the on-screen ramp indicator renders.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 11:43:54 -05:00
Me Here
5e71df6b17 PM_K-1: chunked firmware transfer (reliable), LED run/stop indicator, revert bg tint
APP_VERSION -> 0.0.6. Device firmware + editor change in lockstep — one-time manual
copy of 0.0.6 needed (the broken single-shot updater can't deliver it).

Update transport (fixes the failed/bricking updates):
- Editor now pushes app.py in 512-byte flow-controlled chunks: begin(0x21,len) ->
  data(0x22)* -> commit(0x23), waiting for each ACK before the next. A single ~38KB
  SysEx overran the device's USB-MIDI input buffer and arrived corrupt.
- Device writes chunks straight to /app.new, and on commit verifies length + no NUL +
  App().run()/APP_VERSION present before the A/B install; rejects (NAK) otherwise and
  keeps the working build. All errors caught -> never bricks.

Run/stop indicator moved off the screen onto the RGB LED (per feedback that recoloring
the whole background is wrong — it forces a full-screen SPI repaint and fringes the
anti-aliased text):
- Dim GREEN when stopped ("on"), dim RED while playing; the beat pulse flashes brighter
  and now decays back to the running base instead of to black. Background is static black.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 11:33:43 -05:00
Me Here
711a02fcc1 Fix firmware-update brick: app.py must be ASCII for the 7-bit MIDI push (+ guards)
Root cause: a non-ASCII em-dash in an app.py comment. The A/B updater pushes app.py
as 7-bit SysEx (charCode & 0x7F), which turned the em-dash's bytes into a NUL byte ->
corrupt source -> the pushed build crashed on boot (black screen, onboard LED blinking
CircuitPython's error/safe-mode pattern). A dragged copy was fine (valid UTF-8); only
the over-MIDI path mangled it.

- Replace the em-dash with ASCII; app.py is now pure ASCII.
- build.sh now ASSERTS pico-cp/app.py is pure ASCII (fails the build otherwise) so this
  class of bug can never ship again.
- Device 0x20 handler VALIDATES the pushed app.py before installing (reject if it
  contains a NUL byte, or is missing App().run()/APP_VERSION) and now catches ALL
  exceptions (not just OSError) -> a corrupt/truncated/oversized push NAKs and keeps the
  working build instead of bricking. Longer pre-reload sleep so the ACK flushes.

APP_VERSION -> 0.0.5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 10:14:13 -05:00
Me Here
2b113a18cc PM_K-1 firmware: show version (small, dim) top-right of the logo. APP_VERSION -> 0.0.4
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 09:49:25 -05:00
Me Here
ca44aa833d PM_K-1 firmware: screen refinements (run-state bg tint, time/bar totals, per-track log, square/circle pads, separated track #)
App.py-only (ships over the one-click updater). APP_VERSION -> 0.0.3.

- Run/stop is now a background tint (gray running / near-black stopped) instead of
  STOP text, reclaiming the space.
- Running time + bar counter show "of total" when the track has a b<n> length:
  "1:23 of 2:00" and "bar N of 16" (bar cycles 1..N); total time derived from
  bars x master-beats-per-bar x 60/bpm. Parser now reads the b<n> token.
- Practice log is filtered to the current track (drops the redundant track column).
- Pads: squares for the main pulse, circles for subdivisions (was square + hollow
  outline); fewer vectorio shapes too.
- Track number set apart from the title (small + dim, right) so it no longer reads
  as part of the title.

On-device editing (tap instrument -> lane table; tap beat -> cycle state; dirty-name
-> confirm save/revert) is deferred to Phase 2, where "save" has a correct destination
(an edited built-in saves as a user copy).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 09:41:57 -05:00
Me Here
dec6c61fce PM_K-1 firmware Phase 1: VARASYS logo, MIDI/USB status icons, square/outline beats, beat gridlines, stopwatch + bar counter
Device screen redesign (CircuitPython app.py), built proportional to WIDTH/HEIGHT
so it scales to other panels (one adaptive firmware, per-panel config — not a fork):

- gen_assets.py bakes logo.bin (VARASYS wordmark, no tagline), midi.bin (DIN-5),
  usb.bin (trident) as 4-bit-alpha bitmaps (same packing as the fonts).
- Header: VARASYS logo (brand cyan) replaces the "PM_K-1 KIT" text; MIDI icon goes
  green when a host is listening, USB icon lights when supervisor.runtime.usb_connected.
  load_alpha/make_glyph are non-fatal — a missing .bin falls back to text, never a
  black screen (addresses the corrupt-file failure mode we just hit).
- Pad grid: filled squares on main beats, hollow outline squares (outer+inner rect) on
  off-beats; playhead fills the lit pad. Vertical gridlines at the master lane's beats
  (full height) so beats line up across lanes.
- Stopwatch (m:ss) + bar counter (master-lane cycles), refreshed ~4x/s only on change.

The .bin assets ship in the drive bundle (the A/B updater only pushes app.py), so a
one-time re-copy is needed to pick them up. APP_VERSION -> 0.0.2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 08:56:45 -05:00
Me Here
e8945ee1d1 PM_K-1: one-click A/B firmware updates over USB-MIDI (+ version check)
Split the CircuitPython firmware into a tiny stable loader (code.py) + the application (app.py,
carries APP_VERSION). The editor's ⋯ → "⬆ Update firmware" queries the device version (SysEx 0x02
-> 0x03 reply), fetches the latest app from the site (/pico-cp-app.py), shows device-vs-latest, and
pushes the new app.py over USB-MIDI (SysEx 0x20). The device installs it to a trial slot (old build
kept as app.bak), reboots, and the loader AUTO-ROLLS-BACK to app.bak if the new build fails to start;
a build that runs cleanly ~5s is confirmed (clears /trial). No BOOTSEL, no dragging; Chromium/Firefox.
app.py forced to pure ASCII so it pushes raw (no base64); SysEx buffer raised to 60KB.

build.sh/deploy.sh: bundle code.py+app.py and serve /pico-cp-app.py. Docs updated.

Verified in CPython: version reply, update install+reboot+ACK, rollback file dance; editor loads clean
with the updater wired.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 06:55:58 -05:00