Skip to content

Add MIDI SysEx firmware upgrade for v1.0.0+ devices - #20

Merged
DavidMenting merged 1 commit into
mainfrom
feat/sysex-firmware-upgrade
Jul 7, 2026
Merged

Add MIDI SysEx firmware upgrade for v1.0.0+ devices#20
DavidMenting merged 1 commit into
mainfrom
feat/sysex-firmware-upgrade

Conversation

@DavidMenting

Copy link
Copy Markdown
Member

Summary

  • Adds an in-app firmware upgrade over MIDI SysEx for devices running v1.0.0+ firmware, complementing the legacy (pre-v1.0.0) UF2 drag-and-drop flow from Add legacy firmware upgrade flow for pre-v1.0.0 devices #19 — no manual file handling needed.
  • Implements the Begin/Bytes/End/Abort protocol (tags 0x20–0x23) from drumtool.js: UF2 validation, SHA-256 via WebCrypto, 8-to-7 / 3-to-16 SysEx encoding, 1022-byte chunks with per-chunk ACK/NAK handshaking (5s timeout), and Abort on stream failure.
  • New FirmwareUpgrade dialog mirrors the legacy flow: auto-opens when a connected non-legacy device reports firmware older than the bundled release, shows download/upload progress, and auto-dismisses once the device reboots and reconnects with the new version.
  • Bundles the firmware at build time: a prebuild script (scripts/fetch-latest-firmware.mjs) downloads the latest release UF2 into static/firmware/ and writes firmwareManifest.json. GitHub's release-asset CDN sends no CORS headers, so the browser cannot fetch the bytes cross-origin; serving same-origin fixes both this flow and makes the app usable offline. Replaces the runtime githubReleaseService.
  • Gated behind the sysexFirmwareUpgrade feature flag (default off).

Notes

  • Shipping a new firmware release now requires a webapp rebuild/redeploy (the fetch runs inside docker build). If GitHub is unreachable at build time, the script falls back to the committed UF2 with a warning.
  • If the trial boot fails and the device rolls back to the old firmware, the dialog intentionally stays open (reported version is still older than bundled).

Test plan

  • datoFeatures.enable('sysexFirmwareUpgrade'), connect a v1.0.0+ DRUM on older firmware → prompt appears, upgrade streams with progress, dialog closes after reboot
  • datoFeatures.showFirmwareUpgrade() on an up-to-date device → forced flow flashes and auto-dismisses after reconnect
  • Legacy pre-v1.0.0 device still gets the legacy flow (unchanged)
  • npm run build (including prebuild fetch) and npm run check pass

Devices on v1.0.0 and later support streaming a UF2 image over SysEx to
the inactive A/B partition (Begin/Bytes/End/Abort, tags 0x20-0x23, as in
drumtool.js flash). Add an upgrade dialog that mirrors the legacy flow:
it auto-opens when a connected non-legacy device reports firmware older
than the bundled release, downloads the UF2, streams it with per-chunk
ACK/NAK handshaking and a progress bar, then auto-dismisses once the
device reboots and reconnects with the new version.

The firmware is bundled at build time: a prebuild script fetches the
latest GitHub release UF2 into static/firmware/ and records it in a
manifest, because GitHub's release-asset CDN sends no CORS headers and
the browser cannot fetch the bytes directly. This replaces the runtime
githubReleaseService; the app now works offline and never advertises a
version it cannot deliver.

Hidden behind the sysexFirmwareUpgrade feature flag; the flow can be
forced open on any device via datoFeatures.showFirmwareUpgrade().
@DavidMenting
DavidMenting merged commit f550dbd into main Jul 7, 2026
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