esp-rs / espflash

Serial flasher utility for Espressif SoCs and modules based on esptool.py
Apache License 2.0
455 stars 110 forks source link

Doesn't reset after flashing via JTAG-serial (Windows 11) #592

Closed bjoernQ closed 4 months ago

bjoernQ commented 4 months ago

Observed in v3.0.0-rc.1 but probably was an issue earlier. Host: Windows 11

When flashing via JTAG-serial the target doesn't get reset. When using --monitor option CTRL-R resets the target just fine.

From skimming over the code, it seems that reset_after and reset_after_flash (the later used by CTRL-R) are quite different

bjoernQ commented 4 months ago

Temporarily changing HardReset to what reset_after_flash does for JtagSerial like this

impl ResetStrategy for HardReset {
    fn reset(&self, serial_port: &mut Port) -> Result<(), Error> {
        debug!("Using HardReset reset strategy");

        // self.set_rts(serial_port, true)?;
        // sleep(Duration::from_millis(100));
        // self.set_rts(serial_port, false)?;

        self.set_dtr(serial_port, false)?;
        sleep(Duration::from_millis(100));
        self.set_rts(serial_port, true)?;
        self.set_dtr(serial_port, false)?;
        self.set_rts(serial_port, true)?;
        sleep(Duration::from_millis(100));
        self.set_rts(serial_port, false)?;

        Ok(())
    }
}

Fixes it for me - so we would need the PID and decide which way to reset

bjoernQ commented 4 months ago

Or an even simpler solution:

❯ git diff
diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs
index f0899eb..0fd54c5 100644
--- a/espflash/src/connection/mod.rs
+++ b/espflash/src/connection/mod.rs
@@ -257,6 +257,11 @@ impl Connection {
     // Reset the device taking into account the reset after argument
     pub fn reset_after(&mut self, is_stub: bool) -> Result<(), Error> {
         match self.after_operation {
+            ResetAfterOperation::HardReset
+                if self.get_usb_pid().unwrap_or_default() == USB_SERIAL_JTAG_PID =>
+            {
+                ClassicReset::new(false).reset(&mut self.serial)
+            }
             ResetAfterOperation::HardReset => HardReset.reset(&mut self.serial),
             ResetAfterOperation::NoReset => {
                 info!("Staying in bootloader");
SergioGasquez commented 4 months ago

Some more context regarding this issue, it seems to work fine on Linux. And we've already had a similar issue in the past, see: https://github.com/esp-rs/espflash/pull/157 and https://github.com/esp-rs/espflash/pull/153. At that point we introduced the reset sequence in reset_after_flash. We dont know where this came from, but its been working since then.

We tried using the same sequence for HardReset as esptool uses, but it does not solve the issue for @bjoernQ.