22
22
import usb .core
23
23
import usb .util
24
24
import zlib
25
- import time
26
- import math
27
25
28
26
# VID/PID
29
27
__VID = 0x0483
30
28
__PID = 0xDF11
31
29
32
30
# USB request __TIMEOUT
33
31
__TIMEOUT = 4000
34
- __NEXT_TIMEOUT = 0
35
- __STATUS_TIMEOUT = 20000
36
32
37
33
# DFU commands
38
34
__DFU_DETACH = 0
@@ -99,13 +95,6 @@ def get_string(dev, index):
99
95
return usb .util .get_string (dev , index )
100
96
101
97
102
- def timeout ():
103
- global __NEXT_TIMEOUT
104
- t = max (__TIMEOUT , __NEXT_TIMEOUT )
105
- __NEXT_TIMEOUT = 0
106
- return int (math .ceil (t ))
107
-
108
-
109
98
def find_dfu_cfg_descr (descr ):
110
99
if len (descr ) == 9 and descr [0 ] == 9 and descr [1 ] == _DFU_DESCRIPTOR_TYPE :
111
100
nt = collections .namedtuple (
@@ -161,45 +150,24 @@ def init():
161
150
162
151
def abort_request ():
163
152
"""Sends an abort request."""
164
- __dev .ctrl_transfer (0x21 , __DFU_ABORT , 0 , __DFU_INTERFACE , None , timeout () )
153
+ __dev .ctrl_transfer (0x21 , __DFU_ABORT , 0 , __DFU_INTERFACE , None , __TIMEOUT )
165
154
166
155
167
156
def clr_status ():
168
157
"""Clears any error status (perhaps left over from a previous session)."""
169
- __dev .ctrl_transfer (0x21 , __DFU_CLRSTATUS , 0 , __DFU_INTERFACE , None , timeout () )
158
+ __dev .ctrl_transfer (0x21 , __DFU_CLRSTATUS , 0 , __DFU_INTERFACE , None , __TIMEOUT )
170
159
171
160
172
161
def get_status ():
173
162
"""Get the status of the last operation."""
174
- _timeout = time .time () + max (__STATUS_TIMEOUT , timeout ())
175
- stat = None
176
- while time .time () < _timeout :
177
- try :
178
- stat = __dev .ctrl_transfer (
179
- 0xA1 , __DFU_GETSTATUS , 0 , __DFU_INTERFACE , 6 , int (_timeout - time .time ())
180
- )
181
- break
182
- except usb .core .USBError as ex :
183
- # If the firmware is blocked the transfer can timeout much quicker than
184
- # the supplied timeout. If so, retry until the overall timeout is used up.
185
- if "Operation timed out" not in str (ex ):
186
- raise
187
-
188
- if stat is None :
189
- raise SystemExit ("DFU: get_status timed out" )
163
+ stat = __dev .ctrl_transfer (0xA1 , __DFU_GETSTATUS , 0 , __DFU_INTERFACE , 6 , 20000 )
190
164
191
165
# firmware can provide an optional string for any error
192
166
if stat [5 ]:
193
167
message = get_string (__dev , stat [5 ])
194
168
if message :
195
169
print (message )
196
170
197
- # firmware can send a longer timeout request while it's performing slow operation eg. erase
198
- timeout_ms = stat [1 ] << 16 | stat [2 ] << 8 | stat [3 ]
199
- if timeout_ms :
200
- global __NEXT_TIMEOUT
201
- __NEXT_TIMEOUT = __TIMEOUT + timeout_ms
202
-
203
171
return stat [4 ]
204
172
205
173
@@ -212,9 +180,9 @@ def check_status(stage, expected):
212
180
def mass_erase ():
213
181
"""Performs a MASS erase (i.e. erases the entire device)."""
214
182
# Send DNLOAD with first byte=0x41
215
- __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 0 , __DFU_INTERFACE , "\x41 " , timeout () )
183
+ __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 0 , __DFU_INTERFACE , "\x41 " , __TIMEOUT )
216
184
217
- # Execute erase and wait until complete
185
+ # Execute last command
218
186
check_status ("erase" , __DFU_STATE_DFU_DOWNLOAD_BUSY )
219
187
220
188
# Check command state
@@ -228,7 +196,7 @@ def page_erase(addr):
228
196
229
197
# Send DNLOAD with first byte=0x41 and page address
230
198
buf = struct .pack ("<BI" , 0x41 , addr )
231
- __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 0 , __DFU_INTERFACE , buf , timeout () )
199
+ __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 0 , __DFU_INTERFACE , buf , __TIMEOUT )
232
200
233
201
# Execute last command
234
202
check_status ("erase" , __DFU_STATE_DFU_DOWNLOAD_BUSY )
@@ -241,7 +209,7 @@ def set_address(addr):
241
209
"""Sets the address for the next operation."""
242
210
# Send DNLOAD with first byte=0x21 and page address
243
211
buf = struct .pack ("<BI" , 0x21 , addr )
244
- __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 0 , __DFU_INTERFACE , buf , timeout () )
212
+ __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 0 , __DFU_INTERFACE , buf , __TIMEOUT )
245
213
246
214
# Execute last command
247
215
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):
275
243
# Send DNLOAD with fw data
276
244
chunk = min (__cfg_descr .wTransferSize , xfer_total - xfer_bytes )
277
245
__dev .ctrl_transfer (
278
- 0x21 , __DFU_DNLOAD , 2 , __DFU_INTERFACE , buf [xfer_bytes : xfer_bytes + chunk ], timeout ()
246
+ 0x21 , __DFU_DNLOAD , 2 , __DFU_INTERFACE , buf [xfer_bytes : xfer_bytes + chunk ], __TIMEOUT
279
247
)
280
248
281
249
# Execute last command
@@ -299,7 +267,7 @@ def write_page(buf, xfer_offset):
299
267
set_address (xfer_base + xfer_offset )
300
268
301
269
# Send DNLOAD with fw data
302
- __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 2 , __DFU_INTERFACE , buf , timeout () )
270
+ __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 2 , __DFU_INTERFACE , buf , __TIMEOUT )
303
271
304
272
# Execute last command
305
273
check_status ("write memory" , __DFU_STATE_DFU_DOWNLOAD_BUSY )
@@ -317,7 +285,7 @@ def exit_dfu():
317
285
set_address (0x08000000 )
318
286
319
287
# Send DNLOAD with 0 length to exit DFU
320
- __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 0 , __DFU_INTERFACE , None , timeout () )
288
+ __dev .ctrl_transfer (0x21 , __DFU_DNLOAD , 0 , __DFU_INTERFACE , None , __TIMEOUT )
321
289
322
290
try :
323
291
# Execute last command
0 commit comments