Skip to content

Unable to upload to ESP32-S3 due to slow NOR flash writes #11462

Open
@KrisBigK

Description

@KrisBigK

Board

ESP32S3 Dev Module, with custom PCB

Device Description

I am using a custom setup with ESP32-S3R2 chip, 4MB NOR Flash (ZD25WQ32CEIGR from a credible Chinese supplier). The PCB is a 4-layer one manufactured by JLCPCB with 0.8mm thickness, 1oz/0.5oz copper, JLC04081H-7628 layer stackup, ±20% impedance control and ENIG surface finish. My board works with baud rates up to 3 million, based on some trial-and-error.

Hardware Configuration

ESP32-S3R2:
IO0 is connected to a push button via a schottky diode.
IO16 and IO17 are connected to an external 32K crystal.
IO19 and IO20 are connected directly to 16 pin USB type-c port, with 90Ω differential impedance.
SPICS1 is left floating.
VDD_SPI is connected to ZD25WQ32CEIGR with 1uF + 100nF decoupling capacitors, according to ESP32-S3 hardware design guidelines.
SPIHD, SPIWP, SPICS0, SPICLK, SPIQ, SPID are connected directly to ZD25WQ32CEIGR.
All other GPIOs are connected to 1.27mm pin connectors on the edge of the PCB.

Here is the PCB design and the soldered PCB, showing the connection between ESP32-S3R2 and the NOR flash.
Image

The image shows my module being attached to a larger base board, but the flash write problem already occurs with the small core board described above.
Image

Version

v3.2.0

IDE Name

Arduino IDE

Operating System

Windows 10

Flash frequency

80MHz QIO

PSRAM enabled

yes

Upload speed

921600

Description

I encountered upload issues with my PCB module, and is able to nail it down to tripping esptool's default write timeout of 3 seconds, which could be configured with the "timeout" option through esptool.cfg. (link to esptool config file documentation). The problem occurs when the compiled sketch was uploaded with compression enabled. The ZD25 flash that I'm using here apparently have relatively slow write times. As soon as it fails to return its upload percentage within 3 seconds (which happens when compression is used), esptool throws out an error.

Workarounds that I have found:
Workaround 1: disable compression by editing tools.esptool_py.upload.pattern_args in C:\Users\<my_username>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.2.0\platform.txt.
Without compression, the chip responds with a fixed time interval of ~1 second when writing, which results in a successful upload. Here is the complete pattern_args that could upload my program successfully:
tools.esptool_py.upload.pattern_args=--chip {build.mcu} --port "{serial.port}" --baud {upload.speed} {upload.flags} --before default_reset --after hard_reset write_flash --no-compress {upload.erase_cmd} --flash_mode keep --flash_freq keep --flash_size keep {build.bootloader_addr} "{build.path}/{build.project_name}.bootloader.bin" 0x8000 "{build.path}/{build.project_name}.partitions.bin" 0xe000 "{runtime.platform.path}/tools/partitions/boot_app0.bin" 0x10000 "{build.path}/{build.project_name}.bin" {upload.extra_flags}

Workaround 2: add esptool.cfg file, set timeout to 10 (seconds), and upload with CLI.
I have placed the esptool.cfg file in C:\Users\<my_username>\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.9.dev3, run powershell in the same directory with the upload command (enabling compression by default)
esptool.exe --port COM18 --baud 3000000 write_flash --flash_mode keep --flash_freq keep --flash_size keep 0x0 "C:\Users\<my_username>\AppData\Local\arduino\sketches\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin"

and the verify command

esptool.exe --port COM18 --baud 3000000 verify_flash --diff yes --flash_mode keep --flash_freq keep --flash_size detect 0x0 "esptool.exe --port COM18 --baud 3000000 verify_flash --diff yes --flash_mode keep --flash_freq keep --flash_size detect 0x0 "C:\Users\<my_username>\AppData\Local\arduino\sketches\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin"

The esptool.cfg file contents:

# esptool.cfg file to configure internal settings of esptool
[esptool]
timeout = 10

There are quite a few identical bug reports in the esptool repo (issue 842, 890, 941, 966, 967).

I have decided to make a bug report here because:

  1. esptool behaves as intended when I use CLI from powershell
  2. esptool ignores esptool.cfg when uploading from Arduino

I think the problem should be fixed here (and not in esptool) because:

  1. I don't consider the above workarounds to be intended behavior for arduino-esp32, especially considering the average user base of Arduino
  2. Uploading without compression is painstakingly slow, especially with large sketch sizes for ESP32 series. Tweaking anything with long upload times takes almost forever.

Methods that could fix the problem:

  1. add a configurable timeout option in Arduino GUI
  2. respect esptool.cfg when uploading from Arduino
  3. increase default timeout to something like 10s

Sketch

void setup() {
  // put your setup code here, to run once:
  pinMode(46, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(46, HIGH);
  delay(500);
  digitalWrite(46, LOW);
  delay(500);
}

Debug Message

Uploading with default arguments:
(The compiling logs are omitted for easier comparison)

"C:\\Users\\<my_username>\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\esptool_py\\4.9.dev3/esptool.exe" --chip esp32s3 merge_bin -o "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin" --fill-flash-size 4MB --flash_mode keep --flash_freq keep --flash_size keep 0x0 "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.bootloader.bin" 0x8000 "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.partitions.bin" 0xe000 "C:\\Users\\<my_username>\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\3.2.0/tools/partitions/boot_app0.bin" 0x10000 "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.bin"
esptool.py v4.8.1
Wrote 0x400000 bytes to file C:\Users\<my_username>\AppData\Local\arduino\sketches\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin, ready to flash to offset 0x0

"C:\\Users\\<my_username>\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\esp-x32\\2411/bin/xtensa-esp32s3-elf-size" -A "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.elf"
Sketch uses 315146 bytes (24%) of program storage space. Maximum is 1310720 bytes.
Global variables use 20696 bytes (6%) of dynamic memory, leaving 306984 bytes for local variables. Maximum is 327680 bytes.
esptool.py v4.8.1
Serial port COM18
Connecting...
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: 98:a3:16:03:6b:d8
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00004fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x0005cfff...
Compressed 20208 bytes to 13057...
Writing at 0x00000000... (100 %)
Wrote 20208 bytes (13057 compressed) at 0x00000000 in 1.6 seconds (effective 100.3 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 146...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (146 compressed) at 0x00008000 in 0.3 seconds (effective 86.9 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.7 seconds (effective 99.4 kbit/s)...
Hash of data verified.
Compressed 315296 bytes to 169255...
Writing at 0x00010000... (9 %)
Writing at 0x0001bee5... (18 %)
Writing at 0x000286c1... (27 %)
Traceback (most recent call last):
  File "esptool\__init__.py", line 1325, in _main
  File "esptool\__init__.py", line 1042, in main
  File "esptool\cmds.py", line 652, in write_flash
  File "esptool\loader.py", line 127, in inner
  File "esptool\loader.py", line 1161, in flash_defl_block
  File "esptool\loader.py", line 506, in check_command
  File "esptool\loader.py", line 475, in command
  File "esptool\loader.py", line 408, in read
StopIteration

A fatal error occurred: The chip stopped responding.
Failed uploading: uploading error: exit status 2






using --no-compression in tools.esptool_py.upload.pattern_args:

"C:\\Users\\<my_username>\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\esptool_py\\4.9.dev3/esptool.exe" --chip esp32s3 merge_bin -o "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin" --fill-flash-size 4MB --flash_mode keep --flash_freq keep --flash_size keep 0x0 "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.bootloader.bin" 0x8000 "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.partitions.bin" 0xe000 "C:\\Users\\<my_username>\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\3.2.0/tools/partitions/boot_app0.bin" 0x10000 "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.bin"
esptool.py v4.8.1
Wrote 0x400000 bytes to file C:\Users\<my_username>\AppData\Local\arduino\sketches\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin, ready to flash to offset 0x0

"C:\\Users\\<my_username>\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\esp-x32\\2411/bin/xtensa-esp32s3-elf-size" -A "C:\\Users\\<my_username>\\AppData\\Local\\arduino\\sketches\\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.elf"
Sketch uses 323270 bytes (24%) of program storage space. Maximum is 1310720 bytes.
Global variables use 20800 bytes (6%) of dynamic memory, leaving 306880 bytes for local variables. Maximum is 327680 bytes.
esptool.py v4.8.1
Serial port COM18
Connecting...
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: 98:a3:16:03:6b:d8
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00004fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x0005efff...
Writing at 0x00000000... (50 %)
Writing at 0x00004000... (100 %)
Wrote 32768 bytes at 0x00000000 in 1.6 seconds (161.9 kbit/s)...
Hash of data verified.
Writing at 0x00008000... (100 %)
Wrote 16384 bytes at 0x00008000 in 0.4 seconds (372.4 kbit/s)...
Hash of data verified.
Writing at 0x0000e000... (100 %)
Wrote 16384 bytes at 0x0000e000 in 0.7 seconds (178.7 kbit/s)...
Hash of data verified.
Writing at 0x00010000... (5 %)
Writing at 0x00014000... (10 %)
Writing at 0x00018000... (15 %)
Writing at 0x0001c000... (20 %)
Writing at 0x00020000... (25 %)
Writing at 0x00024000... (30 %)
Writing at 0x00028000... (35 %)
Writing at 0x0002c000... (40 %)
Writing at 0x00030000... (45 %)
Writing at 0x00034000... (50 %)
Writing at 0x00038000... (55 %)
Writing at 0x0003c000... (60 %)
Writing at 0x00040000... (65 %)
Writing at 0x00044000... (70 %)
Writing at 0x00048000... (75 %)
Writing at 0x0004c000... (80 %)
Writing at 0x00050000... (85 %)
Writing at 0x00054000... (90 %)
Writing at 0x00058000... (95 %)
Writing at 0x0005c000... (100 %)
Wrote 327680 bytes at 0x00010000 in 23.4 seconds (111.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting with RTC WDT...

A serial exception error occurred: Cannot configure port, something went wrong. Original message: OSError(22, 'A device which does not exist was specified.', None, 433)
Note: This error originates from pySerial. It is likely not a problem with esptool, but with the hardware connection or drivers.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
Failed uploading: uploading error: exit status 1

(The program already started to run in spite of showing an error at the end)






Uploading with CLI from PowerShell: 

PS C:\Users\<my_username>\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.9.dev3> esptool.exe --port COM18 --baud 3000000 write_flash --flash_mode keep --flash_freq keep --flash_size keep 0x0 "C:\Users\<my_username>\AppData\Local\arduino\sketches\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin"
esptool.py v4.7.0
Loaded custom configuration from C:\Users\<my_username>\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.9.dev3\esptool.cfg
Serial port COM18
Connecting...
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: 98:a3:16:03:6b:d8
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 3000000
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x003fffff...
Compressed 4194304 bytes to 187268...
Writing at 0x0005baa2... (100 %)

(After writing reaches 100%, I closed the PowerShell window, power cycle the MCU, and the application would run normally)





Program verification from PowerShell: 

PS C:\Users\<my_username>\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.9.dev3> esptool.exe --port COM18 --baud 3000000 verify_flash --diff yes --flash_mode keep --flash_freq keep --flash_size detect 0x0 "C:\Users\<my_username>\AppData\Local\arduino\sketches\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin"
esptool.py v4.7.0
Loaded custom configuration from C:\Users\<my_username>\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.9.dev3\esptool.cfg
Serial port COM18
Connecting...
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
MAC: 98:a3:16:03:6b:d8
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 3000000
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Verifying 0x400000 (4194304) bytes @ 0x00000000 in flash against C:\Users\<my_username>\AppData\Local\arduino\sketches\D31E780FCDA6DCDBBE25058AA1303624/LED_Blink.ino.merged.bin...
-- verify OK (digest matched)
Hard resetting via RTS pin...
PS C:\Users\<my_username>\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.9.dev3>

Other Steps to Reproduce

I have tested 2 ZD25WQ32CEIGR chips from the same tape & reel, both exhibited identical write speeds. With compression and longer timeout, the actual longest interval between 2 flash write responses is around 5 seconds. Therefore, increasing the timeout to 10 seconds would at least fix my problem.

Reproduction of the problem would require a slow flash IC & custom PCB, or decreasing flash write timeout value in esptool configuration file. However, Arduino-esp32 apparently ignores esptool configuration file.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions