mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-14 10:35:11 +00:00
firmware/ev3: allow buggy replies from EV3 bootloader
Add a hack to not fail if the EV3 bootloader sends an echo of the request instead of the expected response. There is a known compatibility issue with the EV3 bootloader USB and, e.g. Windows with USB 3.0 ports. This apparently causes a race condition where commands that don't take long to process before sending a response will have the request echoed back instead of receiving the actual response. If this happens, we can ignore it and assume the command was successful. It just won't work, e.g. for the version command since that has a payload in the response.
This commit is contained in:
+24
-7
@@ -1107,16 +1107,33 @@ function* handleFlashEV3(action: ReturnType<typeof firmwareFlashEV3>): Generator
|
||||
continue; // ignore empty reports
|
||||
}
|
||||
|
||||
const length = event.data.getInt16(0, true);
|
||||
let length = event.data.getInt16(0, true);
|
||||
const replyNumber = event.data.getInt16(2, true);
|
||||
const messageType = event.data.getUint8(4);
|
||||
let messageType = event.data.getUint8(4);
|
||||
const replyCommand = event.data.getUint8(5);
|
||||
const status = event.data.getUint8(6);
|
||||
const payload = event.data.buffer.slice(7, 7 + length + 2);
|
||||
let status = event.data.getUint8(6);
|
||||
let payload = event.data.buffer.slice(7, 7 + length + 2);
|
||||
|
||||
console.debug(
|
||||
`EV3 reply: length=${length}, replyNumber=${replyNumber}, messageType=${messageType}, replyCommand=${replyCommand}, status=${status}, payload=${payload}`,
|
||||
);
|
||||
if (messageType === 0x01) {
|
||||
// HACK: This works around a strange bug that can be triggered
|
||||
// e.g. by USB 3.0 on Windows. Sometimes the EV3 bootloader will
|
||||
// send the request back instead of the reply. In this case,
|
||||
// fake the reply to avoid protocol errors. This seems to work
|
||||
// as long as we aren't sending commands that have a reply
|
||||
// with a payload (like reading version or checksum)
|
||||
|
||||
console.warn(
|
||||
`Bad EV3 reply: length=${length}, replyNumber=${replyNumber}, messageType=${messageType}, replyCommand=${replyCommand}, status=${status}`,
|
||||
);
|
||||
length = 5;
|
||||
messageType = 0x03;
|
||||
status = 0x00;
|
||||
payload = new ArrayBuffer(0);
|
||||
|
||||
console.info(
|
||||
`Fixed EV3 reply: length=${length}, replyNumber=${replyNumber}, messageType=${messageType}, replyCommand=${replyCommand}, status=${status}`,
|
||||
);
|
||||
}
|
||||
|
||||
yield* put(
|
||||
firmwareDidReceiveEV3Reply(
|
||||
|
||||
Reference in New Issue
Block a user