Heltec V4: System freeze during radio transmission with custom UI (LVGL overlay) #8703
Replies: 4 comments 7 replies
-
|
What measures did you take to prevent concurrent access to the SPI bus? |
Beta Was this translation helpful? Give feedback.
-
|
@mverch67 thank you for the follow up! SPI Bus Protection Measures and Testing Done: We’ve attempted several approaches to prevent concurrent SPI access, though we may be missing the correct method for V4: 1. Display Library Locking:
2. SPI Host Isolation:
3. Manual Synchronization Attempt: volatile bool radioIsBusy = false;
void enhanced_loopCustomUI() {
if (!radioIsBusy) {
lv_timer_handler();
// display operations
}
}
// Modified NodeInfoModule to set flag before transmission
radioIsBusy = true;
delay(100);
sendOurNodeInfo(...);
delay(100);
radioIsBusy = false;Still froze during transmission. 4. DMA Channel Configuration:
5. Deferred Initialization:
6. Memory Allocation Testing:
7. Complexity Reduction:
8. Complete Display Removal:
Consistent Behavior Pattern: The freeze is 100% reproducible:
Serial output always stops here: Questions We Have:
We’re likely missing the proper approach for V4 custom overlays. Any guidance on the correct synchronization method or known limitations would be greatly appreciated. We’re happy to test any suggested approaches or provide additional debugging information. |
Beta Was this translation helpful? Give feedback.
-
|
Regarding 3. (manual synchronization attempt): You need to use OS semaphores for synchronization! A simple boolean check cannot work (infamous testAndSet problem). #include "SPILock.h"
void loopCustomUI() {
{
concurrency::LockGuard g(spiLock);
lv_timer_periodic_handler();
}
delay(5);
}
Then you can leave the LovyanGFX Also make sure that you explicitly initialize all SPI CS pins that are connected to the same SPI bus prior any SPI initialization. |
Beta Was this translation helpful? Give feedback.
-
Regarding this question, (M)UI is fully supported for this device, see here and here and here. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hardware
Board: Heltec LoRa V4 (ESP32-S3, 16MB Flash, 2MB PSRAM)
Display: ST7796 320x480 TFT via SPI3
Touch: FT5x06 capacitive touch via I2C
Firmware: Meshtastic 2.7.13.163842d alpha
Description
Screen/UI freezes when radio attempts to transmit packets after AES encryption. Freeze occurs consistently at the first NodeInfo broadcast (~147 seconds after boot) or when sending messages via app. The issue ONLY occurs with custom LVGL UI overlay - official firmware works perfectly.
Expected Behavior
Radio should successfully transmit packets after encryption, as it does with official firmware.
Actual Behavior (CORRECTED)
System crashes and automatically reboots during/after radio transmission following “Use AES128 key!” log. The device enters a crash-reboot loop:
• Serial output stops at “Use AES128 key!”
• Screen UI freezes (blinking UI dot stops blinking) but screen stays on for a while (exact timing unknown)
• Then crashes - board reboots and screen turns off then back on, display dot starts blinking again (confirms device rebooted)
• Serial connection breaks - no boot logs appear in monitor
• Device boots and crashes again at same point (~147 seconds later)
• Cycle repeats indefinitely
Logs
INFO | ??:??:?? 146 [NodeInfo] Send our nodeinfo to mesh (wantReplies=0)
INFO | ??:??:?? 146 [NodeInfo] Send owner !b2a7c154/Meshtastic c154/c154
DEBUG | ??:??:?? 146 [NodeInfo] Initial packet id 335703107
DEBUG | ??:??:?? 146 [NodeInfo] Partially randomized packet id 1544295492
DEBUG | ??:??:?? 146 [NodeInfo] Ignore update from self
DEBUG | ??:??:?? 146 [NodeInfo] handleReceived(LOCAL) (id=0x5c0c1444 fr=0xb2a7c154 to=0xffffffff, transport = 0, WantAck=0, HopLim=3 Ch=0x0 Portnum=4 priority=10)
DEBUG | ??:??:?? 146 [NodeInfo] No modules interested in portnum=4, src=LOCAL
INFO | ??:??:?? 146 [NodeInfo] Packet History - insert: Using new slot @uptime 146.442s TRACE NEW
DEBUG | ??:??:?? 146 [NodeInfo] Expand short PSK #1
DEBUG | ??:??:?? 146 [NodeInfo] Use AES128 key!
[SYSTEM FREEZES HERE - no further logs, no reboot]
Custom Overlay Details
Display Library: LovyanGFX (local lib, same version that works on V3)
UI Framework: LVGL 8.x
SPI Configuration: SPI3_HOST, DMA_CH_AUTO
Display Pins: SCLK=3, MOSI=4, DC=26, CS=33, RST=48
LVGL Buffer: 320x40 static array in internal RAM (confirmed via address check)
What We've (Claude and I) Tested
✅ Confirmed working:
Official Meshtastic 2.7.13/2.7.14 firmware on same V4 hardware (no freeze)
Identical custom overlay code on Heltec V3 hardware (no freeze)
Minimal code with NO display operations (radio works perfectly)
❌ All cause freeze:
Full LVGL overlay with custom screens
Minimal overlay with just tft.fillCircle() (no LVGL)
Any display operations running when radio transmits
Attempted fixes (all failed):
Different DMA channels (1, 2, 3, disabled)
Different SPI hosts (SPI2_HOST, SPI3_HOST)
Deferred LGFX initialization (after radio init)
LVGL buffer in internal RAM vs PSRAM
Disabling touch input
Adding delays before/after radio operations
Pausing LVGL during transmission attempts
Root Cause Theory (May be Incorrect)
V4 has external QSPI PSRAM while V3 has internal PSRAM. We suspect concurrent access to external PSRAM by both the LoRa radio driver and display operations causes a deadlock/race condition during radio transmission. The freeze happens specifically during the transmission phase after encryption completes, suggesting the radio driver's DMA or interrupt handling conflicts with display SPI operations.
Comparison with Working V3
The exact same custom overlay code works perfectly on Heltec V3 (ESP32, internal PSRAM). The ONLY hardware difference between V3 and V4 that affects this is the external PSRAM architecture.
Request
From the application/overlay side, we have not found a configuration that avoids this freeze while still using the display. We’re wondering:
Is this a known limitation or bug on the Heltec V4 / ESP32-S3 target when using external PSRAM + SPI display?
Are there recommended constraints (e.g., no DMA on display, specific PSRAM config, task/core affinity) for custom overlays on V4?
Is support for custom UI overlays on V4 something that’s expected to work in 2.7.x, or is it planned for a later stable?
Beta Was this translation helpful? Give feedback.
All reactions