You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On macOS, Chrome's Web Serial API silently loses bytes during bulk 0x84/0x8A reads from the G6 controller. This affects the pre-existing SD-table Download button and the live pattern previews re-enabled by #151. It is a host-side (Chromium/macOS) limitation, not a firmware or #151 regression: the same controller sustains flawless full-speed downloads over pyserial on the same machine (the firmware repo's full HIL suite passes), and the firmware recovers cleanly from every aborted transfer (the reiserlab/LED-Display_G6_Firmware_Arena#16 fix behaving as designed).
All with a 21,338-byte pattern (002_grating_sq.pat); byte counts from arena-link.js's own bulk-read timeout diagnostics:
Default Web Serial receive buffer (255 bytes, no bufferSize passed in port.open): every bulk read stalled early — bulk-read data timeout: got 5650/21338 bytes. Preview spinner timed out; Download button failed.
With bufferSize: 1 MiB (local patch, below): the first bulk read after a fresh port-open completes reliably — the fix(console+studio): re-enable live 0x84 pattern preview #151 thumbnail rendered end-to-end (20-frame badge, hover animation). Subsequent bulk reads still fail intermittently with variable loss points: got 20625/21338, then got 17048/21338 on the next attempt.
The missing bytes are lost, not delayed: after a failed read, the next framed command returns a clean, correctly-framed reply with no stray body bytes flushing out first.
No JS exceptions, no read-loop error, no Chrome console errors — the loss is silent.
Same controller, same cable, same Mac, via pyserial: sustained multi-MB downloads at ~8 MB/s pass repeatedly (firmware HIL suite, 81/81 green).
Known upstream issue
This matches the reported Chromium Web Serial behavior for CDC devices under bulk transfer:
Buffer issue WICG/serial#164 — data stops being received after a certain amount when bufferSize is unset; larger buffers mitigate.
js/arena-link.js currently opens with { baudRate } only. Passing a large receive buffer takes the failure mode from "always fails a few KB in" to "first-transfer-after-open reliably works; later transfers intermittently lose tail bytes":
// bufferSize: Web Serial's default receive buffer is only 255 bytes.// On macOS that is too small for 0x84/0x8A bulk downloads — the CDC// read pipeline stalls a few KB into a fast burst, the controller// rightly treats the dead host as stalled (issue #16 fix 1, ~2 s bound)// and aborts the transfer. 1 MiB absorbs a whole transfer's burstiness.awaitthis._port.open({ baudRate,bufferSize: 1<<20});
(Currently applied locally on the bench Mac; happy to push to a branch/PR.)
Possible further directions (untested)
Retry-with-reopen in sendBulkRead: the strong first-transfer-after-open pattern suggests closing/reopening the port (or cancelling and re-acquiring the reader) between bulk reads may reset whatever state accumulates. Ugly but automatable inside ArenaLink.
Application-level integrity + retry: the bulk read already knows the expected byte count; on shortfall, retry the 0x84 once or twice before surfacing an error (previews are idempotent; the firmware recovers cleanly between attempts).
macOS + Chrome: SD Download button and live previews (fix(console+studio): re-enable live 0x84 pattern preview #151) fail intermittently; everything else (framed commands, uploads, streaming) works. Uploads are unaffected because the loss is in the host receive direction.
Relevant for CSHL course benches if any run macOS.
Summary
On macOS, Chrome's Web Serial API silently loses bytes during bulk
0x84/0x8Areads from the G6 controller. This affects the pre-existing SD-table Download button and the live pattern previews re-enabled by #151. It is a host-side (Chromium/macOS) limitation, not a firmware or #151 regression: the same controller sustains flawless full-speed downloads over pyserial on the same machine (the firmware repo's full HIL suite passes), and the firmware recovers cleanly from every aborted transfer (the reiserlab/LED-Display_G6_Firmware_Arena#16 fix behaving as designed).Environment
GET_PATTERN_FILEarena_console.htmlv9 (PR fix(console+studio): re-enable live 0x84 pattern preview #151 head) served from localhostEvidence
All with a 21,338-byte pattern (
002_grating_sq.pat); byte counts fromarena-link.js's own bulk-read timeout diagnostics:bufferSizepassed inport.open): every bulk read stalled early —bulk-read data timeout: got 5650/21338 bytes. Preview spinner timed out; Download button failed.bufferSize: 1 MiB(local patch, below): the first bulk read after a fresh port-open completes reliably — the fix(console+studio): re-enable live 0x84 pattern preview #151 thumbnail rendered end-to-end (20-frame badge, hover animation). Subsequent bulk reads still fail intermittently with variable loss points:got 20625/21338, thengot 17048/21338on the next attempt.read-loop error, no Chrome console errors — the loss is silent.Known upstream issue
This matches the reported Chromium Web Serial behavior for CDC devices under bulk transfer:
bufferSizeis unset; larger buffers mitigate.bufferSizerequired for bulk transmission; circular-buffer implementation quirks.Mitigation (proposed, one line + comment)
js/arena-link.jscurrently opens with{ baudRate }only. Passing a large receive buffer takes the failure mode from "always fails a few KB in" to "first-transfer-after-open reliably works; later transfers intermittently lose tail bytes":(Currently applied locally on the bench Mac; happy to push to a branch/PR.)
Possible further directions (untested)
sendBulkRead: the strong first-transfer-after-open pattern suggests closing/reopening the port (or cancelling and re-acquiring the reader) between bulk reads may reset whatever state accumulates. Ugly but automatable insideArenaLink.Impact
🤖 Generated with Claude Code