Skip to content

Commit 055d2c8

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 04697e9 commit 055d2c8

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
@@ -1225,9 +1225,17 @@ function* handleFlashEV3(action: ReturnType<typeof firmwareFlashEV3>): Generator
12251225
const sectorSize = 64 * 1024; // flash memory sector size
12261226
const maxPayloadSize = 1018; // maximum payload size for EV3 commands
12271227

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

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

0 commit comments

Comments
 (0)