Skip to content

Commit

Permalink
feat(reset): Automatically reconnect if port disconnects during reset.
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewleech committed May 22, 2024
1 parent 4394a65 commit e3e0ecb
Showing 1 changed file with 27 additions and 0 deletions.
27 changes: 27 additions & 0 deletions esptool/reset.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,30 @@
DEFAULT_RESET_DELAY = 0.05 # default time to wait before releasing boot pin after reset


def reconnect(f):
def wrapper(*args):
"""
On targets with native USB, the reset process can cause the port to
disconnect / reconnect during reset.
This will retry reconnections for up to 10 seconds on ports that drop
out during the RTS/DTS reset process.
"""
self = args[0]
for retry in reversed(range(20)):
try:
if not self.port.isOpen():
self.port.open()
ret = f(*args)
break
except OSError:
if not retry:
raise
self.port.close()
time.sleep(0.5)
return ret
return wrapper


class ResetStrategy(object):
print_once = PrintOnce()

Expand All @@ -51,16 +75,19 @@ def __call__(self):
def reset(self):
pass

@reconnect
def _setDTR(self, state):
self.port.setDTR(state)

@reconnect
def _setRTS(self, state):
self.port.setRTS(state)
# Work-around for adapters on Windows using the usbser.sys driver:
# generate a dummy change to DTR so that the set-control-line-state
# request is sent with the updated RTS state and the same DTR state
self.port.setDTR(self.port.dtr)

@reconnect
def _setDTRandRTS(self, dtr=False, rts=False):
status = struct.unpack(
"I", fcntl.ioctl(self.port.fileno(), TIOCMGET, struct.pack("I", 0))
Expand Down

0 comments on commit e3e0ecb

Please sign in to comment.