diff --git a/editor.html b/editor.html
index 32e02f6..4c147a9 100644
--- a/editor.html
+++ b/editor.html
@@ -1147,7 +1147,11 @@ async function loadFromDevice() {
let _midiAccess = null, _midiOn = false, _midiFlash = 0, _midiBeat = 0, _saveCb = null, _verCb = null;
function _midiInputs() { return _midiAccess ? [..._midiAccess.inputs.values()] : []; }
function _midiOutputs() { return _midiAccess ? [..._midiAccess.outputs.values()] : []; }
-function _send(bytes) { for (const o of _midiOutputs()) { try { o.send(bytes); } catch (_) {} } }
+function _isDevicePort(p) { const n = (p.name || "").toLowerCase(); return n.includes("pico") || n.includes("circuitpython") || n.includes("usb_midi"); }
+function _send(bytes) { // send only to the PM_K-1 (not loopback ports like "Midi Through", which just echo)
+ const outs = _midiOutputs(), dev = outs.filter(_isDevicePort);
+ for (const o of (dev.length ? dev : outs)) { try { o.send(bytes); } catch (_) {} }
+}
function _clockSysex() { const d = new Date(); // F0 7D 01 yr-2000 mo dd hh mm ss F7 -> sets the device RTC
return [0xF0, 0x7D, 0x01, d.getFullYear() - 2000, d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), 0xF7]; }
async function _ensureMidi() { // MIDI access WITH SysEx (needed to send/receive SysEx); cached
@@ -1245,20 +1249,22 @@ function _ack(timeout) {
return new Promise((res) => { _saveCb = res; setTimeout(() => { if (_saveCb) { _saveCb = null; res(null); } }, timeout); });
}
function _b64(u8) { let s = ""; for (let i = 0; i < u8.length; i++) s += String.fromCharCode(u8[i]); return btoa(s); }
-// Push the base64-encoded .mpy in flow-controlled chunks (512 base64 chars = a multiple of 4, so each
-// decodes cleanly on the device): begin(0x21) -> data(0x22)* -> commit(0x23), waiting for each ACK. The
-// device base64-decodes each chunk to /app.new, verifies the .mpy header, then A/B-installs + reboots.
+// Push the base64-encoded .mpy in small, flow-controlled chunks: begin(0x21) -> data(0x22)* -> commit(0x23),
+// waiting for each ACK. The device base64-decodes each chunk to /app.new, verifies the .mpy header, then
+// A/B-installs + reboots. CH is small (and a multiple of 4) so a chunk fits the Pico's USB-MIDI RX buffer.
async function _pushFirmware(b64) {
_send([0xF0, 0x7D, 0x21, 0xF7]);
if (await _ack(3000) !== true) return "handshake";
- const CH = 512;
+ const CH = 64, total = Math.ceil(b64.length / CH); let done = 0;
for (let o = 0; o < b64.length; o += CH) {
const part = b64.slice(o, o + CH); const msg = [0xF0, 0x7D, 0x22];
for (let i = 0; i < part.length; i++) msg.push(part.charCodeAt(i)); // base64 is ASCII
msg.push(0xF7); _send(msg);
const a = await _ack(4000);
- if (a !== true) return "transfer at " + o + "/" + b64.length + (a === false ? " (rejected)" : " (timeout)");
+ if (a !== true) return "chunk " + (done + 1) + "/" + total + (a === false ? " rejected" : " no-ack");
+ if (++done % 50 === 0) console.log("[fw] pushed", done, "/", total, "chunks");
}
+ console.log("[fw] all", total, "chunks sent; committing...");
_send([0xF0, 0x7D, 0x23, 0xF7]);
return (await _ack(6000)) === true ? null : "verify";
}