Skip to content

Try AMY CPU overload detection + failsafe (amy#826)#1105

Merged
bwhitman merged 3 commits into
mainfrom
amy-overload-failsafe
Jul 8, 2026
Merged

Try AMY CPU overload detection + failsafe (amy#826)#1105
bwhitman merged 3 commits into
mainfrom
amy-overload-failsafe

Conversation

@bwhitman

@bwhitman bwhitman commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Pins the amy submodule to the head of shorepine/amy#826 (CPU overload detection + failsafe, issue shorepine/amy#791) so this PR's firmware and webapp preview builds carry it for hardware testing.

Also adds tulip.amy_render_load() → float in modtulip.c: AMY's smoothed fraction of real time spent rendering (0..1, ~1.0 = overloaded), backed by the new amy_get_render_load(). Poll it while a heavy sketch runs to watch the load climb.

What to try on AMYboard with this build:

  • Run dpwe's Eno sketch (or anything heavy). As it stacks up voices, tulip.amy_render_load() should climb toward 1.0.
  • At sustained ≥0.98 for 250ms, AMY resets itself and plays four descending doots instead of wedging — and USB CDC / MIDI should stay alive throughout (the fill-buffer task now yields when the i2s write stops blocking).

Follow-up (not in this PR): implement config.amy_external_overload_hook in tulip to stop the running sketch and pop up "this sketch took too many resources" in AMYboard Online.

🤖 Generated with Claude Code

Pins the amy submodule to shorepine/amy#826 (CPU overload detection +
failsafe) so the PR firmware/webapp builds carry it, and adds
tulip.amy_render_load() -> float, AMY's smoothed 0..1 render load
(~1.0 = overloaded), for trying the new measure from Python.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

🔌 AMYboard PR preview

Editor + flasher: https://amyboard-pr-1105.vercel.app/editor/

This preview bundles this PR's firmware — its flasher only flashes this build (not the release). Rebuilt on every push; removed when the PR closes.

The hardware CI has been kicked off and should return within a few minutes, stand by!

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

🌷 Tulip Web PR preview

Tulip Web: https://tulip-pr-1105.vercel.app/run/

Flash a Tulip to this build: on-device run tulip.upgrade(pr=1105).

Rebuilt on every push; removed when the PR closes.

When AMY's CPU overload failsafe trips (it has already reset the synth
and played its bleep), the C hook mp_sched_schedules a Python callback
-- same poll-free pattern as midi_callback -- which stops the sketch
loop and sends F0 00 03 45 'L' <b64 load pct> F7 out the USB-MIDI
gadget. AMYboard Online's existing persistent sysex listener shows
'this sketch needed more CPU' in the error modal. Headless boards just
stop the sketch; the bleep was the notification.

- modtulip.c: tulip.amy_overload_callback(cb) setter
- amy_connector.c: tulip_amy_overload_hook -> mp_sched_schedule, load
  passed as percent small-int (no cross-task heap allocation)
- amyboard.py: _on_amy_overload handler, registered in start_amy()
- spss.js: 'L' sysex frame -> overload modal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bwhitman

bwhitman commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

Added the full overload chain in b09a5c6 — event-driven end to end, no polling anywhere:

amy_fb_task trips failsafe (synth already reset, doots played)
  → tulip_amy_overload_hook: mp_sched_schedule(callback, load%)   [amy_connector.c]
    → amyboard._on_amy_overload on the MP task:
        stop_sketch()                                              [so it can't re-wedge]
        F0 00 03 45 'L' <b64 load%> F7 out the USB-MIDI gadget     [best-effort]
          → AMYboard Online's persistent sysex listener             [spss.js]
            → "This sketch needed more CPU than the AMYboard has…" modal

New Python API: tulip.amy_overload_callback(cb) (pass None to clear). The load crosses the task boundary as a percent small-int, so no cross-task heap allocation. Headless boards just get the sketch stopped — the doots were the notification.

🤖 Generated with Claude Code

Teach the generator to count num_voices across all synths against the
AMYboard's CPU budget: Juno-6 voices cost 1/8 each, DX7 voices 1/12
each, total <= 1.0 (8 Juno, or 12 DX7, or a proportional mix like
4 Juno + 6 DX7). Keeps generated sketches under the new overload
failsafe threshold.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

🎛️ HW CI (physical bench)

AMYboard (USB-MIDI + AMY zP → audio; built-in tones + AMYboard World sketches acid/house/woodpiano over the SysEx control API): ✅ PASS — flashed this PR’s firmware; all checks matched the references.

Tulip (TULIP4_R11; serial-REPL audio + WiFi screenshot): ✅ PASS — flashed this PR’s firmware; all checks matched the references.

⬇️ Artifacts: recordings · screenshot · serial logs · run logs

Self-hosted bench. Audio spectral-compared to ref/hwci_basic.wav, the AMYboard World sketch refs (ref/{acid_generator,house_generator,woodpiano}.wav) + ref/tulip_basic.wav; Tulip screenshot pixel-compared to ref/tulip_screenshot.png. Both analog outs share one capture card, so the tests run sequentially.

@bwhitman bwhitman merged commit 0804b4d into main Jul 8, 2026
3 checks passed
pull Bot pushed a commit to manmuqingshan/tulipcc that referenced this pull request Jul 8, 2026
While the recordings run, poll tulip.amy_render_load() (0..1, ~1.0 =
overloaded; amy#826 / PR shorepine#1105) once a second over zP. Each sample prints
an hwci_load line on MicroPython stdout, riding the CDC serial-log capture
the run already does; the mean/max are printed next to the pass/fail
results. Informational only -- it does not gate pass/fail.

The poll line getattr-guards the call so firmware without the binding
prints -1 (reported as 'not supported by this firmware') instead of
pushing a traceback frame every second. Polling pauses during sketch
transfers to keep the multi-frame AK flow tight, and is skipped entirely
when the CDC log is off (--no-serial-log), since the samples would have
nowhere to land.

Bench-validated on a local AMYboard: polls acked, hwci_load lines captured
on CDC, parsing/averaging verified; the -1 fallback exercised against
firmware predating the binding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant