Eight environments were still pinned to espressif32@6.1.0 (arduino-esp32
2.0.7 / IDF 4.4) while the rest of the tree had moved to the shared
${com.esp32_platform} definition. Align them so they build against the
platform that actually ships, rather than silently keeping an old
toolchain alive:
esp32doitv1-aithinker-r01-sx1278
esp32dev-rtl_433, esp32dev-rtl_433-fsk
heltec-rtl_433, heltec-rtl_433-fsk
lilygo-rtl_433, lilygo-rtl_433-fsk
esp32dev-multi_receiver
The stray "* copy.c" duplicate in rtl_433_ESP that previously blocked
these envs on a modern toolchain is gone as of rtl_433_ESP v0.6.0, which
development already pulls in, so no build workaround is needed.
The move alone is not sufficient: the newer core leaves ~35 KB less heap
on BT-less ESP32 builds, which pushes the memory-constrained RTL_433
boards into a boot loop at the first TLS handshake. That is fixed here
too, in main.cpp.
On ESP32-classic builds without ZgatewayBT, arduino-esp32 3.x leaves most
of the Bluetooth controller's reserved DRAM (CONFIG_BTDM_RESERVE_DRAM =
0xdb5c, 56156 B) stranded. arduino-esp32 2.x released the whole BTDM
region unconditionally in initArduino():
if (!btInUse()) esp_bt_controller_mem_release(ESP_BT_MODE_BTDM);
3.x releases CLASSIC and BLE separately, and the CLASSIC pass silently
short-circuits. cores/esp32/esp32-hal-bt.c has:
#if defined(CONFIG_BT_CLASSIC_ENABLED)
static bool _classicMemReleased = false;
#else
static bool _classicMemReleased = true; // "No Classic BT on this chip"
#endif
With a BLE-only controller build CONFIG_BT_CLASSIC_ENABLED is unset, so
_classicMemReleased starts true and btMemRelease(BT_MODE_CLASSIC_BT)
returns "already released" without reaching IDF. Only the ~5 KB BLE slice
is freed. The guard is wrong for this part: ESP32 does have Classic BT
hardware (CONFIG_SOC_BT_CLASSIC_SUPPORTED) and the DRAM is reserved
regardless of the controller's configured mode; the correct guard would be
CONFIG_SOC_BT_CLASSIC_SUPPORTED. Reported upstream separately.
Release the whole BTDM region explicitly. esp_bt_mem_release() is used
rather than esp_bt_controller_mem_release() because it is a superset that
also frees the linker _bt_data / _bt_controller_* sections. The guard is
compile-time and authoritative: OMG knows via ZgatewayBT whether it uses
BT, whereas the core infers it from link-time flags that NimBLE-Arduino
does not set. Safe no-op if the memory was already released or once the
core is fixed. Note this makes btStart() permanently unavailable in these
builds, which is already the case for a !ZgatewayBT build.
Measured on a Heltec WiFi LoRa32 V2 running heltec-rtl_433 (WiFi + MQTT +
TLS + rtl_433 + SSD1306, no BT), pioarduino 55.03.39 / esp32-arduino-libs
0.1.8:
BT DRAM reclaimed: 209928 -> 245048 (+35120 B)
Update check, free heap: 49868 -> 89484
Without it, the boot-time HTTPS update check fails its TLS handshake
("Dynamic Impl: alloc(4437 bytes) failed", then X509 -9984) because the
largest free block is too small, and the MinimumMemory watchdog then
reboots the board in a loop. With it: no allocation failure, handshake
succeeds, freemem ~85 KB / minmem 53432 against the 40000 threshold,
0 reboots over a 3 min soak with live RTL_433 decodes.
The memory fix affects every ESP32-classic env without ZgatewayBT, not
just the ones moved here. The RTL_433 envs fail loudly because they carry
the MinimumMemory watchdog; others (esp32dev-ir, esp32dev-pilight,
ttgo-lora32-v21, heltec-wifi-lora-32, ...) simply run ~35 KB short.
Builds with ZgatewayBT are unaffected.
Hardware validation, two boards:
heltec-rtl_433 (OOK 433.92 MHz, Heltec WiFi LoRa32 V2)
boots, joins WiFi/MQTT, RadioLib/SX127x RSSI calibration completes,
HA discovery publishes, decodes live ambient sensors
(Ambientweather-F007TH, Prologue-TH, WEC-2103).
heltec-rtl_433-fsk (FSK 915 MHz, second Heltec)
same boot path, decodes a live Fineoffset-WH51 soil sensor.
The other six envs have no matching board on hand and are compile-only.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>