|
26 | 26 | DEFAULT_RESET_DELAY = 0.05 # default time to wait before releasing boot pin after reset
|
27 | 27 |
|
28 | 28 |
|
29 |
| -def reconnect(f): |
30 |
| - def wrapper(*args): |
| 29 | +class ResetStrategy(object): |
| 30 | + print_once = PrintOnce() |
| 31 | + |
| 32 | + def __init__(self, port, reset_delay=DEFAULT_RESET_DELAY): |
| 33 | + self.port = port |
| 34 | + self.reset_delay = reset_delay |
| 35 | + |
| 36 | + def __call__(self): |
31 | 37 | """
|
32 |
| - On targets with native USB, the reset process can cause the port to |
| 38 | + On targets with USB modes, the reset process can cause the port to |
33 | 39 | disconnect / reconnect during reset.
|
34 |
| - This will retry reconnections for up to 10 seconds on ports that drop |
35 |
| - out during the RTS/DTS reset process. |
| 40 | + This will retry reconnections on ports that |
| 41 | + drop out during the reset sequence. |
36 | 42 | """
|
37 |
| - self = args[0] |
38 |
| - for retry in reversed(range(20)): |
| 43 | + for retry in reversed(range(3)): |
39 | 44 | try:
|
40 | 45 | if not self.port.isOpen():
|
41 | 46 | self.port.open()
|
42 |
| - ret = f(*args) |
| 47 | + self.reset() |
43 | 48 | break
|
44 |
| - except OSError: |
45 |
| - if not retry: |
| 49 | + except OSError as e: |
| 50 | + # ENOTTY for TIOCMSET; EINVAL for TIOCMGET |
| 51 | + if e.errno in [errno.ENOTTY, errno.EINVAL]: |
| 52 | + self.print_once( |
| 53 | + "WARNING: Chip was NOT reset. Setting RTS/DTR lines is not " |
| 54 | + f"supported for port '{self.port.name}'. Set --before and --after " |
| 55 | + "arguments to 'no_reset' and switch to bootloader manually to " |
| 56 | + "avoid this warning." |
| 57 | + ) |
| 58 | + break |
| 59 | + elif not retry: |
46 | 60 | raise
|
47 | 61 | self.port.close()
|
48 | 62 | time.sleep(0.5)
|
49 |
| - return ret |
50 |
| - |
51 |
| - return wrapper |
52 |
| - |
53 |
| - |
54 |
| -class ResetStrategy(object): |
55 |
| - print_once = PrintOnce() |
56 |
| - |
57 |
| - def __init__(self, port, reset_delay=DEFAULT_RESET_DELAY): |
58 |
| - self.port = port |
59 |
| - self.reset_delay = reset_delay |
60 |
| - |
61 |
| - def __call__(self): |
62 |
| - try: |
63 |
| - self.reset() |
64 |
| - except OSError as e: |
65 |
| - # ENOTTY for TIOCMSET; EINVAL for TIOCMGET |
66 |
| - if e.errno in [errno.ENOTTY, errno.EINVAL]: |
67 |
| - self.print_once( |
68 |
| - "WARNING: Chip was NOT reset. Setting RTS/DTR lines is not " |
69 |
| - f"supported for port '{self.port.name}'. Set --before and --after " |
70 |
| - "arguments to 'no_reset' and switch to bootloader manually to " |
71 |
| - "avoid this warning." |
72 |
| - ) |
73 |
| - else: |
74 |
| - raise |
75 | 63 |
|
76 | 64 | def reset(self):
|
77 | 65 | pass
|
78 | 66 |
|
79 |
| - @reconnect |
80 | 67 | def _setDTR(self, state):
|
81 | 68 | self.port.setDTR(state)
|
82 | 69 |
|
83 |
| - @reconnect |
84 | 70 | def _setRTS(self, state):
|
85 | 71 | self.port.setRTS(state)
|
86 | 72 | # Work-around for adapters on Windows using the usbser.sys driver:
|
87 | 73 | # generate a dummy change to DTR so that the set-control-line-state
|
88 | 74 | # request is sent with the updated RTS state and the same DTR state
|
89 | 75 | self.port.setDTR(self.port.dtr)
|
90 | 76 |
|
91 |
| - @reconnect |
92 | 77 | def _setDTRandRTS(self, dtr=False, rts=False):
|
93 | 78 | status = struct.unpack(
|
94 | 79 | "I", fcntl.ioctl(self.port.fileno(), TIOCMGET, struct.pack("I", 0))
|
|
0 commit comments