Closed alex-taffe closed 2 years ago
Hello @alex-taffe,
It seems as if the device isn’t going into flash mode.
Your assumption seems to be right. This is confirmed by Failed to connect to Espressif device: Wrong boot mode detected (0x13)! The chip needs to be in download mode.
(esptool detects wrong boot mode since v3.2, that is why the PlatformIO with esptool v3.1 log doesn't show this).
Is there a way to open the device and switch the ESP32 into the download mode manually? If there are no boot
/flash
and reset
buttons, pulling GPIO0
low on reset should do the trick. This way we could confirm there is no other issue.
I use MacBook Pro M1 with the latest macOS Monterrey and the only time I see similar problems is when using a low-quality USB cable, but you say you've tried many. Also, there are no other reports of Macs unable to reset ESP chips properly, so I do not really see an obvious reason for your issue.
Do you have access to a Windows or Linux device? Could you please try to confirm it works on other OSs?
Also, the Freematics documentation mentions Using USB hub with external power supply is recommended.
. Using such a USB hub can cause faulty propagation of DTR/RTS signals necessary for resetting the chip into the download mode.
So I was able to pull the device apart. After pulling the cell module off, there doesnt appear to be any easy access to either a boot/flash/reset button nor GPIO0. Externally, the device only has GND, GPIO32 / Rx2 (ESP32), VCC (5V), and GPIO33 / Tx2 (ESP32). I also unfortunately don’t have another computer easily accessible at the moment, but might be able to get to one next week.
I have never used an external power supply (even with my old laptop where the flashing was working). The device requires a fair bit of power, but the MacBook can provide a fair bit. I also tried plugging the device into a vehicle’s OBD port which can supply plenty of power and the flashing still failed. This makes me think it’s not a power issue, plus there’s no hub so the DTR/RTS
commands should be flowing properly.
Interestingly enough, if I run the pio
command, then open the Arduino app and its serial monitor while that’s occurring, this is what’s being dumped out. This makes me think that the device actually is in flash mode but python just isn’t receiving the data properly.
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
Well I’m slightly confused actually. The standalone version is saying Wrong boot mode detected (0x13)!
but that is indeed what the device is claiming to be in. However, it also seems like 0x13
is SPI_FAST_FLASH_BOOT
based on what the serial monitor is dumping out, which sounds right to me
On the left of the board, there’s a port that appears to say DI0
but I’m not sure if that’s for GPIO0 or just a generic digital in 0 or something so don’t necessarily want to short it. The freematics website wasnt overly helpful
The boot log dump you've provided confirms the device is not switching into the download mode. boot:0x13 (SPI_FAST_FLASH_BOOT)
means it is in the normal SPI flash boot mode. Later in the log, you can actually see the esp loading application data and the entrypoint.
If you were in the download mode, there would be something like boot:0x3 DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2)
. See this page for more information.
If you look at this schematic taken from the Freematics website, the ESP32 module is in the down right corner. It seems like the pins in the schematic match with the physical module (but I can't say for sure). You should be able to bridge the GPIO0 pin with any of the GND pins with a piece of wire (or tweezers / a paperclip, maybe?). If you bridge these, then apply power (keep them bridged) to the chip and try any esptool command or flashing, it should work.
Sorry, this is kinda hacky, but at this moment I do not have any other ideas on how to verify.
I bridged GPIO0 to ground during power connect and it definitely went into download mode, code uploaded and the serial output of my program ran fine. So this definitely seems to be a software issue getting the thing into download mode.
pio run -t upload -t monitor 10:31
Processing esp32dev (platform: espressif32; board: esp32dev; framework: arduino)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32dev.html
PLATFORM: Espressif 32 (3.4.0) > Espressif ESP32 Dev Module
HARDWARE: ESP32 160MHz, 320KB RAM, 4MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
- framework-arduinoespressif32 3.10006.210326 (1.0.6)
- tool-esptoolpy 1.30100.210531 (3.1.0)
- tool-mkspiffs 2.230.0 (2.30)
- tool-openocd-esp32 2.1000.20210721 (10.0)
- toolchain-xtensa32 2.50200.97 (5.2.0)
Converting carduino.ino
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 36 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <ESP32 BLE Arduino> 1.0.1
|-- <FreematicsPlus>
| |-- <WiFi> 1.0
| |-- <SPI> 1.0
|-- <TinyGPS>
|-- <FS> 1.0
|-- <SD(esp32)> 1.0.5
| |-- <FS> 1.0
| |-- <SPI> 1.0
|-- <SPI> 1.0
|-- <SPIFFS> 1.0
| |-- <FS> 1.0
Building in release mode
Compiling .pio/build/esp32dev/src/carduino.ino.cpp.o
Retrieving maximum program size .pio/build/esp32dev/firmware.elf
Checking size .pio/build/esp32dev/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [= ] 11.3% (used 36996 bytes from 327680 bytes)
Flash: [==== ] 39.4% (used 1315682 bytes from 3342336 bytes)
Configuring upload protocol...
AVAILABLE: esp-prog, espota, esptool, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa
CURRENT: upload_protocol = esptool
Looking for upload port...
Auto-detected: /dev/cu.usbserial-0001
Uploading .pio/build/esp32dev/firmware.bin
esptool.py v3.1
Serial port /dev/cu.usbserial-0001
Connecting....
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 24:0a:c4:8b:f4:30
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 16MB
Flash will be erased from 0x00001000 to 0x00005fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x00151fff...
Flash params set to 0x0240
Compressed 17104 bytes to 11191...
Writing at 0x00001000... (100 %)
Wrote 17104 bytes (11191 compressed) at 0x00001000 in 0.5 seconds (effective 268.2 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 129...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (129 compressed) at 0x00008000 in 0.1 seconds (effective 192.2 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.1 seconds (effective 496.6 kbit/s)...
Hash of data verified.
Compressed 1315792 bytes to 735652...
Writing at 0x00010000... (2 %)
Writing at 0x0001b03c... (4 %)
Writing at 0x0002ee53... (6 %)
Writing at 0x0003a8f8... (8 %)
Writing at 0x0004ec5f... (11 %)
Writing at 0x00054b1d... (13 %)
Writing at 0x0005ae70... (15 %)
Writing at 0x0006099e... (17 %)
Writing at 0x00066c0b... (20 %)
…
Writing at 0x0014bb19... (100 %)
Wrote 1315792 bytes (735652 compressed) at 0x00010000 in 19.5 seconds (effective 539.8 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
====================================================================================================== [SUCCESS] Took 26.44 seconds ======================================================================================================
--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
Please build project in debug configuration to get more details about an exception.
See https://docs.platformio.org/page/projectconf/build_configurations.html
--- Miniterm on /dev/cu.usbserial-0001 115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
10:32:01.462 > Initializing Carduino...
So some more stuff I just tried. I tried making a pipenv to see if my python install was broken. Still didn’t work. Created a new fresh install of Monterey, no go. Also tried on my M1 Max work laptop, didn’t work on that machine either.
Nice job, I am glad you can flash the device! This means we have narrowed it down as much as possible.
Can you please try updating the CP210x USB to UART Bridge drivers? If this doesn't help, we will need to capture the DTR/RTS signals - is there any chance you have a logic analyzer / oscilloscope?
So I had actually played around with these drivers during my own debugging and it didn’t seem to help. I just reinstalled them and restarted the machine just for the sake of clarity. It appears to create a new virtual USB device at /dev/cu.SLAB_USBtoUART
but doesn’t actually work:
python3 esptool.py --chip=esp32 run 10:38
esptool.py v3.3-dev
Found 3 serial ports
Serial port /dev/cu.usbserial-0001
Connecting......................................
/dev/cu.usbserial-0001 failed to connect: Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
Serial port /dev/cu.SLAB_USBtoUART
Connecting......................................
/dev/cu.SLAB_USBtoUART failed to connect: Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
Serial port /dev/cu.Bluetooth-Incoming-Port
Connecting......................................
/dev/cu.Bluetooth-Incoming-Port failed to connect: Failed to connect to ESP32: No serial data received.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
A fatal error occurred: Could not connect to an Espressif device on any of the 3 available serial ports.
pio
fails in the same fashion. I unfortunately do not have an oscilloscope, I might have a friend that does but not sure
Do you have any generic instructions on what signals are being sent to the device to get it into download mode? I have some experience interacting with USB devices via Swift. I’m wondering if I can recreate the steps in Swift (or some other language), we can narrow it down to being something with the Python install/esptool code base. If it’s something simple like “open device at baud rate 9600, send the string RESET\n\r
, and close the device”, can probably recreate it pretty quickly.
I just tried this:
if (Serial.available() > 0) {
// read the incoming string:
String incomingString = Serial.readString();
// prints the received data
Serial.print("I received: ");
Serial.println(incomingString);
}
From the Arduino serial manager, if I type something, it does manage to spit it back out. This combined with the fact that flashing does work, serial communication is working bidirectionally, and that my old laptop could put the device into flashing mode successfully makes me think that this is neither a macOS specific issue nor a hardware one. It seems to be either related to the firmware on the device, something wrong with esptool, or a python issue.
Do you have any generic instructions on what signals are being sent to the device to get it into download mode?
Read through this documentation page to learn more about automatically resetting into download mode.
Esptool resets the chip right here: https://github.com/espressif/esptool/blob/master/esptool.py#L584. It is just a simple sequence of asserting DTR and RTS lines (the same way you would be pressing the boot
and rst
physical buttons). This can be easily replicated.
It seems to be either related to the firmware on the device, something wrong with esptool, or a python issue.
I would argue otherwise. It absolutely doesn't matter what firmware is loaded into the device - the chip will always switch into the download mode if GPIO0 is pulled low during reset. This is handled by ROM, which is burned into the chip and runs before any user application is run. (See ESP32 datasheet, section 2.4 Strapping pins)
I never say esptool is perfect, but it has been successfully used and well tested on ESP32 on millions of occasions. It seems highly unlikely there is suddenly a problem in the reset logic. And as long as you use a supported version of Python (any from 2.7 to 3.9) and pyserial>=3.0, this should most definitely work.
Usually, this is either a faulty HW or driver-related problem.
flashing does work, serial communication is working bidirectionally
No one questions this. This was already confirmed the moment you got this message: Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode.
. If communication didn't work, esptool wouldn't be able to detect the boot log and read the current boot mode. If comms work, flashing can also happen - IF the chip is in the download mode. You were able to switch into it manually, which rules out chip problems.
At this moment I am out of ideas, we would need to capture DTR/RTS traces or USB packets to get more information.
Well, I found the issue. This made me wonder if it was the USB C to USB A adapter I was using. The original one I was using was a simple C>A to I wasn't particularly suspicious. I tried 3 more hubs and they still all failed. I finally tried a cheapo hub from amazon that mainly was meant to be an XQD adapter and happened to have a USB A port. Worked. Something about the DTR/RTS was being lost. I can’t even begin to explain why, but crummy USB hubs strike again. Sorry for the trouble😅
Also, the Freematics documentation mentions
Using USB hub with external power supply is recommended.
. Using such a USB hub can cause faulty propagation of DTR/RTS signals necessary for resetting the chip into the download mode.
Should also mention that included in the list of hubs I tried was the official Apple USB C AV Multiport adapter that costs $70 or something...
I am glad you could resolve this! The DTR/RTS propagation is definitely something I plan to investigate more
Operating system
macOS 12.0.1 (21A559)
Python version
3.9.8
What Chip
ESP32 (Freematics ONE+ Model B)
What development board or other hardware is the chip attached to
STM32 protocol co-processor Integrated ICM-20948 9-axis motion sensor Integrated u-blox UBX-M8030 10Hz GNSS module and antenna Integrated SIM7600A-H or SIM7600E-H 4G LTE CAT4 cellular module
If your hardware is custom or unusual, please attach a photo to the issue.
https://freematics.com/products/freematics-one-plus-model-b/
Is anything else attached to the development board, except for the serial flasher connections?
https://freematics.com/products/freematics-one-plus-model-b/
Are you running esptool.py from an IDE such as Arduino or Eclipse?
Both from
pio
in the command line and plain command line with just esptoolFull esptool.py command line that was run:
python3 esptool.py --trace run
andpio run -t upload -t monitor
Full output from esptool.py
Do you have any other information from investigating this?
I used to have a 2018 MacBook Pro and an iMac Pro. This same issue occurred on my iMac every time and I was doing development exclusively on my MacBook. I recently traded both for a 2021 M1 Max MacBook Pro. The backup from my iMac was moved to my new laptop. The issue is now occurring on my new laptop as well, which is a bit of a problem as it is my only system. Interestingly, the Arduino Mac app can read the serial output of the device no problem. It seems as if the device isn’t going into flash mode. I don’t know if this is an install issue or a hardware issue. I’ve tried a number of different cables. The device obviously works because I was able to connect on my old MacBook with no issue.