[SOLVED] How to use esptool

I want to program the ESP32 chip with esp-idf, but I couldn't figure out how to talk to the ESP32 from esptool.

After flashing WiFiNINAFirmwareUpdater into the SAMD21, I believe the COM port would provide a bridge to the ESP32. However, esptool times out:

sunny@sunny5 MINGW64 ~/Documents/Arduino/hardware/espressif/esp32/tools/esptool (master)
$ ./esptool.exe --port COM14 --baud 115200 chip_id
esptool.py v2.3.1
Connecting........_____....._____....._____....._____....._____....._____....._____....._____....._____....._____

A fatal error occurred: Failed to connect to Espressif device: Timed out waiting for packet header

After reading the schematics, I think I could use a separate USB-UART device to connect to MKR board's RX and TX pins. However, esptool also times out.

What's the correct way of programming the ESP32?

Juraj:
you need to upload firmware updater sketch into SAMD.

I already did that, but it doesn’t seem effective.

Hi @yoursunny,

You need to pass the reset args into esptool

--chip esp32 --port --baud 115200 --before default_reset --after hard_reset

sandeepmistry:
You need to pass the reset args into esptool

Having reset args doesn't change anything:

sunny@sunny5 MINGW64 ~/Documents/Arduino/hardware/espressif/esp32/tools/esptool (master)
$ ./esptool.exe --chip esp32 --port COM14 --baud 115200 --before default_reset --after hard_reset chip_id
esptool.py v2.3.1
Connecting........_____....._____....._____....._____....._____....._____....._____....._____....._____....._____

A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header

I also swapped the USB cable, and it doesn't help either.

he did it [Solved] WifiNINA (ESP32) firmware and source - MKRWIFI1010 - Arduino Forum

Juraj:
he did it [Solved] WifiNINA (ESP32) firmware and source - MKRWIFI1010 - Arduino Forum

Yes. :slight_smile: It worked out of the box for me. I've flashed said WiFiNINAFirmwareUpdater to the Arduino and then used the hello_world from the ESP-IDF, using "make flash". The command line is uses is as follows:

python /path/to/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /path/to/hello_world/build/bootloader/bootloader.bin 0x10000 /path/to/hello_world/build/hello_world.bin 0x8000 /path/to/hello_world/build/partitions_singleapp.bin

flipflip:
python /path/to/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /path/to/hello_world/build/bootloader/bootloader.bin 0x10000 /path/to/hello_world/build/hello_world.bin 0x8000 /path/to/hello_world/build/partitions_singleapp.bin

This seems to be Linux. I was on Windows. Today I'm trying it on a Linux machine (Raspberry Pi 3B with Ubuntu Mate 16).
esptool.py is version 2.5.1 installed from pip3.

chip_id and flash_id commands work:

sunny@pimate:~$ sudo esptool.py --chip esp32 --port /dev/ttyACM0 --baud 115200 --before default_reset --after hard_reset flash_id
esptool.py v2.5.1
Serial port /dev/ttyACM0
Connecting.....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse
MAC: 84:0d:8e:11:2b:34
Uploading stub...
Running stub...
Stub running...
Manufacturer: c2
Device: 2815
Detected flash size: 2MB
Hard resetting via RTS pin...
sunny@pimate:~$ sudo esptool.py --chip esp32 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset flash_id
esptool.py v2.5.1
Serial port /dev/ttyACM0
Connecting....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse
MAC: 84:0d:8e:11:2b:34
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Manufacturer: c2
Device: 2815
Detected flash size: 2MB
Hard resetting via RTS pin...

But read_flash command does not work. With 115200 baud rate, it complains "corrupt data":

sunny@pimate:~$ sudo esptool.py --chip esp32 --port /dev/ttyACM0 --baud 115200 --before default_reset --after hard_reset read_flash 0 0x200000 wifinina.bin
esptool.py v2.5.1
Serial port /dev/ttyACM0
Connecting......
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse
MAC: 84:0d:8e:11:2b:34
Uploading stub...
Running stub...
Stub running...

A fatal error occurred: Corrupt data, expected 0x1000 bytes but received 0xb8d bytes

With 921600 baud rate, read_flash is stuck at changing baud rate:

sunny@pimate:~$ sudo esptool.py --chip esp32 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset read_flash 0 0x200000 wifinina.bin
esptool.py v2.5.1
Serial port /dev/ttyACM0
Connecting....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse
MAC: 84:0d:8e:11:2b:34
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.

I tried the same esptool.py and USB cable with a Heltec WiFi_Kit_32 ESP32 unit (appearing as /dev/ttyUSB0 rather than /dev/ttyACM0). read_flash works with 115200 baud rate but not 921600 baud rate ("corrupt data").

read_flash doesn't work for me neither at 921600 (also stuck). 115200 works without any error or warning. I haven't tried other rates.

Can anyone share a full, uncorrupt wifinina.bin from a good unit? (I've messed up mine: [Solved] WifiNINA (ESP32) firmware and source - MKRWIFI1010 - Arduino Forum)

I got esptool working somewhat.

I modified the SAMD21 side to have this sketch that forces the ESP32 to enter bootloader and stay in bootloader:

void setup() {
  SerialUSB.begin(115200);
  SerialNina.begin(115200);
  
  pinMode(NINA_GPIO0, OUTPUT);
  pinMode(NINA_RESETN, OUTPUT);
  pinMode(LED_BUILTIN, LOW);
}

void loop() {
  static bool ready = false;
  if (!ready && millis() > 2000) {
    digitalWrite(NINA_GPIO0, LOW);
    delay(1);
    digitalWrite(NINA_RESETN, LOW);
    delay(1);
    ready = true;
    digitalWrite(LED_BUILTIN, HIGH);
  }

  while (SerialNina.available() && SerialUSB.availableForWrite()) {
    uint8_t c = SerialNina.read();
    SerialUSB.write(c);
  }

  while (SerialUSB.available() && SerialNina.availableForWrite()) {
    uint8_t c = SerialUSB.read();
    SerialNina.write(c);
  }
}

Corresponding esptool command line is: (I'm back on Windows)

./esptool.exe --chip esp32 --port COM14 --baud 115200 --before no_reset --after no_reset read_mac
./esptool.exe --chip esp32 --port COM14 --baud 115200 --before no_reset --after no_reset flash_id
./esptool.exe --chip esp32 --port COM14 --baud 115200 --before no_reset --after no_reset read_flash 0 0x200000 wififina.bin

A major limitation is that esptool can't reset the ESP32 and can't control its boot mode. To run the program on ESP32 side, you'll have to remove the program on SAMD21 side.

I wrote this for Uno WiFi Dev Ed, to access the esp over Atmega to be able to upload to esp8266 from IDE and debug it:

#include <UnoWiFiDevEdSerial1.h>

//#define FLASHING // uncomment for use with esptool and FDT
#define BAUD 115200L

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  
  Serial.begin(BAUD);

#ifdef FLASHING
  digitalWrite(LED_BUILTIN, HIGH);
  Serial1.begin(BAUD * 2); //double speed is necessary, but it disturbs frequency test of the 'download tool'
  Serial1.resetESP(true); // reset to bootloader. no need to push the B/L button while connecting to USB
#else
  digitalWrite(LED_BUILTIN, LOW);
  Serial1.begin(BAUD);
  Serial1.resetESP(); // power cycle
#endif
}

void loop() {
  while (Serial.available()) {
    detectFlashing();
    Serial1.write(Serial.read());
  }
  while (Serial1.available()) {
    Serial.write(Serial1.read());
  }
  detectFlashingEnd();
}

#ifdef FLASHING
void detectFlashing() {
  // empty
}
void detectFlashingEnd() {
  // empty
}
#else
const byte syncFrame[] = {0xC0, 0x00, 0x08, 0x24, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x07, 0x07, 0x12, 0x20};
const byte checkSumPos = 5; // esptool.py and FDT do not send the checksum for sync frame, IDE does
byte syncFrameIndex = 0;

void detectFlashing() {
  if (syncFrameIndex == sizeof(syncFrame))
    return;
  byte b = Serial.peek();
  if (!(b == syncFrame[syncFrameIndex] || (syncFrameIndex == checkSumPos && b == 0x00))) {
    syncFrameIndex = 0;
  } else {
    syncFrameIndex++;
    if (syncFrameIndex == sizeof(syncFrame)) {
      Serial1.resetESP(true); // reset to bootloader
      digitalWrite(LED_BUILTIN, HIGH);
      Serial1.begin(BAUD * 2); //double speed is necessary, but it disturbs frequency test of the 'download tool'
      Serial1.write(syncFrame, sizeof(syncFrame) - 1); // last byte was not read, only peek
    }
  }
}

void detectFlashingEnd() {
  if (syncFrameIndex < sizeof(syncFrame))
    return;
  static unsigned long lastFlashingActivity = 0;
  if (Serial.available()) {
    lastFlashingActivity = millis();
  } else if (millis() - lastFlashingActivity > 5000) { // wait so much. perhaps the tool makes the reset
    digitalWrite(LED_BUILTIN, LOW);
    Serial1.begin(BAUD);
    Serial1.resetESP(); // power cycle ESP after flashing, to avoid GPIO_STRAPPING register ESP bug
    syncFrameIndex = 0;
  }
}
#endif

The same error on my Wemos D1

esptool.exe --chip esp32 --port COM7 --baud 115200 --before no_reset --after no_reset read_mac
esptool.py v2.3.1
Connecting.....................................................

A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header

Vitalicus:
The same error on my Wemos D1

esptool.exe --chip esp32 --port COM7 --baud 115200 --before no_reset --after no_reset read_mac
esptool.py v2.3.1
Connecting.....................................................

A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header

this thread is about MKR1010 where the esp32 is accessible only over the main MCU of the board

your Wemos D1 (esp8266) problem is completely off topic here

Opening a windows CMD window I went into a folder that contained esptool.exe, there were two such folders in my M5Burner download. Entered these commands:

esptool.exe --chip esp32 --port COM14 --baud 115200 --before no_reset --after no_reset read_mac
esptool.exe --chip esp32 --port COM14 --baud 115200 --before no_reset --after no_reset flash_id
esptool.exe --chip esp32 --port COM14 --baud 115200 --before no_reset --after no_reset read_flash 0 0x200000 wififina.txt

Where wififina.txt was downloaded from [Solved] WifiNINA (ESP32) firmware and source - MKRWIFI1010 - Arduino Forum. The wififina.txt was burned onto the device as a firmware. Opening a terminal from Arduino IDE and pressing reset shows the device is connected to my wifi and the address pings.

Opening a browser window to that IP address gives a window with blanks for Username and Password. Now I google until I find out what those are supposed to be.

I changed to another usb port.
Frederic

I got this error because I had a power supply to the board and to a TTL to RS-232 converter so I could read the serial output on a tty monitor. I turned off the power supply and the convertor and board were powered via the USB port and it worked.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.