Skip to content

Commit a1294e8

Browse files
committed
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.
1 parent b826a0e commit a1294e8

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

src/firmware/sagas.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,9 +1234,17 @@ function* handleFlashEV3(action: ReturnType<typeof firmwareFlashEV3>): Generator
12341234
const sectorSize = 64 * 1024; // flash memory sector size
12351235
const maxPayloadSize = 1018; // maximum payload size for EV3 commands
12361236

1237-
for (let i = 0; i < action.firmware.byteLength; i += sectorSize) {
1238-
const sectorData = action.firmware.slice(i, i + sectorSize);
1239-
assert(sectorData.byteLength <= sectorSize, 'sector data too large');
1237+
// HACK: Ideally, we would erase one sector at a time to minimize required
1238+
// alignment and make the progress indicator smoother. However, there is a
1239+
// bug triggered, e.g. by USB 3.0 on Windows, that causes bad replies from
1240+
// certain commands. This bug happens sometimes when the payload size is
1241+
// 384 bytes (triggered by 65536 % 1018 = 384). To work around this, we
1242+
// always erase two sectors to make the last chunk be twice as big
1243+
// (131072 % 1018 = 768).
1244+
const eraseSize = sectorSize * 2; // flash memory sector size
1245+
1246+
for (let i = 0; i < action.firmware.byteLength; i += eraseSize) {
1247+
const sectorData = action.firmware.slice(i, i + eraseSize);
12401248

12411249
const erasePayload = new DataView(new ArrayBuffer(8));
12421250
erasePayload.setUint32(0, i, true);

0 commit comments

Comments
 (0)