Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions examples/companion_radio/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ static uint32_t _atoi(const char* sp) {
#endif
#elif defined(BLE_PIN_CODE)
#include <helpers/esp32/SerialBLEInterface.h>
SerialBLEInterface serial_interface;
#include <helpers/SerialDualInterface.h>
SerialDualInterface<SerialBLEInterface> serial_interface;
#elif defined(SERIAL_RX)
#include <helpers/ArduinoSerialInterface.h>
ArduinoSerialInterface serial_interface;
Expand Down Expand Up @@ -73,7 +74,8 @@ static uint32_t _atoi(const char* sp) {
#elif defined(NRF52_PLATFORM)
#ifdef BLE_PIN_CODE
#include <helpers/nrf52/SerialBLEInterface.h>
SerialBLEInterface serial_interface;
#include <helpers/SerialDualInterface.h>
SerialDualInterface<SerialBLEInterface> serial_interface;
#else
#include <helpers/ArduinoSerialInterface.h>
ArduinoSerialInterface serial_interface;
Expand Down Expand Up @@ -151,7 +153,7 @@ void setup() {
);

#ifdef BLE_PIN_CODE
serial_interface.begin(BLE_NAME_PREFIX, the_mesh.getNodePrefs()->node_name, the_mesh.getBLEPin());
serial_interface.begin(BLE_NAME_PREFIX, the_mesh.getNodePrefs()->node_name, the_mesh.getBLEPin(), Serial);
#else
serial_interface.begin(Serial);
#endif
Expand Down Expand Up @@ -198,7 +200,7 @@ void setup() {
WiFi.begin(WIFI_SSID, WIFI_PWD);
serial_interface.begin(TCP_PORT);
#elif defined(BLE_PIN_CODE)
serial_interface.begin(BLE_NAME_PREFIX, the_mesh.getNodePrefs()->node_name, the_mesh.getBLEPin());
serial_interface.begin(BLE_NAME_PREFIX, the_mesh.getNodePrefs()->node_name, the_mesh.getBLEPin(), Serial);
#elif defined(SERIAL_RX)
companion_serial.setPins(SERIAL_RX, SERIAL_TX);
companion_serial.begin(115200);
Expand Down
2 changes: 1 addition & 1 deletion examples/companion_radio/ui-new/UITask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ class HomeScreen : public UIScreen {
display.setTextSize(1);
display.drawTextCentered(display.width() / 2, 43, "< Connected >");

} else if (the_mesh.getBLEPin() != 0) { // BT pin
} else if (the_mesh.getBLEPin() != 0 && _task->isSerialEnabled()) { // BT pin
display.setColor(DisplayDriver::RED);
display.setTextSize(2);
sprintf(tmp, "Pin:%d", the_mesh.getBLEPin());
Expand Down
8 changes: 6 additions & 2 deletions src/helpers/ArduinoSerialInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ void ArduinoSerialInterface::disable() {
_isEnabled = false;
}

bool ArduinoSerialInterface::isConnected() const {
return true; // no way of knowing, so assume yes
bool ArduinoSerialInterface::isConnected() const {
#if defined(NRF52_PLATFORM) || defined(ESP32_PLATFORM)
return Serial; // operator bool() checks connection (USB CDC DTR, UART init)
#else
return true; // platforms without operator bool() on Serial have no way of knowing, so assume yes
#endif
}

bool ArduinoSerialInterface::isWriteBusy() const {
Expand Down
73 changes: 73 additions & 0 deletions src/helpers/SerialDualInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#pragma once

#include "ArduinoSerialInterface.h"

template <typename BLEInterface>
class SerialDualInterface : public BaseSerialInterface {
BLEInterface _ble;
ArduinoSerialInterface _usb;
bool _bleWasConnected;

public:
SerialDualInterface() : _bleWasConnected(false) { }

void begin(const char* prefix, char* name, uint32_t pin_code, Stream& serial) {
_ble.begin(prefix, name, pin_code);
_usb.begin(serial);
}

// enable/disable only control BLE, USB is always available
void enable() override {
_ble.enable();
}

void disable() override {
_ble.disable();
}

bool isEnabled() const override {
return _ble.isEnabled() || _usb.isEnabled();
}

bool isConnected() const override {
return _ble.isConnected() || _usb.isConnected();
}

bool isWriteBusy() const override {
if (_ble.isConnected()) return _ble.isWriteBusy();
return _usb.isWriteBusy();
}

size_t writeFrame(const uint8_t src[], size_t len) override {
if (_ble.isConnected()) return _ble.writeFrame(src, len);
return _usb.writeFrame(src, len);
}

size_t checkRecvFrame(uint8_t dest[]) override {
// Always call BLE first, it needs polling for send queue draining
// and advertising watchdog, even when USB is the active transport
size_t n = _ble.checkRecvFrame(dest);

bool bleNow = _ble.isConnected();
if (bleNow != _bleWasConnected) {
if (bleNow) {
// BLE just connected, wait for any pending USB write to finish
while (_usb.isWriteBusy()) { }
_usb.disable();
} else {
// BLE just disconnected, re-enable USB (resets state machine,
// discarding any stale bytes from the previous session)
_usb.enable();
}
_bleWasConnected = bleNow;
}

if (n > 0) return n; // got a BLE frame

// Only check USB when BLE is not connected
if (!bleNow) {
return _usb.checkRecvFrame(dest);
}
return 0;
}
};