Esp32 with esp-idf framework running into a boot loop

While testing the ESPHome Bluetooth Proxy component I am running into a boot loop problem with an ESP32.
This is a LilyGO TTGO T7 Mini32 V1.3 board.
The ESPHome Bluetooth Proxy page states that: “The ESP32 Platform component should be configured to use the esp-idf framework, as the arduino framework uses significantly more memory and performs poorly with the Bluetooth proxy enabled.”

Originally I did use the Arduino framework, and this does work, but I am now trying to convert to the esp-idf framework and this fails.
The only difference between the two configurations is:

esp-idf framework:

esp32:
  board: ttgo-t7-v13-mini32
  framework:
    # type: arduino
    type: esp-idf

# captive_portal:

Arduino framework:

esp32:
  board: ttgo-t7-v13-mini32
  framework:
    type: arduino
    # type: esp-idf

captive_portal:

For the rest there is nothing connected to any pins, I and there are only some basic internal sensors defined in the configuration.

Flashing through the USB serial connection appears to finish normally, but right after this the ESP goes into a boot loop with the following serial log:

Wrote 0x136a50 bytes to file /data/t7v13-02/.pioenvs/t7v13-02/firmware-factory.bin, ready to flash to offset 0x0
======================== [SUCCESS] Took 1174.08 seconds ========================
INFO Successfully compiled program.
esptool.py v4.5.1
Serial port /dev/ttyUSB1
Connecting…
Chip is ESP32-D0WDQ6-V3 (revision v3.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 08:3a:f2:47:0b:d0
Uploading stub…
Running stub…
Stub running…
Changing baud rate to 460800
Changed.
Configuring flash size…
Auto-detected Flash size: 4MB
Flash will be erased from 0x00010000 to 0x00136fff…
Flash will be erased from 0x00001000 to 0x00007fff…
Flash will be erased from 0x00008000 to 0x00008fff…
Flash will be erased from 0x00009000 to 0x0000afff…
Compressed 1206864 bytes to 774701…
Wrote 1206864 bytes (774701 compressed) at 0x00010000 in 18.2 seconds (effective 531.6 kbit/s)…
Hash of data verified.
Compressed 25504 bytes to 15998…
Wrote 25504 bytes (15998 compressed) at 0x00001000 in 0.7 seconds (effective 294.8 kbit/s)…
Hash of data verified.
Compressed 3072 bytes to 134…
Wrote 3072 bytes (134 compressed) at 0x00008000 in 0.1 seconds (effective 350.6 kbit/s)…
Hash of data verified.
Compressed 8192 bytes to 31…
Wrote 8192 bytes (31 compressed) at 0x00009000 in 0.1 seconds (effective 487.2 kbit/s)…
Hash of data verified.

Leaving…
Hard resetting via RTS pin…
INFO Successfully uploaded program.
INFO Starting log output from /dev/ttyUSB1 with baud rate 115200
[12:08:37]\x80 \x80 \x80 \x80\xf8\x80\x80 \x80 \x80 \x80 @ \x82\xbd́00030000
[12:08:37]1150 mmu set 00040000, pos 00040000
[12:08:37]1150 mmu set 00050000, pos 00050000
[12:08:37]1150 mmu set 00060000, pos 00060000
[12:08:37]1150 mmu set 00070000, pos 00070000
[12:08:37]1150 mmu set 00080000, pos 00080000
[12:08:37]1150 mmu set 00090000, pos 00090000
[12:08:37]1150 mmu set 000a0000, pos 000a0000
[12:08:37]1150 mmu set 000b0000, pos 000b0000
[12:08:37]1150 mmu set 000c0000, pos 000c0000
[12:08:37]1150 mmu set 000d0000, pos 000d0000
[12:08:37]1150 mmu set 000e0000, pos 000e0000
[12:08:37]1150 mmu set 000f0000, pos 000f0000
[12:08:37]1150 mmu set 00100000, pos 00100000
[12:08:37]1150 mmu set 00110000, pos 00110000
[12:08:37]1150 mmu set 00120000, pos 00120000
[12:08:37]1150 mmu set 00130000, pos 00130000
[12:08:37]1150 mmu set 00140000, pos 00140000
[12:08:37]1150 mmu set 00150000, pos 00150000
[12:08:37]1150 mmu set 00160000, pos 00160000
[12:08:37]1150 mmu set 00170000, pos 00170000
[12:08:37]ets Jul 29 2019 12:21:46
[12:08:37]
[12:08:37]rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
[12:08:37]configsip: 0, SPIWP:0xee
[12:08:37]clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
[12:08:37]mode:QIO, clock div:1
[12:08:37]load:0x3fff0030,len:6660
[12:08:37]load:0x3df03df0,len:-1400336
[12:08:37]1150 mmu set 00010000, pos 00010000
[12:08:37]1150 mmu set 00020000, pos 00020000
[12:08:37]1150 mmu set 00030000, pos 00030000
[12:08:37]1150 mmu set 00040000, pos 00040000
[12:08:37]1150 mmu set 00050000, pos 00050000
[12:08:37]1150 mmu set 00060000, pos 00060000
[12:08:37]1150 mmu set 00070000, pos 00070000
[12:08:37]1150 mmu set 00080000, pos 00080000
[12:08:37]1150 mmu set 00090000, pos 00090000
[12:08:37]1150 mmu set 000a0000, pos 000a0000
[12:08:37]1150 mmu set 000b0000, pos 000b0000
[12:08:37]1150 mmu set 000c0000, pos 000c0000
[12:08:37]1150 mmu set 000d0000, pos 000d0000
[12:08:37]1150 mmu set 000e0000, pos 000e0000
[12:08:37]1150 mmu set 000f0000, pos 000f0000
[12:08:37]1150 mmu set 00100000, pos 00100000
[12:08:37]1150 mmu set 00110000, pos 00110000
[12:08:37]1150 mmu set 00120000, pos 00120000
[12:08:38]1150 mmu set 00130000, pos 00130000
[12:08:38]1150 mmu set 00140000, pos 00140000
[12:08:38]1150 mmu set 00150000, pos 00150000
[12:08:38]1150 mmu set 00160000, pos 00160000
[12:08:38]1150 mmu set 00170000, pos 00170000
[12:08:38]ets Jul 29 2019 12:21:46
[12:08:38]

Converting back to the Arduino framework gives a working unit again.

Doing a “Clean Build Files” between the conversion does not help either.
Does somebody have an idea what could be causing this problem and how to flash this ESP32 with the esp-idf framework?

Did you manage to solve this? I encountered this error too, and somehow managed to fix it by manually flashing it using another tool (I don’t remember which) on one of my boards, but haven’t managed to reproduce the fix on another (both are LilyGO TTGO T7 Mini32 boards like yours)

No, unfortunately not.
Could it be that you did use the ESPHome Flasher tool?

I did some more trials, and finally got some success.
For the record: this is what I did:

  1. Flashing the device from the ESPHome Dashboard via the USB serial connection with a basic configuration (all additional internal sensors removed) and the arduino framework → this was successful
  2. Flashing the device from the ESPHome Dashboard via the USB serial connection with a basic configuration and the esp-idf framework and captive_portal disabled → flashing finished as normal, but the device went into a boot loop again
  3. Flashing the device manually via the USB serial connection using the ESPHome Flasher tool with a basic configuration and the esp-idf framework → flashing finished as normal, but the device went into a boot loop again
  4. Changing the board type from ttgo-t7-v13-mini32 into esp32dev, than flashing the device from the ESPHome Dashboard via the USB serial connection with a basic configuration and the esp-idf framework → flashing finished as normal, and the device came to live as a BLE tracker and Bluetooth Proxy
  5. Flashing the device from the ESPHome Dashboard via WiFi with still the board type as esp32dev and esp-idf as framework, and with the previously under the Arduino framework existing internal sensors added again → I got a compilation error
  6. Doing a “Clean build files” and repeating the previous step → success: the device came back online with the BLE tracker and Bluetooth Proxy and all internal sensors enabled as well

So in the end it looks like the board type ttgo-t7-v13-mini32 (as specified on the PlatformIO website) is incompatible with the esp-idf framework when using ESPHome?

Has anybody been able to successfully flash a LilyGO TTGO T7 Mini32 V1.3 board in ESPHome with the esp-idf framework while using ttgo-t7-v13-mini32 as the board type?

Can you file a bug on Platform IO (?) with that information? I’m assuming they can fix it pretty easily.

I could do that, but is it sure that this problem is (was?) caused by PlatformIO and not by ESPHome?

Anyhow, this morning there was an update for ESPHome: version 2023.5.0 and after installing this update and re-flashing the LilyGO TTGO T7 Mini32 V1.3 board via WiFi with the same yaml configuration but with ttgo-t7-v13-mini32 as board type it finished successfully without a boot loop.
So in the end I am now successfully running ESPHome on a LilyGO TTGO T7 Mini32 V1.3 board with the esp-idf framework and with ttgo-t7-v13-mini32 as board type.

I cannot find anything in the ESPHome changelog about solving this issue, but does this mean that the problem was indeed caused by ESPHome and solved with this new version?
Does someone have more information about this?

Afaik, the issue only happens when the bootloader changes which only happens when flashing via USB (I think).

Thanks.
I think you are correct, because after re-flashing the device with the exact same yaml configuration through the USB serial connection it went into a boot loop again, and after again flashing the device through the USB serial connection with esp32dev as board type it came back online again.

So does this indeed mean that this, being a bootloader issue, is a PlatformIO problem?
Or could it also still be an ESPHome problem?

And can we conclude that a workaround for the issue is to first flash through USB serial with esp32dev as board type, and then re-flash via WiFi with ttgo-t7-v13-mini32 as board type?
And I am also not sure whether using either esp32dev or ttgo-t7-v13-mini32 as board type makes a difference anyhow?

I think those are worthwhile questions to ask on the PlatformIO bug report.

I think it is a PlatformIO bug, but I am not completely sure. Maybe try to flash a simple PlatformIO program and see if you get a boot loop?

But yes, that is a workaround for now.

I’m using a Lilygo T7mini32v1.5 (with a PMS5003T FWIW)
Since I change the board as below its picked up the PINs, UART etc I have connected the PMS too

esp32:
board: wemos_d1_mini32
framework:
type: arduino

I was able to successfully flash a LilyGO TTGO T7 Mini32 V1.3 board first over serial and then OTA with one tweak.

esphome:
  # extra config options
  platformio_options:
    # ttgo-t7-v13-mini32 board config tries qio when UART flashing
    # which goes into a boot loop
    # https://github.com/platformio/platform-espressif32/blob/b0a7f56bcde9fa332b40111b1423482d8f7cbc77/boards/ttgo-t7-v13-mini32.json
    board_build.flash_mode: dio

esp32:
  board: ttgo-t7-v13-mini32

When flashing using board: esp32dev over UART (aka USB) the flash mode is set as dio. However, when serial flashing board: ttgo-t7-v13-mini32, the flash mode is set to qio. I’m guessing the flash mode is only changed when serial flashing, so that’s why first flashing board: esp32dev over USB followed by board: ttgo-t7-v13-mini32 over the air worked.

The flash mode qio is a problem because many ESP32 boards don’t support this mode. I haven’t figured out exactly why this particular board doesn’t like qio flashing, but Espressif has some possibilities: SPI Flash Modes - ESP32 - — esptool.py latest documentation

3 Likes

Sorry i’m late :joy: stumbled upon this when looking why we can’t have two i2c buses with idf (any help welcome, lilygo t-higrow wont work, don’t want to go back to arduino) …

substitutions:
  friendly_name: 'T7 1.3'
  node_name: 't7'
  device_name: 't7'
  device_description: 'TP4054(IC)@JST1.25 BAT' #  32 BLE 4.2 / BLE
  project_base: 'LILYGO® TTGO'
  project_name: 'T7 Mini 32'
  project_version: '1.3'
# PINS
    # https://raw.githubusercontent.com/LilyGO/TTGO-T7-Demo/master/images/T7V1.3.jpg
    # https://github.com/LilyGO/TTGO-T7-Demo/blob/ef0f6b1589f7aec405114c6bda6b5a734d38150b/t7_v1.3.pdf
  pin_status_led: '22' # 19 - https://github.com/LilyGO/TTGO-T7-Demo/issues/12  # GREEN #'22' - weird both toggle green
  pin_adc_voltage: '35'  # '36'  # '35' #'34' ?? 
  pin_boot_switch: '0'
# native
  i2c_sda: '21' # wire_sda
  i2c_scl: '22' # wire_scl
  serial_tx: '1' # TX0
  serial_rx: '3' # RX0

esphome:
  name: $node_name
  friendly_name: ${friendly_name}
  comment: $device_description
  project:
    name: ${project_base}.${project_name}
    version: $project_version
  platformio_options:
    board_build.extra_flags:
      - "-Wno-error"
      - "-DARDUINO_TTGO_T7_V13_Mini32"
      - "-DURL=\\\"https://www.lilygo.cc/products/t7-v1-3-mini-32-esp32\\\""
      - "-DVENDOR=\\\"LILYGO®\\\""
      - "-DUSB_MANUFACTURER_STRING=\\\"T7Mini32\\\""
      - "-DUSB_PRODUCT_STRING=\\\"v1.3\\\""

esp32:
  board: ttgo-t7-v13-mini32
  framework: 
    type: esp-idf
    version: 5.3.1
    platform_version: 6.9.0
    sdkconfig_options:
      CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
      CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
      CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240: y
      CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ: '240'

preferences:
  flash_write_interval: 30min 

packages:
  api: !include common/api.yaml
  ota: !include common/ota.yaml
  wifi: !include common/wifi.yaml
  web_server: !include common/web_server.yaml
  button: !include common/button.yaml
  sensor: !include common/sensor.yaml
  internal_temperature: !include common/sensor/internal_temperature/esp32.yaml
  battery: !include common/sensor/battery/ttgo-t7-v13-mini32.yaml

logger:
  level: DEBUG
  logs:
    light: INFO

i2c: # https://esphome.io/components/i2c
  sda: $i2c_sda
  scl: $i2c_scl
  scan: true

output:
- platform: ledc
  id: status_led_output
  pin:
    number: $pin_status_led

light:
  - platform: status_led # https://esphome.io/components/light/status_led
    name: Status Led
    output: status_led_output
    id: ${node_name}_statusled
    icon: mdi:led-off
    internal: true

  - platform: monochromatic 
    name: Led
    output: status_led_output
    restore_mode: ALWAYS_OFF
    id: ${node_name}_status_led
    icon: mdi:led-off
    <<: *disabled
    effects:
      - strobe:
      - pulse: