mirror of
https://github.com/espressif/esptool.git
synced 2025-10-18 00:32:43 +08:00
feat(hard_reset): Support custom hard reset sequence configuration
Closes https://github.com/espressif/esptool/issues/1004
This commit is contained in:

committed by
Roland Dobai

parent
6abd05d5c9
commit
1b157384bc
@@ -111,14 +111,19 @@ Complete list of configurable options:
|
||||
+------------------------------+-----------------------------------------------------------+----------+
|
||||
| custom_reset_sequence | Custom reset sequence for resetting into the bootloader | |
|
||||
+------------------------------+-----------------------------------------------------------+----------+
|
||||
| custom_hard_reset_sequence | Custom reset sequence for hard resetting the chip | |
|
||||
+------------------------------+-----------------------------------------------------------+----------+
|
||||
|
||||
Custom Reset Sequence
|
||||
---------------------
|
||||
Custom Reset Sequences
|
||||
----------------------
|
||||
|
||||
The ``custom_reset_sequence`` configuration option allows you to define a reset sequence which will get
|
||||
used when an :ref:`automatic reset into the serial bootloader <automatic-bootloader>` is performed.
|
||||
|
||||
The sequence is defined with a string in the following format:
|
||||
The ``custom_hard_reset_sequence`` option allows you to define a reset sequence which will get
|
||||
used when a hard reset (a reset out of the bootloader) is performed.
|
||||
|
||||
A sequence is defined with a string in the following format:
|
||||
|
||||
- Consists of individual commands divided by ``|`` (e.g. ``R0|D1|W0.5``).
|
||||
- Commands (e.g. ``R0``) are defined by a code (``R``) and an argument (``0``).
|
||||
@@ -148,3 +153,11 @@ For example: ``D0|R1|W0.1|D1|R0|W0.5|D0`` represents the following classic reset
|
||||
_setRTS(False) # EN=HIGH, chip out of reset
|
||||
time.sleep(0.05)
|
||||
_setDTR(False) # IO0=HIGH, done
|
||||
|
||||
Similarly, ``R1|W0.1|R0`` represents the classic hard reset sequence:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
_setRTS(True) # EN=LOW, chip in reset
|
||||
time.sleep(0.1)
|
||||
_setRTS(False) # EN=HIGH, chip out of reset
|
||||
|
@@ -74,7 +74,11 @@ class EspPortManager(serial.rfc2217.PortManager):
|
||||
"""
|
||||
if self.logger:
|
||||
self.logger.info("Activating hard reset in thread")
|
||||
HardReset(self.serial)()
|
||||
cfg_custom_hard_reset_sequence = cfg.get("custom_hard_reset_sequence")
|
||||
if cfg_custom_hard_reset_sequence is not None:
|
||||
CustomReset(self.serial, cfg_custom_hard_reset_sequence)()
|
||||
else:
|
||||
HardReset(self.serial)()
|
||||
|
||||
def _reset_thread(self):
|
||||
"""
|
||||
|
@@ -21,6 +21,7 @@ CONFIG_OPTIONS = [
|
||||
"reset_delay",
|
||||
"open_port_attempts",
|
||||
"custom_reset_sequence",
|
||||
"custom_hard_reset_sequence",
|
||||
]
|
||||
|
||||
|
||||
|
@@ -1525,9 +1525,13 @@ class ESPLoader(object):
|
||||
)
|
||||
return norm_xtal
|
||||
|
||||
def hard_reset(self):
|
||||
def hard_reset(self, uses_usb=False):
|
||||
print("Hard resetting via RTS pin...")
|
||||
HardReset(self._port)()
|
||||
cfg_custom_hard_reset_sequence = cfg.get("custom_hard_reset_sequence")
|
||||
if cfg_custom_hard_reset_sequence is not None:
|
||||
CustomReset(self._port, cfg_custom_hard_reset_sequence)()
|
||||
else:
|
||||
HardReset(self._port, uses_usb)()
|
||||
|
||||
def soft_reset(self, stay_in_bootloader):
|
||||
if not self.IS_STUB:
|
||||
|
@@ -205,5 +205,5 @@ class CustomReset(ResetStrategy):
|
||||
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}')
|
||||
raise FatalError(f"Invalid custom reset sequence option format: {e}")
|
||||
return "\n".join(fn_calls_list)
|
||||
|
@@ -8,7 +8,6 @@ from typing import Dict
|
||||
|
||||
from .esp32c6 import ESP32C6ROM
|
||||
from ..loader import ESPLoader
|
||||
from ..reset import HardReset
|
||||
from ..util import FatalError
|
||||
|
||||
|
||||
@@ -128,8 +127,7 @@ class ESP32C5ROM(ESP32C6ROM):
|
||||
) >> self.PCR_SYSCLK_XTAL_FREQ_S
|
||||
|
||||
def hard_reset(self):
|
||||
print("Hard resetting via RTS pin...")
|
||||
HardReset(self._port, self.uses_usb_jtag_serial())()
|
||||
ESPLoader.hard_reset(self, self.uses_usb_jtag_serial())
|
||||
|
||||
def change_baud(self, baud):
|
||||
if not self.IS_STUB:
|
||||
|
@@ -9,7 +9,6 @@ from typing import Dict
|
||||
|
||||
from .esp32 import ESP32ROM
|
||||
from ..loader import ESPLoader
|
||||
from ..reset import HardReset
|
||||
from ..util import FatalError, NotImplementedInROMError
|
||||
|
||||
|
||||
@@ -310,8 +309,7 @@ class ESP32S2ROM(ESP32ROM):
|
||||
if uses_usb_otg:
|
||||
self._check_if_can_reset()
|
||||
|
||||
print("Hard resetting via RTS pin...")
|
||||
HardReset(self._port, uses_usb_otg)()
|
||||
ESPLoader.hard_reset(self, uses_usb_otg)
|
||||
|
||||
def change_baud(self, baud):
|
||||
ESPLoader.change_baud(self, baud)
|
||||
|
@@ -9,7 +9,6 @@ from typing import Dict
|
||||
|
||||
from .esp32 import ESP32ROM
|
||||
from ..loader import ESPLoader
|
||||
from ..reset import HardReset
|
||||
from ..util import FatalError, NotImplementedInROMError
|
||||
|
||||
|
||||
@@ -382,8 +381,7 @@ class ESP32S3ROM(ESP32ROM):
|
||||
# Skip if response was not valid and proceed to reset; e.g. when monitoring while resetting
|
||||
pass
|
||||
|
||||
print("Hard resetting via RTS pin...")
|
||||
HardReset(self._port, uses_usb_otg)()
|
||||
ESPLoader.hard_reset(self, uses_usb_otg)
|
||||
|
||||
def change_baud(self, baud):
|
||||
ESPLoader.change_baud(self, baud)
|
||||
|
@@ -1604,7 +1604,7 @@ class TestConfigFile(EsptoolTestCase):
|
||||
with self.ConfigFile(config_file_path, invalid_reset_seq_config):
|
||||
output = self.run_esptool_error("flash_id")
|
||||
assert f"Loaded custom configuration from {config_file_path}" in output
|
||||
assert 'Invalid "custom_reset_sequence" option format:' in output
|
||||
assert "Invalid custom reset sequence option format:" in output
|
||||
|
||||
def test_open_port_attempts(self):
|
||||
# Test that the open_port_attempts option is loaded correctly
|
||||
|
Reference in New Issue
Block a user