Skip to content

ESP32-S3 - Arduino framework - WIFI credentials not saved ("wrong" bootloader fixes the issue?) #867

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

Closed
Ezekiel-DA opened this issue Jul 31, 2022 · 5 comments

Comments

@Ezekiel-DA
Copy link

Ezekiel-DA commented Jul 31, 2022

Hi all,

I am trying to migrate an existing app from ESP32 to ESP32-S3.
Specifically, I am using:

  • device: ESP32-S3-DevKitC-1-N8
  • Platform.io Core 6.1.3
  • platform-espressif32 version 5.0.0 (i.e. platform = https://github.com/platformio/platform-espressif32.git); also reproducible with 4.4.0 (platform = espressif32)

The Arduino IDE (v 1.8.19) and arduino-esp32 (v2.0.3) were also used to debug this, for reasons that will be clear below.

TL;DR:

My app makes use of WifiProv for provisioning. After migrating to the ESP32-S3, provisioning through BLE "works", but seems to no longer save wifi credentials to the device, making it useless.

I was able to "fix" this by doing something that sounds like nonsense (but is what the Arduino IDE does?): a manual upload with esptool.py that uses flash_mode set to DIO but uploads the QIO bootloader. That makes no sense to me, and obviously isn't what happens when using normal Platform.io upload commands.

Investigation notes:

I have created a minimal reproduction repo here. This is basically the WifiProv example, ported to Platform.io, with a tiny change to enable BLE provisioning instead of SoftAP provisioning.

I used the Arduino IDE as a point of comparison / reference. Turns out, if I upload my code from there, everything works!

This suggests the isssue is not with my firmware but with some settings. Using the Verbose Upload command in Platform.io and Process Explorer, I captured the esptool.py commands used by the Arduino IDE and Platform.io.

Arduino IDE:

esptool.py --chip esp32s3 --port "COM4" --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB \
0x0 C:\Users\nicol\AppData\Local\Temp\arduino_build_174251/WiFiProv.ino.bootloader.bin \
0x8000 C:\Users\nicol\AppData\Local\Temp\arduino_build_174251/WiFiProv.ino.partitions.bin \
0xe000 C:\Users\nicol\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.3/tools/partitions/boot_app0.bin \
0x10000 .pio\build\ESP32-S3\firmware.bin

Platform.io:

esptool.py --chip esp32s3 --port "COM4" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 8MB \
0x0000 C:\Users\nicol\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32s3\bin\bootloader_dio_80m.bin \
0x8000 C:\Users\nicol\OneDrive\Documents\PlatformIO\Projects\provisioning_repro\.pio\build\ESP32-S3\partitions.bin \
0xe000 C:\Users\nicol\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin \
0x10000 .pio\build\ESP32-S3\firmware.bin

Based on this, I tested out several things using esptool.py manually:

  • Using the "Arduino IDE version of the command, but replacing just my own code (the path to firmware.bin at the end, obviously) with the version built with Platform.io: this works!
  • Replacing the other binaries uploaded one by one to isolate a cause: partitions.bin and boot_app0.bin have no effect, and indeed the binary files Pure Arduino and Platform.io point to are identical

That left me with the bootloader as a potential culprit. A binary diff of the "temp" bootloader the Arduino IDE uses (C:\Users\nicol\AppData\Local\Temp\arduino_build_174251/WiFiProv.ino.bootloader.bin in my case) with the files found in the Arduino IDE install (C:\Users\nicol\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.3\tools\sdk\esp32s3\bin for me) shows something very interesting: the bootloader being uploaded is bootloader_qio_80m.bin. Note: Qio, not Dio. This is not a typo on my end, despite the esptool.py command being issued with --flash_mode dio!

Indeed, armed with this, I tried a manual upload again with just files from Platform.io like this:

esptool.py --chip esp32s3 --port "COM4" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 8MB \
0x0000 C:\Users\nicol\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32s3\bin\bootloader_qio_80m.bin \
0x8000 C:\Users\nicol\OneDrive\Documents\PlatformIO\Projects\provisioning_repro\.pio\build\ESP32-S3\partitions.bin \
0xe000 C:\Users\nicol\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin \
0x10000 .pio\build\ESP32-S3\firmware.bin

This is the exact same command as the one issued natively by Platform.io, including setting --flash-mode dio, EXCEPT that the bootloader used in the QIO file.

This fixes the issue for me, but obviously a) I don't want to have to upload manually and b) this opens up a whole lot of questions like "am I doing something fundamental very wrong or is there some odd bug here?" :)

(sidenote: I tested changing --flash_mode to qio to match the bootloader: this seems to result in a boot loop on my device).

Thanks in advance for any help!

@valeros
Copy link
Member

valeros commented Aug 1, 2022

Hi @Ezekiel-DA ! I suppose you're using the esp32-s3-devkitc-1 board ID, right? In a nutshell, there are a plenty of variations of the ESP32-S3-DevKitC out there that have different flash memory configurations. First of all, I'd recommend adjusting the flash mode directly in your platformio.ini, something like this:

[env:esp32-s3-devkitc-1]
platform = espressif32
framework = arduino
board = esp32-s3-devkitc-1
board_build.flash_mode= qio

@Ezekiel-DA
Copy link
Author

Hi @valeros ! Thanks for the reply!

I am indeed using esp32-s3-devkitc-1 as the board ID in platform.io in this reproduction repo.

The board in question is actually a genuine Espressif ESP32-S3-DevKitC-1-N8 acquired from Adafruit.

After creating this issue and in attempt to automate the workaround, I did add board_build.flash_mode = qio to my configuration.

This works, but really only raises more questions!

The resulting upload command becomes the one I outlined as a workaround, i.e.: it QIO bootloader is uploaded, but esptool is still called with --flash_mode dio.

Indeed, when the ESP32-S3 boots, it still reports mode:DIO. As said above, manually calling esptool with flash_mode qio and the QIO bootloader results in a boot loop, with these traces:

ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:QIO, clock div:1
load:0x3fce3808,len:0x43c
ets_loader.c 78 

@valeros
Copy link
Member

valeros commented Aug 1, 2022

The resulting upload command becomes the one I outlined as a workaround, i.e.: it QIO bootloader is uploaded, but esptool is still called with --flash_mode dio.

That's expected, the DIO mode is mandatory for the first stage bootloader (here is the code that responsible for this transformation). After that the firmware switches to a proper flash mode on the next boot steps.

@Ezekiel-DA
Copy link
Author

Thank you for the clarification! I'll admit I'm a little out of my depth here, while the software part is in my wheelhouse, I'm not familar enough with the hardware side to understand all the details.

Given that this is an original Espressif board, should the default behavior for board = esp32-s3-devkitc-1 be changed to automatically use board_build.flash_mode= qio? As it stands, this board doesn't work out of the box with the basic WifiProv example, and I assume this behavior extends to not saving other things to flash?

@valeros valeros closed this as completed in 9400386 Aug 2, 2022
@valeros
Copy link
Member

valeros commented Aug 2, 2022

Thanks for testing, fixed in the dev branch.

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

No branches or pull requests

2 participants