Upload creates crazy GPIO-values + constant reboots (builds fine)

My firmware and littleFS file system build and upload just fine to a esp32-s3 devkitc N16R8.
But after that my S3 goes into constant reboot and shows crazy GPIO assignments which don’t exist in my code:

rst:0x8 (TG1WDT_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x4037971c
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x44c
load:0x403c9700,len:0xbe4
load:0x403cc700,len:0x2a38
entry 0x403c98d4
E (23) gpio: gpio_set_direction(274): GPIO number error
E (24) gpio: gpio_set_direction(274): GPIO number error
E (24) gpio: gpio_pullup_en(71): GPIO number error
E (27) gpio: gpio_pullup_en(71): GPIO number error
E (31) pcnt: _pcnt_unit_config(358): PCNT pulse input io error
E (37) pcnt: _pcnt_unit_config(358): PCNT pulse input io error
[   292][E][esp32-hal-gpio.c:102] __pinMode(): Invalid pin selected
E (48) gpio: gpio_set_level(226): GPIO output gpio_num error
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021

My Project is at GitHub - NoLackOfIdeas/CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow.
I only have these problems with src\esp3: CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/src/esp3 at main · NoLackOfIdeas/CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow · GitHub.

I just don’t know where to look for the culprit anymore. Any hints would be much appreciated!

Multiple sources say this can happen when you try to access pin “-1”, which in some libraries means “pin undefined”, but they still try to use it.

For example, with the LovyanGFX library

and you also set a pin to -1 here

Not saying that that’s the culprit, but “something” in either your code or a library seems to try to use either pin -1 or another invalid pin number in pinMode.

The good message is that the ESP32S3 has a built in USB-JTAG controller. So, if your development board’s USB port is directly connected to the ESP32S3, then you can actually start up the debugger in the VSCode Debug sidebar and press “Play” for the PIO Debug configuration. The default debug_tool for the board should already be esp-builtin.

https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-guides/jtag-debugging/configure-builtin-jtag.html

There’s also a guide here:

https://community.platformio.org/t/how-to-use-jtag-built-in-debugger-of-the-esp32-s3-in-platformio/36042

What this will allow you to do is set a breakpoint in the __pinMode which throws that error message

by e.g. saying

debug_init_break = break esp32-hal-gpio.c:102

so that after the debugger starts, it keeps running until it hits that breakpoint in that line, which is where the error message is printed. The call stack in the debugger sidebar will then show you how execution has reached that location, immediately identifying the calling function and library, from which you can identify what’s wrong.

Thanks so much maxgerhardt!

I commented out “cfg.pin_busy = -1;” but it didn’t change anything.

Meanwhile - for testing purposes - I have deactivated all encoder-peripherals and their use of GPIOs and those error messages disappeared…
…BUT: it still reboots and the monitor shows:

abort() was called at PC 0x40379297 on core 1


Backtrace: 0x40377b82:0x3fcca360 0x4037d641:0x3fcca380 
0x40384111:0x3fcca3a0 0x40379297:0x3fcca420 0x403793a9:0x3fcca450 
0x40379478:0x3fcca470 0x420b36f2:0x3fcca4a0 0x420b6719:0x3fcca7b0 
0x420c8765:0x3fcca7e0 0x4206d61a:0x3fcca810 0x4206d6af:0x3fcca840 
0x42046691:0x3fcca8c0 0x42033f0d:0x3fcca8f0 0x42033f9e:0x3fcca920 
0x42006ac6:0x3fcca940 0x42006b5b:0x3fcca960 0x420187bc:0x3fcca990 
0x42018f41:0x3fcca9e0 0x4201bce5:0x3fccaa00 0x4200702b:0x3fccaa30

Maybe, the underlying problems are still the GPIOs.

The output of xtensa-esp32s3-elf-addr2line.exe reads:
0x4037d641: esp_system_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c:137
0x40384111: abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/abort.c:46
0x40379297: lock_acquire_generic at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/locks.c:139
0x403793a9: _lock_acquire_recursive at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/locks.c:167
0x40379478: __retarget_lock_acquire_recursive at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/locks.c:323 (discriminator 3)
0x420b4232: phy_i2c_init2 at ??:?
0x420b7259: __cxxabiv1::__si_class_type_info::__do_dyncast(int, __cxxabiv1::__class_type_info::__sub_kind, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__dyncast_result&) const at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32s3-elf/src/gcc/libstdc++-v3/libsupc++/si_class_type_info.cc:59
0x420c92d5: __ssvfiscanf_r at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32s3-elf/src/newlib/newlib/libc/stdio/vfscanf.c:649 (discriminator 1)
0x4206d9d6: tcp_create_segment at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/core/tcp_out.c:168 (discriminator 2)
0x4206da6b: tcp_create_segment at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/core/tcp_out.c:201
0x42046a4d: AsyncWebSocketResponse::_respond(AsyncWebServerRequest*) at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/libdeps/esp3/ESPAsyncWebServer/src/AsyncWebSocket.cpp:1223
 (inlined by) AsyncWebSocketResponse::_respond(AsyncWebServerRequest*) at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/libdeps/esp3/ESPAsyncWebServer/src/AsyncWebSocket.cpp:1221
0x420341d9: lv_bin_decoder_info at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/libdeps/esp3/lvgl/src/libs/bin_decoder/lv_bin_decoder.c:123
0x4203426a: fs_read_file_at at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/libdeps/esp3/lvgl/src/libs/bin_decoder/lv_bin_decoder.c:1088
0x42006b46: setup() at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/src/esp3/main_esp3.cpp:134
 (inlined by) setup() at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/src/esp3/main_esp3.cpp:72
0x42006bff: setup() at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/src/esp3/main_esp3.cpp:168
 (inlined by) setup() at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/src/esp3/main_esp3.cpp:74
0x42018a88: get_glyph_dsc_id at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/libdeps/esp3/lvgl/src/font/lv_font_fmt_txt.c:299
0x4201920d: indev_proc_short_click at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/libdeps/esp3/lvgl/src/indev/lv_indev.c:1542
0x4201bfb1: lv_color_over32 at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/libdeps/esp3/lvgl/src/misc/lv_color_op.c:109
0x42007273: ArduinoJson::V704PB2::detail::parseNumber(char const*, ArduinoJson::V704PB2::detail::VariantData&) at C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/libdeps/esp3/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp:101
0x42045615: WiFiGenericClass::mode(wifi_mode_t) at C:/Users/Maasen.KHV-NB-MZ37/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiGeneric.cpp:701
 (inlined by) espWiFiStop at C:/Users/Maasen.KHV-NB-MZ37/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiGeneric.cpp:735
 (inlined by) WiFiGenericClass::mode(wifi_mode_t) at C:/Users/Maasen.KHV-NB-MZ37/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiGeneric.cpp:1153

I just updated my repo with all my changes.

I’ll have to research the debug thing. As I said: I’m a noob, I do all this with AI as an excercise and because it’s fun…
…sometimes
…not right now, actually,

I know I say it again and again, but: thanks!! Again!

The crash looks worse than before. Also, removing cfg.pin_busy = -1; leaves that variable uninitialized, meaning it has an unpredictable value. That might be even worse.

Try to use the debugger as described to get the offending call to pinMode. Things will become much clearer then.

Hmmm…in other working configs I saw this parameter was simply ommitted. I guess, debugging is the most promising route.
I will read a bit and if I’m lucky I’ll understand enough to setup the debugging. Somehow I think, it will turn out to be something very simple and maybe even unexpected.
I checked the GPIOs so often already…
But I’ve been going in circles for so long now. It’s time for a more structured approach.

I am a bit at a loss here…

I installed and setup the integrated debugger according to the How-To.

Screenshot 2025-08-16 114450

In my platformio.ini:

[env:esp3]
platform = espressif32@~6.1.0
framework = arduino
board = esp32-s3-devkitc-1
upload_speed = 2000000     ;ESP32S3 USB-Serial Converter maximum 2000000bps
upload_port = COM5
monitor_speed = 115200
monitor_port = COM4
debug_tool = esp-builtin
debug_init_break = break setup
build_type = debug      ;build in debug mode instead of release mode
lib_ldf_mode = deep+

When I click “debug” (“play”) I get:

lauch.json shows:
// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY
//
// PlatformIO Debugging Solution
//
// Documentation: https://docs.platformio.org/en/latest/plus/debugging.html
// Configuration: https://docs.platformio.org/en/latest/projectconf/sections/env/options/debug/index.html

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "platformio-debug",
            "request": "launch",
            "name": "PIO Debug",
            "executable": "C:/Pio_projects/CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/build/esp3/firmware.elf",
            "projectEnvName": "esp3",
            "toolchainBinDir": "C:/Users/Maasen.KHV-NB-MZ37/.platformio/packages/toolchain-xtensa-esp32s3/bin",
            "internalConsoleOptions": "openOnSessionStart",
            "preLaunchTask": {
                "type": "PlatformIO",
                "task": "Pre-Debug"
            }
        },
        {
            "type": "platformio-debug",
            "request": "launch",
            "name": "PIO Debug (skip Pre-Debug)",
            "executable": "C:/Pio_projects/CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/build/esp3/firmware.elf",
            "projectEnvName": "esp3",
            "toolchainBinDir": "C:/Users/Maasen.KHV-NB-MZ37/.platformio/packages/toolchain-xtensa-esp32s3/bin",
            "internalConsoleOptions": "openOnSessionStart"
        },
        {
            "type": "platformio-debug",
            "request": "launch",
            "name": "PIO Debug (without uploading)",
            "executable": "C:/Pio_projects/CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow/.pio/build/esp3/firmware.elf",
            "projectEnvName": "esp3",
            "toolchainBinDir": "C:/Users/Maasen.KHV-NB-MZ37/.platformio/packages/toolchain-xtensa-esp32s3/bin",
            "internalConsoleOptions": "openOnSessionStart",
            "loadMode": "manual"
        }
    ]
}
Debug Console shows:
undefinedC:\Users\Maasen.KHV-NB-MZ37\.platformio\packages\toolchain-xtensa-esp32s3\bin\xtensa-esp32s3-elf-gdb.exe: warning: Couldn't determine a path for the index cache directory.

Reading symbols from C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow\.pio\build\esp3\firmware.elf...
PlatformIO Unified Debugger -> https://bit.ly/pio-debug
PlatformIO: debug_tool = esp-builtin
PlatformIO: Initializing remote target...
Open On-Chip Debugger  v0.11.0-esp32-20220706 (2022-07-06-15:48)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Info : esp_usb_jtag: VID set to 0x303a and PID to 0x1001
Info : esp_usb_jtag: capabilities descriptor set to 0x2000
adapter speed: 40000 kHz

Warn : Transport "jtag" was already selected
adapter speed: 5000 kHz

Info : tcl server disabled
Info : telnet server disabled
Error: libusb_open() failed with LIBUSB_ERROR_NOT_FOUND
Error: esp_usb_jtag: could not find or open device!

.pioinit:11: Error in sourced command file:
Remote communication error.  Target disconnected.: Success.

This usually means that WinUSB or LibUSB aren’t installed for the USB JTAG interface and thus OpenOCD couldn’t access it. Can you try both WinUSB and LibUSB for this section?

Still in ZADIG, select “USB Jtag/serial debug unit (interface 2)”, change the current driver to “WinUSB” and install by clicking the “Update Driver” button in Zadig.

Thanks - again…

Just to be on the safe side: I connect the left (=USB) port and with this one connection I install both drivers for “USB Jtag/serial debug unit (interface 1[and 2])”.
Meaning: I do not switch ports on the S3 in between driver up-/downgrades, correct?

I chose libUSB for interface 2, driver installed successfully.

→ I did a clean and then “run and debug”. Same error in debug console as before.

Update:
I re-checked Zadoc and made sure, inerface 0 had the WinUSB driver installed. I’m not sure, if this was the case before.

Questions:
Do I always have to do a clean and build before I try to run debug?
Do I always need to use debug with pre-debug?

Very weird. The device list looks good. And I guess it’s the same when using WinUSB?

Can you try this procedure?

  1. Press the “Upload” button and see that it uploads correctly
  2. Check that you still have the “USB JTAG/serial debug unit” device in your device manager present. If not, reboot the board into bootloader mode (BOOT button held, EN button pressed and released, BOOT button released)
  3. In the debug sidebar, switch from using the “PIO Debug” to “PIO Debug (without uploading)” (since the program is already uploaded) and start it. Does that connect?

Upload works after rebooting the board into bootloader mode.
The same output after debug without uploading.

I installed WinUSB on interface 2 in Zadoc to test. But after successfull installation Zadog still shows this (see “Driver:”):

and device manager shows no com 5:

Update:
I even de-installed the libusb-win32 device and installed WinUSB again on interface 2 using a different cable and port. After resetting and putting the S3 into bottloader mode: still the same in Zadic and in device manager…

I’m going to give this a try…

same erros:
Error: libusb_open() failed with LIBUSB_ERROR_ACCESS
Error: esp_usb_jtag: could not find or open device!

I don’t understand, why I cannot revert to WinUSB in Zadic and why COM 5 for interface 2 doesn’t show up in my device manager anymore…

In the Windows device manager, you can use “View → Device by Container” to get a grouping of all USB interfaces that the ESP32-S3 provides. You can rightclick and uninstall (with the “remove device driver” ticked) on any interface and plug the device out and back in, to get back to default drivers.

Thanks (for XXX-th time)!
I closed Zadig and opened it again and re-did the whole driver install-procedure.
I used WinUSB for interface 2, again.
Device manager shows both Com-ports again.
Debug works.
Have to start understanding how to use it now and hunt down the problems…see in a year from now I guess. :wink:

See if you can directly use that to make the initial breakpoint in the problematic __pinMode function. (You can also set breakpoints manually by clicking on the line number of an opened file).

If you manage to set the breakpoint per above where it hits the “Invalid pin selected” print statement, then you can post a screenshot of the “Call Stack” in the left debug sidebar, and it should point to the problem as you walk up the call stack (you can click on any function in the call stack to see the “history” of how execution got there).

I think

also teaches some of the basics on how to use the debugger (breakpoints, watches, call stack, GDB commands, …)

Intermediate state:

  • I triple-checked the GPIOs used in setup and changed them all to a safe config (19 and 20 are also NOT used, because they’re used by UART-debugging).
  • added several debug-prints
  • Debugging: it keeps hanging in an endless loop and I cannot pause or stop it. Will keep trying

But there seems to be “some” progress (I hope, it is):
Serial monitor shows:

rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x420f6eca
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x44c
load:0x403c9700,len:0xbe4
load:0x403cc700,len:0x2a38
entry 0x403c98d4

--- ESP3 Pendant Booting ---
PSRAM size: 8386295 bytes
Free PSRAM: 8386295 bytes
Loaded default pendant configuration.
✅ Preferences.begin succeeded for namespace 'pendant'.
✅ Preferences.begin succeeded for namespace 'pendant'.
INFO: Loaded web config from NVS.
✅ Preferences.begin succeeded for namespace 'encoder'.

--- PIN MAP DUMP ---
Rows:   17 18
Cols:   3 21
LEDs:
FEED A      -> GPIO 14
FEED B      -> GPIO 13

--------------------------------

Heap summary for capabilities 0x00000400:
  At 0x3d800000 len 8388607 free 8293867 allocated 92332 min_free 8293867
    largest_free_block 8257524 alloc_blocks 6 free_blocks 1 total_blocks 7
  Totals:
    free 8293867 allocated 92332 min_free 8293867 largest_free_block 8257524
Heap summary for capabilities 0x00000004:
  At 0x3fcef958 len 1620 free 0 allocated 1148 min_free 0
    largest_free_block 0 alloc_blocks 10 free_blocks 0 total_blocks 10
  At 0x3d800000 len 8388607 free 8293867 allocated 92332 min_free 8293867
    largest_free_block 8257524 alloc_blocks 6 free_blocks 1 total_blocks 7
  At 0x3fcc1ba8 len 162664 free 161496 allocated 168 min_free 161496
    largest_free_block 155636 alloc_blocks 3 free_blocks 1 total_blocks 4
  At 0x3fce9710 len 22308 free 7744 allocated 12984 min_free 6112
    largest_free_block 7668 alloc_blocks 52 free_blocks 1 total_blocks 53
  At 0x3fcf0000 len 32768 free 17228 allocated 13848 min_free 12100
    largest_free_block 11764 alloc_blocks 59 free_blocks 4 total_blocks 63
  At 0x600fe000 len 8176 free 7784 allocated 0 min_free 7784
    largest_free_block 7668 alloc_blocks 0 free_blocks 1 total_blocks 1
  Totals:
    free 8488119 allocated 120480 min_free 8481359 largest_free_block 8257524
DEBUG: LVGL initialization complete
DEBUG: Starting WiFi setup...
DEBUG: WiFi mode set to STA
DEBUG: WiFi.begin() called
Connecting to Wi-FiDEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.DEBUG: In WiFi delay loop
.
WARN: Wi-Fi failed to connect.
--- Setup Complete ---
DEBUG: loopTask starting - LVGL ready

abort() was called at PC 0x4037930b on core 1


Backtrace: 0x40377bf6:0x3fcca480 0x4037d6c9:0x3fcca4a0 0x40384199:0x3fcca4c0 0x4037930b:0x3fcca540 0x4037941d:0x3fcca570 0x403794ec:0x3fcca590 0x420e4422:0x3fcca5c0 0x420e7449:0x3fcca8d0 0x420faef9:0x3fcca900 0x4209e35e:0x3fcca930 0x4209e3f3:0x3fcca960 0x42074ada:0x3fcca9e0 0x4205ff81:0x3fccaa10 0x42060052:0x3fccaa40 0x42007e42:0x3fccaa60 0x42007e97:0x3fccaa80 0x42026b7e:0x3fccaab0 0x4202803e:0x3fccaad0 0x420280b1:0x3fccab40 0x4202c45d:0x3fccab60 0x4202c4fd:0x3fccab80 0x420088b3:0x3fccaba0




ELF file SHA256: 63b009344f2f38d2

Also:

xtensa-esp32s3-elf-addr2line -pfiaC -e C:\Pio_projects\CNCpanel-LinuxCNC-Ethercat-ESP32-ESPnow\.pio\build\esp3\firmware.elf 0x4037930b
0x4037930b: lock_acquire_generic at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/locks.c:139

Install the filter in the monitor that will decode the entire crash for you. Reference: pio device monitor — PlatformIO v6.1 documentation if you’re using platformio monitor. There’s a similar one for idf.py monitor if ou’re using that.

Then you can see the entire call tree where you’ll surely find something called something that tried to grab a lock at an inopportune time. Maybe you did something crazy like tried to write to a serial console while in an interrupt handler. (The serial console might need interrupts itself…) That would have stood out if you saw the entire trace.

https://esp32.com/viewtopic.php?t=30417

This isn’t a platformio issue as much as a generic programming question.