firmware/ev3: erase 2 sectors at one time

Change from erasing 1 sector at a time to erasing 2 sectors at a time.
This works around a USB issue where commands that don't take long to
execute can receive an incorrect response.

The point of erasing 2 sectors at a time is that when we write the data
to the sectors that we just erased, the last (partial) chunk of data is
now twice as large, which makes it take twice as long to write. This
seems to be long enough to avoid the USB issue.
This commit is contained in:
David Lechner
2026-01-24 16:16:02 -06:00
parent 04697e9afa
commit 055d2c8ca8
+11 -3
View File
@@ -1225,9 +1225,17 @@ function* handleFlashEV3(action: ReturnType<typeof firmwareFlashEV3>): Generator
const sectorSize = 64 * 1024; // flash memory sector size
const maxPayloadSize = 1018; // maximum payload size for EV3 commands
for (let i = 0; i < action.firmware.byteLength; i += sectorSize) {
const sectorData = action.firmware.slice(i, i + sectorSize);
assert(sectorData.byteLength <= sectorSize, 'sector data too large');
// HACK: Ideally, we would erase one sector at a time to minimize required
// alignment and make the progress indicator smoother. However, there is a
// bug triggered, e.g. by USB 3.0 on Windows, that causes bad replies from
// certain commands. This bug happens sometimes when the payload size is
// 384 bytes (triggered by 65536 % 1018 = 384). To work around this, we
// always erase two sectors to make the last chunk be twice as big
// (131072 % 1018 = 768).
const eraseSize = sectorSize * 2; // flash memory sector size
for (let i = 0; i < action.firmware.byteLength; i += eraseSize) {
const sectorData = action.firmware.slice(i, i + eraseSize);
const erasePayload = new DataView(new ArrayBuffer(8));
erasePayload.setUint32(0, i, true);