From ee1f034c5966ee0f8ead4f5f70c5b94aa73bf779 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 3 Jul 2026 18:12:46 -0400 Subject: [PATCH] Defer BLE-callback display teardown and MSD update to the main loop (ESP32) onConnect() and onDisconnect() run in the BLE host task. onConnect() called updatemsdata() (I2C sensor reads + shared-state mutation) and onDisconnect() called cleanupDirectWriteState() (bbepSleep/SPI.end/pwrmgm) directly. Both race loop(): a disconnect firing while loop() is mid bbepWriteData powers the panel down under an in-flight SPI transfer and clears state the handler is still using; onConnect's updatemsdata races the loop's I2C/statics. Set pending flags in the callbacks (like the existing bleRestartAdvertisingPending) and do the work in loop() instead. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01MgW3EZCfMkGFffseDPwV74 --- src/ble_init.cpp | 2 ++ src/ble_init.h | 2 ++ src/esp32_ble_callbacks.h | 5 ++--- src/main.cpp | 11 +++++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/ble_init.cpp b/src/ble_init.cpp index 1c036b4..310ca82 100644 --- a/src/ble_init.cpp +++ b/src/ble_init.cpp @@ -137,6 +137,8 @@ void ble_init() { #ifdef TARGET_ESP32 volatile bool bleRestartAdvertisingPending = false; +volatile bool bleConnectMsdUpdatePending = false; +volatile bool bleDirectWriteCleanupPending = false; volatile bool esp32BleNotifySubscribed = false; #if defined(CONFIG_BLUEDROID_ENABLED) static BLE2902* s_bleNotifyCccd = nullptr; diff --git a/src/ble_init.h b/src/ble_init.h index 2ad8d93..f929184 100644 --- a/src/ble_init.h +++ b/src/ble_init.h @@ -15,6 +15,8 @@ void esp32_restart_ble_advertising(void); void esp32_ble_clear_handles(void); bool esp32_ble_notify_enabled(void); extern volatile bool bleRestartAdvertisingPending; +extern volatile bool bleConnectMsdUpdatePending; +extern volatile bool bleDirectWriteCleanupPending; extern volatile bool esp32BleNotifySubscribed; #endif diff --git a/src/esp32_ble_callbacks.h b/src/esp32_ble_callbacks.h index 088613a..69e2079 100644 --- a/src/esp32_ble_callbacks.h +++ b/src/esp32_ble_callbacks.h @@ -41,7 +41,7 @@ class MyBLEServerCallbacks : public BLEServerCallbacks { writeSerial("=== BLE CLIENT CONNECTED (ESP32) ==="); rebootFlag = 0; esp32BleNotifySubscribed = false; - updatemsdata(); + bleConnectMsdUpdatePending = true; } void onDisconnect(BLEServer* pServer) { (void)pServer; @@ -50,8 +50,7 @@ class MyBLEServerCallbacks : public BLEServerCallbacks { if (epdRefreshInProgress) { writeSerial("EPD refresh in progress — deferring cleanup/advertising to main loop"); } else if (directWriteActive) { - cleanupDirectWriteState(true); - touchResumeAfterEpdRefresh(); + bleDirectWriteCleanupPending = true; } bleRestartAdvertisingPending = true; } diff --git a/src/main.cpp b/src/main.cpp index cb202f8..41b1c22 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -134,6 +134,17 @@ void loop() { if (bleRestartAdvertisingPending) { esp32_restart_ble_advertising(); } + if (bleConnectMsdUpdatePending) { + bleConnectMsdUpdatePending = false; + updatemsdata(); + } + if (bleDirectWriteCleanupPending) { + bleDirectWriteCleanupPending = false; + if (directWriteActive) { + cleanupDirectWriteState(true); + touchResumeAfterEpdRefresh(); + } + } if (directWriteActive && directWriteStartTime > 0) { uint32_t directWriteDuration = millis() - directWriteStartTime; if (directWriteDuration > 900000UL) { // 15 minute timeout (upload + refresh window)