Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unix tight reset #387

Closed
wants to merge 7 commits into from
Closed

Add unix tight reset #387

wants to merge 7 commits into from

Conversation

AVee
Copy link

@AVee AVee commented Apr 16, 2023

This adds the 'UnixTight' reset to flash method that Espressif added to EspTool to fix espressif/esptool#712. It takes some things from #344 but I tried to minimize the code impact a bit more. If more ways of resetting show up in the future the approach of actually creating an explicit ResetStrategy trait might still turn out to be better.

The flow is slightly different from what EspTool does, as this first tries UnixTight and Classic resets with the normal delay and then retries both with the longer delay. I think that should be fine as the same things are tried, just in a different order.

I've tested this on Linux and Windows, but not on macOS. It would be nice if someone could test that.

AVee added 2 commits April 16, 2023 20:36
Adds a reset approach for *nix called UnixTight reset by Espressif to avoid
timing issues with USB-serial connections on Linux and macOS. See
espressif/esptool#712 for details.
Add a #[cfg(unix)] I forgot (so it actually builds on windows).
@yshui yshui mentioned this pull request Apr 28, 2023
@SergioGasquez SergioGasquez linked an issue May 5, 2023 that may be closed by this pull request
@SergioGasquez
Copy link
Member

I was able to do some further testing on Linux (Arch Linux) and successfully flashed the following devkits:

  • ESP32-C3-DevKit-RUST-1
  • ESP32-C3-DevkitC-02
  • ESP32-Ethernet-Kit
  • ESP32-S2-DevKitC-1
  • ESP32-S3-DevKitC-1

@SergioGasquez
Copy link
Member

Just did some further testing on macOS 13.3.1 and successfully flashed the following devkits:

  • ESP32-C3-DevKit-RUST-1
  • ESP32-C3-DevkitC-02
  • ESP32-Ethernet-Kit
  • ESP32-S2-DevKitC-1
  • ESP32-S3-DevKitC-1

Keep comments consistent.
@tingox
Copy link

tingox commented May 20, 2023

Using a WT32-SC01 Plus on Debian 11.7 this patch improves things (board goes from "can't connect" to "works with caveats")

tingo@kg-vm4:~/personal/projects/2023/embedded/rust/espflash$ target/release/espflash board-info
[2023-05-20T20:56:54Z INFO ] Detected 2 serial ports
[2023-05-20T20:56:54Z INFO ] Ports which match a known common dev board are highlighted
[2023-05-20T20:56:54Z INFO ] Please select a port
[2023-05-20T20:56:56Z INFO ] Serial port: '/dev/ttyACM0'
[2023-05-20T20:56:56Z INFO ] Connecting...
[2023-05-20T20:56:56Z INFO ] Attempting UnixTight reset with default delay...
^C[2023-05-20T20:56:59Z INFO ] Attempting Classic reset with default delay...
[2023-05-20T20:56:59Z INFO ] Using flash stub
Chip type:         esp32s3 (revision v0.1)
Crystal frequency: 40MHz
Flash size:        16MB
Features:          WiFi, BLE
MAC address:       68:b6:b3:36:a5:a8

As can been seen above, I have to press Ctrl-C to abort the first attempt (if I don't, the program just waits forever - I'm guessing that the default delay is shorter than a few minutes)
if I specify the port however, the program just aborts when I press Ctrl-C

tingo@kg-vm4:~/personal/projects/2023/embedded/rust/espflash$ target/release/espflash board-info --port /dev/ttyACM0
[2023-05-20T20:57:10Z INFO ] Serial port: '/dev/ttyACM0'
[2023-05-20T20:57:10Z INFO ] Connecting...
[2023-05-20T20:57:10Z INFO ] Attempting UnixTight reset with default delay...
^C

no further attempts are tried. The official esptool works

tingo@kg-vm4:~/personal/projects/2023/embedded/rust/espflash$ ~/dl/esptool-v4.5.1-linux-amd64/esptool --port /dev/ttyACM0 chip_id
esptool.py v4.5.1
Serial port /dev/ttyACM0
Connecting...
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (revision v0.1)
Features: WiFi, BLE
Crystal is 40MHz
MAC: 68:b6:b3:36:a5:a8
Uploading stub...
Running stub...
Stub running...
Warning: ESP32-S3 has no Chip ID. Reading MAC instead.
MAC: 68:b6:b3:36:a5:a8
Hard resetting via RTS pin...

espflash/src/connection.rs Outdated Show resolved Hide resolved
espflash/src/connection.rs Show resolved Hide resolved
AVee added 2 commits June 1, 2023 22:23
Fix #[cfg(unix)] (and windows build).
Comment on lines +134 to +138
self.serial.write_data_terminal_ready(false)?;
self.serial.write_request_to_send(false)?;

self.serial.write_data_terminal_ready(true)?;
self.serial.write_request_to_send(false)?;
self.serial.write_data_terminal_ready(true)?;
self.serial.write_request_to_send(true)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this come from? esptool doesn't do this. (?)

Also, since in unix_tight_reset we have the IO0/EN comments, it would be good to have them here too

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only difference I can discern between this branch and the branch I have trying to solve this issue. If these 4 lines are all it takes to get my branch working that would be great, but I would like to be certain this does not have detrimental effects on other OSs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit of code essentially turns classic reset into unix tight reset. This seems to work because of the way the retrying is working currently:

https://github.com/esp-rs/espflash/pull/387/files#diff-9b8216d416248667f4612fb114829cb89c5754ca818d5784b3b0d879ec0d4ee6R70-R75

Here, we should be retrying the UNIX reset for X attempts, and then moving on to the classic mode.

espflash/src/connection.rs Show resolved Hide resolved
@dacut
Copy link

dacut commented Jul 17, 2023

FWIW, the reset issue seems to be specific to Apple Silicon Macs. I'm not able to get this to run successfully on my M1 MacBook Pro (MacBookPro18,2 MK233LL/A), nor does esptool.py in ESP-IDF 5.1 work for me. Same cable, etc., work fine on an AMD64 Linux box.

I'm trying to probe the signals on my scope, but the board doesn't break them out easily for my aged eyes and fingers.

@reinismu
Copy link

Tried this on my M1 mac and no luck.

~/projects/hub master !2 ❯ espflash monitor -b 115200                                                                                                                                     15s 12:10:52
[2023-07-24T09:10:55Z INFO ] 🚀 A new version of espflash is available: v2.0.1
[2023-07-24T09:10:55Z INFO ] Detected 6 serial ports
[2023-07-24T09:10:55Z INFO ] Ports which match a known common dev board are highlighted
[2023-07-24T09:10:55Z INFO ] Please select a port
[2023-07-24T09:10:58Z INFO ] Serial port: '/dev/tty.usbserial-10'
[2023-07-24T09:10:58Z INFO ] Connecting...
[2023-07-24T09:10:58Z INFO ] Attempting UnixTight reset with default delay...
[2023-07-24T09:10:59Z INFO ] Attempting Classic reset with default delay...
[2023-07-24T09:11:00Z INFO ] Attempting UnixTight reset with extra delay...
[2023-07-24T09:11:01Z INFO ] Attempting Classic reset with extra delay...
[2023-07-24T09:11:02Z INFO ] Attempting UnixTight reset with default delay...
[2023-07-24T09:11:03Z INFO ] Attempting Classic reset with default delay...
[2023-07-24T09:11:03Z INFO ] Attempting UnixTight reset with extra delay...
[2023-07-24T09:11:04Z INFO ] Attempting Classic reset with extra delay...
[2023-07-24T09:11:05Z INFO ] Attempting UnixTight reset with default delay...
[2023-07-24T09:11:06Z INFO ] Attempting Classic reset with default delay...
[2023-07-24T09:11:07Z INFO ] Attempting UnixTight reset with extra delay...
[2023-07-24T09:11:08Z INFO ] Attempting Classic reset with extra delay...
[2023-07-24T09:11:09Z INFO ] Attempting UnixTight reset with default delay...
[2023-07-24T09:11:10Z INFO ] Attempting Classic reset with default delay...
Error: espflash::connection_failed

  × Error while connecting to device
  ╰─▶ Failed to connect to the device
  help: Ensure that the device is connected and the reset and boot pins are not being held down

Has anyone managed to flash device with ARM Macs? Are there any workarounds?
#323 seems to be still unsolved.

@jessebraham
Copy link
Member

Has anyone managed to flash device with ARM Macs? Are there any workarounds?

I have an M1 Mac Mini that I use all the time without issue.

@dacut
Copy link

dacut commented Jul 24, 2023

Has anyone managed to flash device with ARM Macs? Are there any workarounds?

I have an M1 Mac Mini that I use all the time without issue.

Which module and serial driver (if not the built-in Apple driver with Ventura) are you using? Having the same issue with M1 MacBook Pro and various ESP boards (Teyleten Robot, ESP-WROOM-32 and ESP32-C3-DevKitM-1; LilyGo T5 EPaper displays using ESP32).

I can't think of a reason why Mini vs laptop should make a difference here, though it's certainly a possibility...

@dacut
Copy link

dacut commented Aug 5, 2023

Apparently the issue on my system isn't the reset. It's failing on the first MemData command.

I've instrumented espflash to print out the commands being sent, and everything is identical. It's just the response to the MemData command that is different. Here's what I'm seeing (kit is ESP32C3-DEV-MINI-1) -- everything is identical on Linux vs. Mac (aside from the serial port name) here:

[INFO ] Serial port: '/dev/ttyACM0' / 'dev/cu.usbmodem552E0044181'
[INFO ] Connecting...
[INFO ] Resetting device to flash mode using UART, extra_delay=false
[DEBUG] write_command: command=Sync
[DEBUG] write_command: command=Sync
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 8, return_length: 4, value: 538052359, error: 0, status: 0 }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 8, return_length: 4, value: 538052359, error: 0, status: 0 }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 8, return_length: 4, value: 538052359, error: 0, status: 0 }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 8, return_length: 4, value: 538052359, error: 0, status: 0 }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 8, return_length: 4, value: 538052359, error: 0, status: 0 }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 8, return_length: 4, value: 538052359, error: 0, status: 0 }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 8, return_length: 4, value: 538052359, error: 0, status: 0 }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 8, return_length: 4, value: 538052359, error: 0, status: 0 }
[DEBUG] write_command: command=ReadReg { address: 1073745920 }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 10, return_length: 4, value: 456216687, error: 0, status: 0 }
[INFO ] Using flash stub
[DEBUG] Loading flash stub for chip: Esp32c3
[DEBUG] Write 3748 byte stub text
[DEBUG] write_command: command=MemBegin { size: 3748, blocks: 1, block_size: 6144, offset: 1077411840, supports_encryption: false }
[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 5, return_length: 4, value: 456216687, error: 0, status: 0 }
[DEBUG] write_command: command=MemData { data: <3748 bytes that are identical>, pad_to: 4, pad_byte: 0, sequence: 0 }

Then, on Linux, I get:

[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 7, return_length: 4, value: 456216687, error: 0, status: 0 }
[DEBUG] Write 160 byte stub data
[DEBUG] write_command: command=MemBegin { size: 160, blocks: 1, block_size: 6144, offset: 1070164912, supports_encryption: false }

But from the Mac, I get:

[DEBUG] read_response: header=CommandResponse { resp: 1, return_op: 7, return_length: 4, value: 456216687, error: 1, status: 7 }
Error:   × The bootloader returned an error
  ├─▶ Error while running MemData command
  ╰─▶ Other

@horatiu-udrea
Copy link

The current fix worked for me.
Setup: Macbook Pro M2 Pro -> USB-C to USB-A adapter -> USB-A to Micro USB cable -> ESP32-PICO-D4

@dacut
Copy link

dacut commented Aug 7, 2023

There's definitely something going on lower level, my hunch is with the specific UART IC and driver being used, or possibly that and transistors and pullups. I'm back to looking at the reset timing, and spent a good part of the weekend staring at oscilloscope traces between (good) Linux flashing and (bad) M1 Mac flashing sequences, unable to discern a meaningful difference on the EN, GPIO0, TX, and RX lines. JTAG flashing does work, but many of my devices lack a USB-JTAG-attached port.

@kcking
Copy link
Contributor

kcking commented Aug 16, 2023

Chiming in in support of this PR: was able to flash a esp32-wroom-32d on an M1 macbook pro using this fork, installed using the command below

cargo install --git https://github.com/AVee/espflash --branch add_unix_tight_reset cargo-espflash espflash

@dacut
Copy link

dacut commented Sep 25, 2023

My issue appears to be very specific to a certain board with a peculiar rev of a UART + M1 Mac. <sigh>

Specifically, the Teyleten Robot ESP32-C3-DevKitM-1 board, but with the WCH343 UART (not pictured in the Amazon links).

@SergioGasquez
Copy link
Member

Can anyone affected by this issue check if #487 fixes the issue?

cargo install --git https://github.com/SergioGasquez/espflash --branch fix/resets cargo-espflash espflash

@jessebraham
Copy link
Member

Closing in favour of #487

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

espflash unable to connect ESP32 fails to enter download mode on Macbook via USB C Adapters (ESPTOOL-383)
9 participants