Fix Heltec V4 display (Vext PMOS polarity) and Xtensa TX-wait stack overflow.
Conflict in heltec_wifi_lora32_v4_procpu.dts resolved: kept the corrected
BatADC header line from 247ca65 (GPIO1 = ADC1_CH0 / &adc0, GPIO37 active-HIGH)
and took the PR Vext change (GPIO36 active-LOW PMOS rail switch).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
TX_WAIT_THREAD_STACK_SIZE was 1024 bytes, shared by every radio
adapter. On Xtensa (all ESP32/S3 boards) the windowed ABI needs ~3x
the stack of Cortex-M for the same code — Zephyr's own Kconfig
defaults reflect this (IDLE_STACK_SIZE: 1024 if XTENSA vs 320 ARM).
Measured peak usage on Heltec V4 (immediate-mode logging, full TX
cycle including startReceive/lora_config): 1252 bytes — already past
the old 1024 limit. The overflow corrupts the exception frame and
parks CPU0 in _DoubleExceptionVector (LoadProhibited @0x2c), a silent
total freeze at boot. Confirmed via the S3 built-in USB-JTAG:
current thread at crash = lora_tx_wait.
2048 gives ~39% headroom over the measured worst case.
The V4's Vext rail switch is a PMOS: GPIO36 LOW turns the rail ON.
The DTS drove it ACTIVE_HIGH, leaving the OLED (and its I2C pull-ups)
unpowered — the rail floats at ~1.6V and SSD1306 init always fails
with -ETIMEDOUT.
Verified on hardware with a multimeter: GPIO36 high = 1.6V on Vext,
GPIO36 low = 3.3V, display works.
This matches what the working Arduino MeshCore firmware actually does
with the pin, despite its PIN_VEXT_EN_ACTIVE=HIGH define:
RefCountedDigitalPin::begin() initialises the pin to its *inactive*
level (LOW), and the V4 OLED build constructs the display with a NULL
periph_power (variants/heltec_v4/target.cpp) so nothing ever claims
it HIGH. GPIO36 is therefore driven LOW continuously under Arduino —
the exact state this fix reproduces via an ACTIVE_LOW boot-on
regulator.