-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
ESP32 Reset To Bootloader Issues on Windows (ESPTOOL-386) #136
Comments
Thanks @negativekelvin. I don't know if you're following the forum thread, but I'm guessing you are. I considered this solution as well (although I didn't test it either.) The problem is, I'm not comfortable relying on the private interface of pyserial. At minimum, it's necessary to check it hasn't changed over any previous supported pyserial versions. But even if it works with all those, if the private interface changes in the future then it could break esptool without warning. A hacky but somewhat safer way would be to check all these properties exist with hasattr() before calling them, and fail back to the public API instead. But this is still super hacky. The safest, most maintainable, fix that I can think of is probably to call the win32 GetCommState/SetCommState API functions directly. This is a stable public API, and the only private part of pyserial it needs to touch is the port handle. I still don't like that idea, but it seems least likely to suddenly break. |
Or to submit a patch to pyserial, some variant of the existing |
Yes, that makes sense. I don't know if those properties and methods are very likely to change, so yes I like the check and fall back strategy until pyserial can support it. |
However it also looks like |
For full details on this issue I have done a full analysis of the problem on Win7 see I also confirm that by modifying esptool.py
to
That fix the problem on win7 (thanks to rudi post http://esp32.com/viewtopic.php?f=13&p=1512#p1512) |
In fact after analysis of rudi patch it is pure luck (thanks to watchdog and glitch on EN signal)
I have simplified it like that
to
The main problem is the glitch on IO0 during 1.1ms which does not allow to enter download mode as IO0 is sampled by ESP32 during this glitch but we are lucky that we have a reset by watchdog after 0.385s (with message RTCWDT_RTC_RESET) which then boot in download mode because EN=1 and IO0=0 For more details see Saleae Logic 1.2.10 capture of MyPatch:
For information MyPatch is a bit faster (300ms) compared to Rudi version and keep EN to 0 during at least 50ms(and not 3.5ms like Rudi which in fact is a glitch) and after multiple test my patch never fail with Win7 64bits and also under VirtualBox with Xubuntu 14.04 |
@bvernoux are you able to capture the waveforms for the method using reconfigure_port in the first post on windows? |
I just tried a different fix for this issue (1f5d9d2) which should be equivalent to calling _reconfigure_port, and I thought would definitely correct the issue. Unfortunately the timing seems to be the same (trace attached), even when both DTR & RTS are set in the same Windows API call. Which I think means the CP2102 Windows driver is doing this, and there's no way to change that pulse in software. |
That is disappointing. Time to ask silicon labs? |
What is the cause of this? |
It's a silicon bug, that will be fixed at some point. A solution that seems to work reliably is to add a ~2.2uF capacitor (I think 470nF-2.2uF range should be suitable) to the EN pin (between EN and GND), so it rises slower (there is a ~12K pullup on this pin.) This is not super desirable, as it requires a hardware change, but it works. |
@projectgus and all - thank you guys! |
hiya - got bit by this bug, and found a few things helped. capacitor helps but easier to change the second time.sleep(0.05) to time.sleep(0.5) e.g. https://github.com/adafruit/arduino-esp32/blob/master/tools/esptool.py#L279 |
For information it is already fixed in actual branch even without the capacitor => thanks to an ESP32 silicon bug with reset by watchdog after 0.385s |
Hi @bvernoux,
I don't believe this is fixed in any branch at the moment, without adding either a capacitor or the Hi @ladyada,
The problem I see is because the 0.5s delay happens to rely on a silicon bug, which is already fixed in the forthcoming chip revision. When the updated chips come out, the bug will bite everyone again (if the capacitor on EN hasn't been changed in the board design) and it will also take longer any time esptool.py fails to connect, due to the extra delays. There are perhaps some other ways to work around this, either a command line option like |
yah ok - i didn't realize it was a silicon issue on the esp32 (thought it was cp210x) in which case... i agree y'all should keep as wontfix. |
Just to be sure we're on the same page, the silicon issue on esp32 is what allows the extra
That would be awesome, thanks very much. :) |
ahh ok yes reading thru more carefully i understand the double-bug interaction! too funny - ok thanks! |
just found my way to this issue. not before spending some time banging my head against the wall, though :) the workaround seems fine, i just want to confirm: devkit hardware will be revised to increase the capacitor value, right? hopefully, in time for new chip revision which fixes the glitch. |
Yes, newer Espressif DevKits will fix this issue via increased capacitance on the EN pin. |
esptool v2.0 (current master, and the version in esp-idf) has a new The option can also be selected under "make menuconfig" in esp-idf. |
I've been investigating this and I think there's a more permanent solution that'd be effective and not too burdensome. Interestingly, the A long discussion follows with technical details I've gleaned, but the bottom line is that holding the chip in reset longer does the trick. The code change to esptool.py is a one-liner:
This has the advantage of working on both current boards (and 2 seconds isn't long to wait relative to everything else). If it were a default it'd work smoothly with the Arduino-ESP32 as well - not sure how one is supposed to get Note: for the hard-reset bit, while I see the The Core Board v2 and ESP-WROVER-KIT act differently upon serial disconnect, and downloads negotiation works slightly differently for each. Previous discussions about this include: Tested on Windows with the latest serial drivers via RealTerm: Note: interestingly, clear/set can be positive logic (clear = 0/low/false, set = 1/high/true), or the inverse (active low). In esptool.py the active low mode is used - here, I used active high notation. For the ESP-WROVER-KIT, to get to download mode, it's pretty simple:
The Core Board v2 is different though - it needs about 2 seconds delay between clearing DTR and setting it:
The boot up sequence differs slightly too - on the Core Board v2 that long pause causes a flash error. ESP-WROVER-KIT
Core Board v2
Also peculiar: if DTR and RTS are both cleared, the EN switch on the ESP-WROVER-KIT won't work at all (this is not the case on the Core Board v2). (As an aside, on both devices, if RTS is set, setting DTR (from cleared) resets the board. If DTR is clear, clearing RTS (from set) also resets the board.) The only obvious difference between the two RTS/DTR circuits in the corresponding schematics is that the Core Board v2 specs 12kohm resistors between the CP2102 bridge and the bases of the S8050 transistors, while the ESP-WROVER-KIT specs 1kohm resistors between the FT2232HL bridge and the bases of the S8050 transistors. (The BOOT and EN switch circuits appear to be identical on both.) Note: I have no shunts bridging the CTS/RTS headers on the WROVER board. It doesn't appear it would have a positive effect. |
One other thing... I'm using non-enumerating drivers here. I strongly recommend people stay far away from the enumerating drivers (or disable enumeration for the ports using it), particularly in Windows, if they don't have a reason to be using it (typically emulating a mouse). If the mouse filter gets spurious data (as is quite likely even from a factory fresh device during reset/boot-up) you could get a blue screen. Longer discussion here. The default driver Windows installs for the CP2102 is enumerating - the one I used to test all this is the same one but non-enumerating. That alone could compound everything above as there is that extra layer of introspection for enumeration purposes (and they do act differently... it's annoying. My fix above should work in either case, though the risk of BSOD would remain with enumeration). |
Attempts normal connection, then attempts legacy connection Improves legacy connection compatibility Resolves issue espressif#136
This is not windows specific. Same issue on macOS with cp210x drivers: espressif/esp-idf#305 |
Attempts normal connection, then attempts connection with esp32r0-related delays Improves esp32r0 connection compatibility Resolves issue espressif#136
Attempts normal connection, then attempts connection with esp32r0-related delays Improves esp32r0 connection compatibility Resolves issue espressif#136
Improves connection compatibility - Attempts normal connection, then attempts connection with an extended reset delay and a delay that triggers a watchdog timeout (esp32r0-only) to more reliably enter download mode. Fallback design - initial connect is without workarounds - if that fails, the extra delays are used. Resolves issue espressif#136
Improves connection compatibility - Attempts normal connection, then attempts connection with an extended reset delay and a delay that triggers a watchdog timeout (esp32r0-only) to more reliably enter download mode. Fallback design - initial connect is without workarounds - if that fails, the extra delays are used. Resolves issue espressif#136
Improves connection compatibility - Attempts normal connection, then attempts connection with an extended reset delay and a delay that triggers a watchdog timeout (esp32r0-only) to more reliably enter download mode. Fallback design - initial connect is without workarounds - if that fails, the extra delays are used. Resolves issue espressif#136
Thanks to @MartyMacGyver and everyone else who helped diagnose this, we seem to have a reliable fix now which doesn't require any special command line arguments. This fix should propagate to the ESP-IDF & Arduino esptool.py versions, soon. Also, new development board hardware should no longer exhibit the underlying bug in the first place (provided 100nF or more of capacitance is present on the EN pin, with a 10K or higher pullup on that pin). Please open an issue if this fix doesn't appear to fix auto-reset on your board (either reopen this issue, or if you have more specifics to provide then please open a new one instead.) Thanks. |
Hi, Also I needed to put this on the platformio.ini configuration file to be able to use the serial monitor (in Arduino ide no fix is needed):
|
FWIW, I have the NodeMCU ESP32S boards (https://www.amazon.ca/KeeYees-Development-Bluetooth-Microcontroller-ESP-WROOM-32/dp/B07QCP2451) that needed button pressing to program. A 0.1µF cap didn't change anything, a 2.2µF did the trick. ESPtool.py v2.8 under Linux. [@projectgus not sure whether this is sufficient reason to open a new issue? I don't seem to be able to reopen this one] |
Cross-link to similar problem for CP2102 chips and its solution: |
Hi all, Thanks for all the analysis and descriptions so far. I ran into the issue of auto-resetting an "ESP32S" module (based on ESP-WROOM-32 and CP2102) today on Linux (Debian 11.6) and looked into it a bit. I do not know if it is a
Flashing needs to be done with Some technical details as far as I understand them so far: The pyserial module uses the TIOCMBIS and TIOCMBIC ioctl calls to modify one of the DTR and RTS bits at a time. Using those commands, I could not convince the CP2102 + transistors on the board to output signals with a timing that worked. Using the TIOCMSET ioctl call, it is possible to set RTS and DTR to a new state at the same time. The CP2102 + transistors still did not output the signals exactly as indicated in the command. ( |
Hi @stefanschuermans, |
Hi @radimkarnis. Thanks for this pointer. I have tried this version and it works for me as well. :-) That's great, so no I do not need a custom solution. |
wie lad ich diese version herunter und wie kann die installiern bitte hilfe |
On windows, it seems like there are timing issues with the reset to bootloader functions using the DTR and RTS circuit for esp32 because setDTR and setRTS are sent separately. Possible fix:
I haven't scoped this or tested it because my v1 board has the transistor bug.
The text was updated successfully, but these errors were encountered: