Add Code
This commit is contained in:
178
code/.venv/lib/python3.12/site-packages/esptool/reset.py
Normal file
178
code/.venv/lib/python3.12/site-packages/esptool/reset.py
Normal file
@@ -0,0 +1,178 @@
|
||||
# SPDX-FileCopyrightText: 2014-2023 Fredrik Ahlberg, Angus Gratton,
|
||||
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import struct
|
||||
import time
|
||||
|
||||
from .util import FatalError
|
||||
|
||||
# Used for resetting into bootloader on Unix-like systems
|
||||
if os.name != "nt":
|
||||
import fcntl
|
||||
import termios
|
||||
|
||||
# Constants used for terminal status lines reading/setting.
|
||||
# Taken from pySerial's backend for IO:
|
||||
# https://github.com/pyserial/pyserial/blob/master/serial/serialposix.py
|
||||
TIOCMSET = getattr(termios, "TIOCMSET", 0x5418)
|
||||
TIOCMGET = getattr(termios, "TIOCMGET", 0x5415)
|
||||
TIOCM_DTR = getattr(termios, "TIOCM_DTR", 0x002)
|
||||
TIOCM_RTS = getattr(termios, "TIOCM_RTS", 0x004)
|
||||
|
||||
DEFAULT_RESET_DELAY = 0.05 # default time to wait before releasing boot pin after reset
|
||||
|
||||
|
||||
class ResetStrategy(object):
|
||||
def __init__(self, port, reset_delay=DEFAULT_RESET_DELAY):
|
||||
self.port = port
|
||||
self.reset_delay = reset_delay
|
||||
|
||||
def __call__():
|
||||
pass
|
||||
|
||||
def _setDTR(self, state):
|
||||
self.port.setDTR(state)
|
||||
|
||||
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)
|
||||
|
||||
def _setDTRandRTS(self, dtr=False, rts=False):
|
||||
status = struct.unpack(
|
||||
"I", fcntl.ioctl(self.port.fileno(), TIOCMGET, struct.pack("I", 0))
|
||||
)[0]
|
||||
if dtr:
|
||||
status |= TIOCM_DTR
|
||||
else:
|
||||
status &= ~TIOCM_DTR
|
||||
if rts:
|
||||
status |= TIOCM_RTS
|
||||
else:
|
||||
status &= ~TIOCM_RTS
|
||||
fcntl.ioctl(self.port.fileno(), TIOCMSET, struct.pack("I", status))
|
||||
|
||||
|
||||
class ClassicReset(ResetStrategy):
|
||||
"""
|
||||
Classic reset sequence, sets DTR and RTS lines sequentially.
|
||||
"""
|
||||
|
||||
def __call__(self):
|
||||
self._setDTR(False) # IO0=HIGH
|
||||
self._setRTS(True) # EN=LOW, chip in reset
|
||||
time.sleep(0.1)
|
||||
self._setDTR(True) # IO0=LOW
|
||||
self._setRTS(False) # EN=HIGH, chip out of reset
|
||||
time.sleep(self.reset_delay)
|
||||
self._setDTR(False) # IO0=HIGH, done
|
||||
|
||||
|
||||
class UnixTightReset(ResetStrategy):
|
||||
"""
|
||||
UNIX-only reset sequence with custom implementation,
|
||||
which allows setting DTR and RTS lines at the same time.
|
||||
"""
|
||||
|
||||
def __call__(self):
|
||||
self._setDTRandRTS(False, False)
|
||||
self._setDTRandRTS(True, True)
|
||||
self._setDTRandRTS(False, True) # IO0=HIGH & EN=LOW, chip in reset
|
||||
time.sleep(0.1)
|
||||
self._setDTRandRTS(True, False) # IO0=LOW & EN=HIGH, chip out of reset
|
||||
time.sleep(self.reset_delay)
|
||||
self._setDTRandRTS(False, False) # IO0=HIGH, done
|
||||
self._setDTR(False) # Needed in some environments to ensure IO0=HIGH
|
||||
|
||||
|
||||
class USBJTAGSerialReset(ResetStrategy):
|
||||
"""
|
||||
Custom reset sequence, which is required when the device
|
||||
is connecting via its USB-JTAG-Serial peripheral.
|
||||
"""
|
||||
|
||||
def __call__(self):
|
||||
self._setRTS(False)
|
||||
self._setDTR(False) # Idle
|
||||
time.sleep(0.1)
|
||||
self._setDTR(True) # Set IO0
|
||||
self._setRTS(False)
|
||||
time.sleep(0.1)
|
||||
self._setRTS(True) # Reset. Calls inverted to go through (1,1) instead of (0,0)
|
||||
self._setDTR(False)
|
||||
self._setRTS(True) # RTS set as Windows only propagates DTR on RTS setting
|
||||
time.sleep(0.1)
|
||||
self._setDTR(False)
|
||||
self._setRTS(False) # Chip out of reset
|
||||
|
||||
|
||||
class HardReset(ResetStrategy):
|
||||
"""
|
||||
Reset sequence for hard resetting the chip.
|
||||
Can be used to reset out of the bootloader or to restart a running app.
|
||||
"""
|
||||
|
||||
def __init__(self, port, uses_usb_otg=False):
|
||||
super().__init__(port)
|
||||
self.uses_usb_otg = uses_usb_otg
|
||||
|
||||
def __call__(self):
|
||||
self._setRTS(True) # EN->LOW
|
||||
if self.uses_usb_otg:
|
||||
# Give the chip some time to come out of reset,
|
||||
# to be able to handle further DTR/RTS transitions
|
||||
time.sleep(0.2)
|
||||
self._setRTS(False)
|
||||
time.sleep(0.2)
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
self._setRTS(False)
|
||||
|
||||
|
||||
class CustomReset(ResetStrategy):
|
||||
"""
|
||||
Custom reset strategy defined with a string.
|
||||
|
||||
CustomReset object is created as "rst = CustomReset(port, seq_str)"
|
||||
and can be later executed simply with "rst()"
|
||||
|
||||
The seq_str input string consists of individual commands divided by "|".
|
||||
Commands (e.g. R0) are defined by a code (R) and an argument (0).
|
||||
|
||||
The commands are:
|
||||
D: setDTR - 1=True / 0=False
|
||||
R: setRTS - 1=True / 0=False
|
||||
U: setDTRandRTS (Unix-only) - 0,0 / 0,1 / 1,0 / or 1,1
|
||||
W: Wait (time delay) - positive float number
|
||||
|
||||
e.g.
|
||||
"D0|R1|W0.1|D1|R0|W0.05|D0" represents the ClassicReset strategy
|
||||
"U1,1|U0,1|W0.1|U1,0|W0.05|U0,0" represents the UnixTightReset strategy
|
||||
"""
|
||||
|
||||
format_dict = {
|
||||
"D": "self.port.setDTR({})",
|
||||
"R": "self.port.setRTS({})",
|
||||
"W": "time.sleep({})",
|
||||
"U": "self._setDTRandRTS({})",
|
||||
}
|
||||
|
||||
def __call__(self):
|
||||
exec(self.constructed_strategy)
|
||||
|
||||
def __init__(self, port, seq_str):
|
||||
super().__init__(port)
|
||||
self.constructed_strategy = self._parse_string_to_seq(seq_str)
|
||||
|
||||
def _parse_string_to_seq(self, seq_str):
|
||||
try:
|
||||
cmds = seq_str.split("|")
|
||||
fn_calls_list = [self.format_dict[cmd[0]].format(cmd[1:]) for cmd in cmds]
|
||||
except Exception as e:
|
||||
raise FatalError(f'Invalid "custom_reset_sequence" option format: {e}')
|
||||
return "\n".join(fn_calls_list)
|
||||
Reference in New Issue
Block a user