From 6c0c77d788bfa9591d2efaadca1f8956659674c0 Mon Sep 17 00:00:00 2001 From: pelgraine <140762863+pelgraine@users.noreply.github.com> Date: Sat, 2 May 2026 06:07:12 +1000 Subject: [PATCH] improved tdpro and t5s3 ble sync speed with large contact lists; updated firmware build date --- examples/companion_radio/MyMesh.h | 2 +- examples/companion_radio/ui-new/UITask.cpp | 7 +++++++ src/helpers/BaseSerialInterface.h | 1 + src/helpers/esp32/SerialBLEInterface.cpp | 20 +++++++++++++++----- src/helpers/esp32/SerialBLEInterface.h | 1 + 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index 7451fb2f..a823e398 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -8,7 +8,7 @@ #define FIRMWARE_VER_CODE 11 #ifndef FIRMWARE_BUILD_DATE -#define FIRMWARE_BUILD_DATE "27 April 2026" +#define FIRMWARE_BUILD_DATE "2 May 2026" #endif #ifndef FIRMWARE_VERSION diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 3003b991..853c8ca9 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -1798,6 +1798,12 @@ if (curr) curr->poll(); if (_display != NULL && _display->isOn()) { if (millis() >= _next_refresh && curr) { + // Defer display refresh while BLE is actively transferring contacts. + // E-ink partial update blocks for ~820ms, stalling the BLE send queue + // and adding ~1.6s of dead time to a full contact sync. + if (_serial != NULL && _serial->hasPendingData()) { + _next_refresh = millis() + 500; // Re-check in 500ms + } else { // Sync dark mode with prefs (settings toggle takes effect here) if (_node_prefs && display.isDarkMode() != (_node_prefs->dark_mode != 0)) { display.setDarkMode(_node_prefs->dark_mode != 0); @@ -1964,6 +1970,7 @@ if (curr) curr->poll(); unsigned long minNext = millis() + 800; // Partial refresh: 800ms floor #endif if (_next_refresh < minNext) _next_refresh = minNext; + } // end else (not bulk syncing) } #if AUTO_OFF_MILLIS > 0 if (millis() > _auto_off) { diff --git a/src/helpers/BaseSerialInterface.h b/src/helpers/BaseSerialInterface.h index 8f5cb61c..e9fa7b45 100644 --- a/src/helpers/BaseSerialInterface.h +++ b/src/helpers/BaseSerialInterface.h @@ -16,6 +16,7 @@ public: virtual bool isConnected() const = 0; virtual bool isWriteBusy() const = 0; + virtual bool hasPendingData() const { return false; } virtual size_t writeFrame(const uint8_t src[], size_t len) = 0; virtual size_t checkRecvFrame(uint8_t dest[]) = 0; }; \ No newline at end of file diff --git a/src/helpers/esp32/SerialBLEInterface.cpp b/src/helpers/esp32/SerialBLEInterface.cpp index 22c44187..747058ff 100644 --- a/src/helpers/esp32/SerialBLEInterface.cpp +++ b/src/helpers/esp32/SerialBLEInterface.cpp @@ -96,6 +96,16 @@ void SerialBLEInterface::onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) { conn_params.timeout = 400; // 4 seconds supervision timeout esp_ble_gap_update_conn_params(&conn_params); BLE_DEBUG_PRINTLN(" - Requested fast connection interval (15-20ms)"); + + // Request 2M PHY for doubled air data rate (BLE 5.0, supported on ESP32-S3) + // Note: ESP-IDF misspells "preferred" as "prefered" in their API + esp_ble_gap_set_prefered_phy(_remote_bda, + 0, // all_phys: no preference flags, use tx/rx masks + ESP_BLE_GAP_PHY_2M_PREF_MASK, + ESP_BLE_GAP_PHY_2M_PREF_MASK, + ESP_BLE_GAP_PHY_OPTIONS_NO_PREF); + esp_ble_gap_set_pkt_data_len(_remote_bda, 251); // Request DLE (max link-layer PDU) + BLE_DEBUG_PRINTLN(" - Requested 2M PHY and DLE (251 bytes)"); } else { BLE_DEBUG_PRINTLN(" - SecurityCallback - Authentication Failure*"); @@ -205,7 +215,7 @@ size_t SerialBLEInterface::writeFrame(const uint8_t src[], size_t len) { return 0; } -#define BLE_WRITE_MIN_INTERVAL 15 +#define BLE_WRITE_MIN_INTERVAL 7 bool SerialBLEInterface::isWriteBusy() const { return millis() < _last_write + BLE_WRITE_MIN_INTERVAL; // still too soon to start another write? @@ -224,8 +234,8 @@ size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) { BLE_DEBUG_PRINTLN("writeBytes: sz=%d, hdr=%d", (uint32_t)send_queue[0].len, (uint32_t) send_queue[0].buf[0]); send_queue_len--; - for (int i = 0; i < send_queue_len; i++) { // delete top item from queue - send_queue[i] = send_queue[i + 1]; + if (send_queue_len > 0) { + memmove(&send_queue[0], &send_queue[1], send_queue_len * sizeof(Frame)); } } @@ -236,8 +246,8 @@ size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) { BLE_DEBUG_PRINTLN("readBytes: sz=%d, hdr=%d", len, (uint32_t) dest[0]); recv_queue_len--; - for (int i = 0; i < recv_queue_len; i++) { // delete top item from queue - recv_queue[i] = recv_queue[i + 1]; + if (recv_queue_len > 0) { + memmove(&recv_queue[0], &recv_queue[1], recv_queue_len * sizeof(Frame)); } return len; } diff --git a/src/helpers/esp32/SerialBLEInterface.h b/src/helpers/esp32/SerialBLEInterface.h index a453e328..a0867bea 100644 --- a/src/helpers/esp32/SerialBLEInterface.h +++ b/src/helpers/esp32/SerialBLEInterface.h @@ -79,6 +79,7 @@ public: bool isConnected() const override; bool isWriteBusy() const override; + bool hasPendingData() const override { return deviceConnected && send_queue_len > 0; } size_t writeFrame(const uint8_t src[], size_t len) override; size_t checkRecvFrame(uint8_t dest[]) override; };