From ba8ec640bf1f6f6e58edc0c43b127371390bec7f Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Wed, 21 Oct 2020 11:34:35 +0200 Subject: [PATCH] reduce likelihood of `IndexError` during DFU In some cases `DfuDevice.control_msg` returns zero bytes. This might be because the device didn't have enough time to process the previous command. This commit adds a single retry after a delay. If the retry fails too, an error message is printed that helps the user to recover the ODrive. Since this issue occurs rarely it's unclear if this commit really solves the issue. --- tools/odrive/dfuse/DfuDevice.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/odrive/dfuse/DfuDevice.py b/tools/odrive/dfuse/DfuDevice.py index be7d404e..57035715 100644 --- a/tools/odrive/dfuse/DfuDevice.py +++ b/tools/odrive/dfuse/DfuDevice.py @@ -2,6 +2,7 @@ import usb.util import time import fractions import array +import time from odrive.dfuse.DfuState import DfuState DFU_REQUEST_SEND = 0x21 @@ -64,7 +65,20 @@ class DfuDevice: self.control_msg(DFU_REQUEST_SEND, DFU_CLRSTATUS, 0, None) def get_state(self): - return self.control_msg(DFU_REQUEST_RECEIVE, DFU_GETSTATE, 0, 1)[0] + msg = self.control_msg(DFU_REQUEST_RECEIVE, DFU_GETSTATE, 0, 1) + + # Second chance after giving the device some time to breathe. + if len(msg) == 0: + time.sleep(0.5) + msg = self.control_msg(DFU_REQUEST_RECEIVE, DFU_GETSTATE, 0, 1) + + if len(msg) == 0: + raise Exception("Could not get device state. Firmware upgrade will abort. " + "Please try again. If odrivetool can't find the device " + "anymore after this, follow the instructions in " + "https://docs.odriverobotics.com/odrivetool#device-firmware-update " + "(\"How to force DFU mode\").") + return msg[0] def abort(self): self.control_msg(DFU_REQUEST_RECEIVE, DFU_ABORT, 0, 0)