From 5828600d48cc06e0cd5f927244fd10085709ca0c Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Thu, 21 May 2026 14:16:07 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20dual=20BLE+USB=20serial=20=E2=80=94=20s?= =?UTF-8?q?ingle=20firmware=20replaces=20separate=20BLE/USB=20builds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DualSerialInterface: enable()/disable() control BLE only, USB always on; USB state machine not read while BLE connected to avoid partial-frame corruption; reset USB on BLE disconnect for clean reconnect - Fix -UBLE_DEBUG_LOGGING (no space) to avoid PlatformIO SCons parse error - build.sh: drop separate USB/BLE builds, dual_settings only - wio-tracker-l1-eink: enable DUAL_SERIAL in companion_radio_ble build Co-Authored-By: Claude Sonnet 4.6 --- build.sh | 2 - src/helpers/nrf52/DualSerialInterface.h | 41 +++++++++++++++------ variants/wio-tracker-l1-eink/platformio.ini | 1 + variants/wio-tracker-l1/platformio.ini | 2 +- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/build.sh b/build.sh index 506f9a39..d34877cc 100755 --- a/build.sh +++ b/build.sh @@ -231,8 +231,6 @@ build_companion_firmwares() { } build_wio_tracker_l1_firmwares() { - build_firmware "WioTrackerL1_companion_radio_usb_settings" - build_firmware "WioTrackerL1_companion_radio_ble_settings" build_firmware "WioTrackerL1_companion_radio_dual_settings" } diff --git a/src/helpers/nrf52/DualSerialInterface.h b/src/helpers/nrf52/DualSerialInterface.h index 259e41ef..6fed9e52 100644 --- a/src/helpers/nrf52/DualSerialInterface.h +++ b/src/helpers/nrf52/DualSerialInterface.h @@ -5,22 +5,29 @@ #include "SerialBLEInterface.h" // Wraps BLE + USB serial interfaces: BLE takes priority when connected, -// USB is always ready as a fallback. Both state machines run continuously. +// USB is always ready as a fallback. +// enable()/disable() control BLE only — USB is always on. +// BLE state machine is only pumped when BLE is enabled; USB is not read while BLE is connected. class DualSerialInterface : public BaseSerialInterface { SerialBLEInterface _ble; ArduinoSerialInterface _usb; uint8_t _ble_buf[MAX_FRAME_SIZE]; uint8_t _usb_buf[MAX_FRAME_SIZE]; + bool _ble_enabled; + bool _ble_was_connected; public: + DualSerialInterface() : _ble_enabled(false), _ble_was_connected(false) {} + void begin(const char* ble_prefix, char* node_name, uint32_t pin_code, Stream& usb_stream) { _ble.begin(ble_prefix, node_name, pin_code); _usb.begin(usb_stream); + _usb.enable(); // USB is always on } - void enable() override { _ble.enable(); _usb.enable(); } - void disable() override { _ble.disable(); _usb.disable(); } - bool isEnabled() const override { return _ble.isEnabled() || _usb.isEnabled(); } + void enable() override { _ble.enable(); _ble_enabled = true; } + void disable() override { _ble.disable(); _ble_enabled = false; } + bool isEnabled() const override { return _ble_enabled; } // Always true — USB is always available as fallback, so the mesh can send. bool isConnected() const override { return true; } @@ -36,16 +43,26 @@ public: } size_t checkRecvFrame(uint8_t dest[]) override { - // Always pump both state machines: BLE needs this for TX queue drain and - // advertising watchdog; USB needs it to drain its input buffer. - size_t ble_len = _ble.checkRecvFrame(_ble_buf); - size_t usb_len = _usb.checkRecvFrame(_usb_buf); + if (_ble_enabled) { + size_t ble_len = _ble.checkRecvFrame(_ble_buf); + bool ble_now = _ble.isConnected(); - if (_ble.isConnected()) { - if (ble_len > 0) { memcpy(dest, _ble_buf, ble_len); return ble_len; } - } else { - if (usb_len > 0) { memcpy(dest, _usb_buf, usb_len); return usb_len; } + if (ble_now) { + _ble_was_connected = true; + if (ble_len > 0) { memcpy(dest, _ble_buf, ble_len); return ble_len; } + return 0; // BLE active — don't read USB to keep its state machine clean + } + + if (_ble_was_connected) { + // BLE just disconnected — reset USB state machine so stale partial frames don't block it + _ble_was_connected = false; + _usb.enable(); + return 0; + } } + + size_t usb_len = _usb.checkRecvFrame(_usb_buf); + if (usb_len > 0) { memcpy(dest, _usb_buf, usb_len); return usb_len; } return 0; } }; diff --git a/variants/wio-tracker-l1-eink/platformio.ini b/variants/wio-tracker-l1-eink/platformio.ini index 42c83477..0afe327f 100644 --- a/variants/wio-tracker-l1-eink/platformio.ini +++ b/variants/wio-tracker-l1-eink/platformio.ini @@ -57,6 +57,7 @@ build_flags = ${WioTrackerL1Eink.build_flags} ; -D MESH_DEBUG=1 -D UI_RECENT_LIST_SIZE=6 -D UI_SENSORS_PAGE=1 + -D DUAL_SERIAL build_src_filter = ${WioTrackerL1Eink.build_src_filter} + + diff --git a/variants/wio-tracker-l1/platformio.ini b/variants/wio-tracker-l1/platformio.ini index dc319d05..1e2325ed 100644 --- a/variants/wio-tracker-l1/platformio.ini +++ b/variants/wio-tracker-l1/platformio.ini @@ -140,7 +140,7 @@ extra_scripts = post:create-uf2.py extends = WioTrackerL1CompanionBLE build_flags = ${WioTrackerL1CompanionBLE.build_flags} -D DUAL_SERIAL=1 - -U BLE_DEBUG_LOGGING + -UBLE_DEBUG_LOGGING [env:WioTrackerL1_companion_radio_dual] extends = WioTrackerL1CompanionDual