Revert "tools/pydfu.py: Respect longer timeouts requested by DFU dev..."

This reverts commit 4d6f60d428.

This implementation used the timeout as a maximum amount of time needed for
the operation, when actually the spec and other tools suggest that it's the
minumum delay needed between subsequent USB transfers.
This commit is contained in:
Andrew Leech 2020-07-01 15:01:16 +10:00 committed by Damien George
parent 494bcad8ab
commit 07f181a216

View File

@ -22,8 +22,6 @@ import sys
import usb.core
import usb.util
import zlib
import time
import math
# VID/PID
__VID = 0x0483
@ -31,8 +29,6 @@ __PID = 0xDF11
# USB request __TIMEOUT
__TIMEOUT = 4000
__NEXT_TIMEOUT = 0
__STATUS_TIMEOUT = 20000
# DFU commands
__DFU_DETACH = 0
@ -99,13 +95,6 @@ else:
return usb.util.get_string(dev, index)
def timeout():
global __NEXT_TIMEOUT
t = max(__TIMEOUT, __NEXT_TIMEOUT)
__NEXT_TIMEOUT = 0
return int(math.ceil(t))
def find_dfu_cfg_descr(descr):
if len(descr) == 9 and descr[0] == 9 and descr[1] == _DFU_DESCRIPTOR_TYPE:
nt = collections.namedtuple(
@ -161,32 +150,17 @@ def init():
def abort_request():
"""Sends an abort request."""
__dev.ctrl_transfer(0x21, __DFU_ABORT, 0, __DFU_INTERFACE, None, timeout())
__dev.ctrl_transfer(0x21, __DFU_ABORT, 0, __DFU_INTERFACE, None, __TIMEOUT)
def clr_status():
"""Clears any error status (perhaps left over from a previous session)."""
__dev.ctrl_transfer(0x21, __DFU_CLRSTATUS, 0, __DFU_INTERFACE, None, timeout())
__dev.ctrl_transfer(0x21, __DFU_CLRSTATUS, 0, __DFU_INTERFACE, None, __TIMEOUT)
def get_status():
"""Get the status of the last operation."""
_timeout = time.time() + max(__STATUS_TIMEOUT, timeout())
stat = None
while time.time() < _timeout:
try:
stat = __dev.ctrl_transfer(
0xA1, __DFU_GETSTATUS, 0, __DFU_INTERFACE, 6, int(_timeout - time.time())
)
break
except usb.core.USBError as ex:
# If the firmware is blocked the transfer can timeout much quicker than
# the supplied timeout. If so, retry until the overall timeout is used up.
if "Operation timed out" not in str(ex):
raise
if stat is None:
raise SystemExit("DFU: get_status timed out")
stat = __dev.ctrl_transfer(0xA1, __DFU_GETSTATUS, 0, __DFU_INTERFACE, 6, 20000)
# firmware can provide an optional string for any error
if stat[5]:
@ -194,12 +168,6 @@ def get_status():
if message:
print(message)
# firmware can send a longer timeout request while it's performing slow operation eg. erase
timeout_ms = stat[1] << 16 | stat[2] << 8 | stat[3]
if timeout_ms:
global __NEXT_TIMEOUT
__NEXT_TIMEOUT = __TIMEOUT + timeout_ms
return stat[4]
@ -212,9 +180,9 @@ def check_status(stage, expected):
def mass_erase():
"""Performs a MASS erase (i.e. erases the entire device)."""
# Send DNLOAD with first byte=0x41
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, "\x41", timeout())
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, "\x41", __TIMEOUT)
# Execute erase and wait until complete
# Execute last command
check_status("erase", __DFU_STATE_DFU_DOWNLOAD_BUSY)
# Check command state
@ -228,7 +196,7 @@ def page_erase(addr):
# Send DNLOAD with first byte=0x41 and page address
buf = struct.pack("<BI", 0x41, addr)
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, buf, timeout())
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, buf, __TIMEOUT)
# Execute last command
check_status("erase", __DFU_STATE_DFU_DOWNLOAD_BUSY)
@ -241,7 +209,7 @@ def set_address(addr):
"""Sets the address for the next operation."""
# Send DNLOAD with first byte=0x21 and page address
buf = struct.pack("<BI", 0x21, addr)
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, buf, timeout())
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, buf, __TIMEOUT)
# Execute last command
check_status("set address", __DFU_STATE_DFU_DOWNLOAD_BUSY)
@ -275,7 +243,7 @@ def write_memory(addr, buf, progress=None, progress_addr=0, progress_size=0):
# Send DNLOAD with fw data
chunk = min(__cfg_descr.wTransferSize, xfer_total - xfer_bytes)
__dev.ctrl_transfer(
0x21, __DFU_DNLOAD, 2, __DFU_INTERFACE, buf[xfer_bytes : xfer_bytes + chunk], timeout()
0x21, __DFU_DNLOAD, 2, __DFU_INTERFACE, buf[xfer_bytes : xfer_bytes + chunk], __TIMEOUT
)
# Execute last command
@ -299,7 +267,7 @@ def write_page(buf, xfer_offset):
set_address(xfer_base + xfer_offset)
# Send DNLOAD with fw data
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 2, __DFU_INTERFACE, buf, timeout())
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 2, __DFU_INTERFACE, buf, __TIMEOUT)
# Execute last command
check_status("write memory", __DFU_STATE_DFU_DOWNLOAD_BUSY)
@ -317,7 +285,7 @@ def exit_dfu():
set_address(0x08000000)
# Send DNLOAD with 0 length to exit DFU
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, None, timeout())
__dev.ctrl_transfer(0x21, __DFU_DNLOAD, 0, __DFU_INTERFACE, None, __TIMEOUT)
try:
# Execute last command