Merge pull request #3357 from skandragon/feat/picow-wifi-ble

Add WiFi to RPI PicoW (and perhaps others)
This commit is contained in:
Liam Cottle authored and GitHub committed 2026-09-09 21:55:22 +12:00
commit 1751783931
34 files changed
+612 -59

No files matched your search

+2
View File
@@ -20,10 +20,12 @@ for item in menv.get("CPPDEFINES", []):
src_filter.append("+<helpers/stm32/*>")
elif item == "ESP32":
src_filter.append("+<helpers/esp32/*>")
src_filter.append("+<helpers/wifi/*>")
elif item == "NRF52_PLATFORM":
src_filter.append("+<helpers/nrf52/*>")
elif item == "RP2040_PLATFORM":
src_filter.append("+<helpers/rp2040/*>")
src_filter.append("+<helpers/wifi/*>")
# DISPLAY HANDLING
elif isinstance(item, tuple) and item[0] == "DISPLAY_CLASS":
+57
View File
@@ -1,6 +1,9 @@
#include "MyMesh.h"
#include <Arduino.h> // needed for PlatformIO
#ifdef ENABLE_WIFI_INTERFACE
#include <WiFi.h>
#endif
#include <Mesh.h>
#define CMD_APP_START 1
@@ -932,6 +935,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
_serial(NULL), telemetry(MAX_PACKET_PAYLOAD - 4), _store(&store), _ui(ui), _iter(0) {
_iter_started = false;
_cli_rescue = false;
cli_command[0] = 0;
offline_queue_len = 0;
app_target_ver = 0;
clearPendingReqs();
@@ -2160,6 +2164,54 @@ bool MyMesh::handleCommand(const char* command, uint32_t sender_timestamp, char*
return true;
}
#ifdef ENABLE_WIFI_INTERFACE
if (memcmp(command, "set wifi.ssid ", 14) == 0) {
StrHelper::strncpy(_prefs.wifi_ssid, &command[14], sizeof(_prefs.wifi_ssid));
savePrefs();
sprintf(reply, "> wifi.ssid is now %s (set wifi.pwd too, then reboot)", _prefs.wifi_ssid);
return true;
}
if (memcmp(command, "set wifi.pwd ", 13) == 0) {
StrHelper::strncpy(_prefs.wifi_pwd, &command[13], sizeof(_prefs.wifi_pwd));
savePrefs();
strcpy(reply, "> wifi.pwd updated (reboot to apply)");
return true;
}
if (strcmp(command, "set wifi.clear") == 0) {
_prefs.wifi_ssid[0] = 0;
_prefs.wifi_pwd[0] = 0;
savePrefs();
strcpy(reply, "> wifi config cleared (reboot to apply)");
return true;
}
if (strcmp(command, "get wifi.ssid") == 0) { // no 'get wifi.pwd', by design
sprintf(reply, "> %s", _prefs.getWifiSSID()[0] ? _prefs.getWifiSSID() : "(not set)");
return true;
}
if (memcmp(command, "set wifi.enabled ", 17) == 0) {
_prefs.wifi_enabled = atoi(&command[17]) ? 1 : 0;
savePrefs();
sprintf(reply, "> wifi.enabled is now %d (reboot to apply)", _prefs.wifi_enabled);
return true;
}
if (strcmp(command, "get wifi.enabled") == 0) {
sprintf(reply, "> %d", _prefs.wifi_enabled);
return true;
}
if (strcmp(command, "get wifi.status") == 0) {
strcpy(reply, WiFi.status() == WL_CONNECTED ? "> connected" : "> disconnected");
return true;
}
if (strcmp(command, "get wifi.ip") == 0) {
if (WiFi.status() == WL_CONNECTED) {
sprintf(reply, "> %s", WiFi.localIP().toString().c_str());
} else {
strcpy(reply, "> (not connected)");
}
return true;
}
#endif
if (strcmp(command, "board") == 0) {
strcpy(reply, board.getManufacturerName());
return true;
@@ -2390,6 +2442,11 @@ void MyMesh::loop() {
checkCLIRescueCmd();
} else {
checkSerialInterface();
#if defined(ENABLE_WIFI_INTERFACE) && defined(RP2040_PLATFORM) && !defined(ENABLE_USB_INTERFACE)
// RP2040 WiFi builds are headless and have no way into the rescue CLI (that needs a
// display + long-press), so serve config commands on the otherwise unused USB serial
checkCLIRescueCmd();
#endif
}
// is there are pending dirty contacts write needed?
+33 -1
View File
@@ -48,6 +48,16 @@ public:
char default_scope_name[31];
uint8_t default_scope_key[16];
int8_t tz_offset = 0;
#ifdef ENABLE_WIFI_INTERFACE
#ifndef WIFI_SSID
#define WIFI_SSID ""
#endif
char wifi_ssid[33] = {0}; // if empty, the compile-time WIFI_SSID is used
char wifi_pwd[64] = {0};
uint8_t wifi_enabled = 1; // enabled by default to allow wifi only builds to work. wifi won't be started if ssid is empty
// use ssid from prefs, or fallback to ssid from build flags
const char* getWifiSSID() const { return wifi_ssid[0] ? wifi_ssid : WIFI_SSID; }
#endif
private:
class RadioPrefs : public CommonRadioPrefs {
@@ -164,6 +174,21 @@ private:
DynamicConfigSerializer custom;
#ifdef ENABLE_WIFI_INTERFACE
class WiFiPrefs : public ConfigSerializer {
NodePrefs* _parent;
protected:
void structure() override {
def("ssid", _parent->wifi_ssid, sizeof(_parent->wifi_ssid));
def("pwd", _parent->wifi_pwd, sizeof(_parent->wifi_pwd));
def("enabled", _parent->wifi_enabled);
}
public:
WiFiPrefs(NodePrefs* parent) : _parent(parent) { }
};
WiFiPrefs wifi;
#endif
protected:
void structure() override {
def("name", node_name, sizeof(node_name));
@@ -176,9 +201,16 @@ protected:
def("repeat", repeat);
def("comp", companion);
def("custom", custom);
#ifdef ENABLE_WIFI_INTERFACE
def("wifi", wifi);
#endif
}
public:
NodePrefs() : radio(this), gps(this), companion(this), custom(&radio) {
NodePrefs() : radio(this), gps(this), companion(this), custom(&radio)
#ifdef ENABLE_WIFI_INTERFACE
, wifi(this)
#endif
{
node_name[0] = 0;
default_scope_name[0] = 0;
memset(default_scope_key, 0, sizeof(default_scope_key));
+94 -27
View File
@@ -26,19 +26,38 @@ MultiSerialInterface interface_manager;
// include nrf52 bluetooth interface
#include <helpers/nrf52/SerialBLEInterface.h>
SerialBLEInterface bluetooth_interface;
#elif defined(RP2040_PLATFORM)
// include rp2040 (Pico W / CYW43) bluetooth interface
#include <helpers/rp2040/SerialBLEInterface.h>
SerialBLEInterface bluetooth_interface;
#else
#error "SerialBLEInterface is not defined for this platform"
#endif
#endif
// include wifi interface
#ifdef WIFI_SSID
#ifdef ENABLE_WIFI_INTERFACE
#ifndef WIFI_SSID
#define WIFI_SSID ""
#endif
#ifndef WIFI_PWD
#define WIFI_PWD ""
#endif
#ifndef TCP_PORT
#define TCP_PORT 5000
#endif
#ifdef ESP32
// include esp32 wifi interface
#include <helpers/esp32/SerialWifiInterface.h>
#ifndef WIFI_RETRY_INTERVAL
#if defined(RP2040_PLATFORM)
#define WIFI_RETRY_INTERVAL 30000 // each attempt blocks loop(), so retry less often
#else
#define WIFI_RETRY_INTERVAL 10000 // millis between reconnect attempts
#endif
#endif
#ifndef WIFI_RETRY_TIMEOUT
#define WIFI_RETRY_TIMEOUT 5000 // RP2040: cap on how long one join may block loop()
#endif
#if defined(ESP32) || defined(RP2040_PLATFORM)
#include <helpers/wifi/SerialWifiInterface.h>
SerialWifiInterface wifi_interface;
#else
#error "SerialWifiInterface is not defined for this platform"
@@ -108,9 +127,13 @@ void halt() {
}
/* WIFI RECONNECT TRACKERS */
#if defined(ESP32) && defined(WIFI_SSID)
#ifdef ENABLE_WIFI_INTERFACE
bool wifi_needs_reconnect = false;
unsigned long last_wifi_reconnect_attempt = 0;
char wifi_ssid[33] = WIFI_SSID; // replaced by stored prefs at boot, if set
char wifi_pwd[64] = WIFI_PWD;
bool wifi_was_connected = false;
bool wifi_enabled = false; // set at boot from prefs; false also when the effective SSID is blank
#endif
void setup() {
@@ -191,23 +214,46 @@ void setup() {
#endif
// add wifi interface
#ifdef WIFI_SSID
board.setInhibitSleep(true); // prevent sleep when WiFi is active
WiFi.setAutoReconnect(true);
#ifdef ENABLE_WIFI_INTERFACE
// use wifi ssid and password from prefs if ssid is not empty, otherwise use the build flag defaults
if (the_mesh.getNodePrefs()->wifi_ssid[0]) {
strcpy(wifi_ssid, the_mesh.getNodePrefs()->wifi_ssid);
strcpy(wifi_pwd, the_mesh.getNodePrefs()->wifi_pwd);
}
// only start wifi if enabled and ssid is not empty
wifi_enabled = the_mesh.getNodePrefs()->wifi_enabled;
if (wifi_enabled && wifi_ssid[0]) {
#if defined(ESP32)
board.setInhibitSleep(true); // prevent sleep when WiFi is active
WiFi.setAutoReconnect(true);
WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){
if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
WIFI_DEBUG_PRINTLN("WiFi disconnected. Flagging for reconnect...");
wifi_needs_reconnect = true;
} else if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
WIFI_DEBUG_PRINTLN("WiFi connected successfully!");
wifi_needs_reconnect = false;
}
});
WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){
if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
WIFI_DEBUG_PRINTLN("WiFi disconnected. Flagging for reconnect...");
wifi_needs_reconnect = true;
} else if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
WIFI_DEBUG_PRINTLN("WiFi connected successfully!");
wifi_needs_reconnect = false;
}
});
#endif
WiFi.begin(WIFI_SSID, WIFI_PWD);
wifi_interface.begin(TCP_PORT);
interface_manager.addInterface(InterfaceType::WiFi, &wifi_interface);
WIFI_DEBUG_PRINTLN("connecting to %s", wifi_ssid);
#if defined(RP2040_PLATFORM)
// the join itself blocks inside the core (CYW43::begin busy-waits for the
// association), so every attempt stalls the mesh loop. beginNoBlock() only skips the
// extra DHCP wait. Give the first connect a full window, then bound the retries below.
WiFi.beginNoBlock(wifi_ssid, wifi_pwd);
last_wifi_reconnect_attempt = millis(); // let DHCP finish before the poll can retry
#else
WiFi.begin(wifi_ssid, wifi_pwd);
#endif
wifi_interface.begin(TCP_PORT);
interface_manager.addInterface(InterfaceType::WiFi, &wifi_interface);
} else {
WIFI_DEBUG_PRINTLN("wifi disabled");
}
#endif
// add usb interface
@@ -262,13 +308,34 @@ void loop() {
#endif
}
#if defined(ESP32) && defined(WIFI_SSID)
// Safely attempt to reconnect every 10 seconds if flagged
if (wifi_needs_reconnect && (millis() - last_wifi_reconnect_attempt > 10000)) {
WIFI_DEBUG_PRINTLN("Attempting manual WiFi reconnect...");
WiFi.disconnect();
WiFi.reconnect();
last_wifi_reconnect_attempt = millis();
#ifdef ENABLE_WIFI_INTERFACE
if (wifi_enabled) {
// RP2040 has no WiFi event callbacks, so poll the link state instead
#if defined(RP2040_PLATFORM)
wifi_needs_reconnect = (WiFi.status() != WL_CONNECTED);
if (wifi_was_connected == wifi_needs_reconnect) { // link state changed
wifi_was_connected = !wifi_needs_reconnect;
if (wifi_was_connected) {
WIFI_DEBUG_PRINTLN("connected, listening on %s:%d", WiFi.localIP().toString().c_str(), TCP_PORT);
} else {
WIFI_DEBUG_PRINTLN("link lost");
}
}
#endif
// Safely attempt to reconnect if flagged. On RP2040 each attempt blocks the mesh loop
// for up to WIFI_RETRY_TIMEOUT, so retry less often and cap how long a join may stall.
if (wifi_needs_reconnect && (millis() - last_wifi_reconnect_attempt > WIFI_RETRY_INTERVAL)) {
WIFI_DEBUG_PRINTLN("Attempting manual WiFi reconnect to %s (status %d)...", wifi_ssid, WiFi.status());
#if defined(RP2040_PLATFORM)
WiFi.setTimeout(WIFI_RETRY_TIMEOUT);
WiFi.beginNoBlock(wifi_ssid, wifi_pwd); // no reconnect() on this platform
#else
WiFi.disconnect();
WiFi.reconnect();
#endif
last_wifi_reconnect_attempt = millis();
}
}
#endif
}
+2 -2
View File
@@ -3,7 +3,7 @@
#include "../MyMesh.h"
#include "target.h"
#include <time.h>
#ifdef WIFI_SSID
#ifdef ENABLE_WIFI_INTERFACE
#include <WiFi.h>
#endif
@@ -260,7 +260,7 @@ public:
sprintf(tmp, "%02d/%02d/%d", dt.day(), dt.month(), dt.year());
display.drawTextCentered(display.width() / 2, 80, tmp);
#endif
#ifdef WIFI_SSID
#ifdef ENABLE_WIFI_INTERFACE
IPAddress ip = WiFi.localIP();
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
display.setTextSize(1);
+2 -2
View File
@@ -4,7 +4,7 @@
#include "target.h"
#include "u8g2_icons.h"
#ifdef WIFI_SSID
#ifdef ENABLE_WIFI_INTERFACE
#include <WiFi.h>
#endif
@@ -173,7 +173,7 @@ public:
display.setCursor(0, 19);
display.print(tmp);
#ifdef WIFI_SSID
#ifdef ENABLE_WIFI_INTERFACE
IPAddress ip = WiFi.localIP();
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
display.setTextSize(1);
+2
View File
@@ -1,4 +1,5 @@
#include "ConfigSerializer.h"
#include <stdlib.h> // atoi/atol/atof (Arduino.h pulls this in on-device, native builds do not)
bool ConfigSerializer::saveSerial(Stream& s) {
Context context(&s, OP::WRITE);
@@ -62,6 +63,7 @@ int ConfigSerializer::Context::readNext() {
case EXPECT_COMMA_OR_KEY:
if (c == ',') { rd_mode = EXPECT_KEY; return TOK_WHITESPACE; }
case EXPECT_KEY:
if (rd_len == 0 && c == '}') { rd_mode = EXPECT_COMMA_OR_KEY_OR_CLOSE; return TOK_END_OBJ; } // empty object, eg. 'custom:{}'
if (rd_len > 0 && c == ':') { rd_buf[rd_len] = 0; rd_len = 0; rd_mode = EXPECT_VAL_OR_OBJ; return TOK_KEY; }
if (rd_len == 0 && is_whitespace(c)) return TOK_WHITESPACE;
if (rd_len < CONFIG_MAX_KEYLEN-1 && is_key_char(c)) { rd_buf[rd_len++] = c; return TOK_WHITESPACE; }
+201
View File
@@ -0,0 +1,201 @@
// only built when the env enables the core BLE stack (build_as_lib.py globs this dir)
#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH
#include "SerialBLEInterface.h"
#include <BluetoothLock.h>
#include <stdio.h>
#include <string.h>
// Nordic UART 6E4000xx-B5A3-F393-E0A9-E50E24DCCA9E, as raw bytes: the core lib's string
// parser uses sscanf("%llx"), which newlib-nano on the RP2040 doesn't support (yields all zeros)
#define NUS_UUID(n) { 0x6E, 0x40, 0x00, n, 0xB5, 0xA3, 0xF3, 0x93, 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E }
static const uint8_t SERVICE_UUID[16] = NUS_UUID(0x01);
static const uint8_t CHARACTERISTIC_UUID_RX[16] = NUS_UUID(0x02);
static const uint8_t CHARACTERISTIC_UUID_TX[16] = NUS_UUID(0x03);
// The BLE core lib's own setValue()/notify path reallocs the value buffer on every call,
// so a second frame queued before the radio drained the first would corrupt it. We keep our
// own frame queue and drive att_server_notify() from the can-send-now callback instead.
SerialBLEInterface::SerialBLEInterface()
: BLEService(BLEUUID(SERVICE_UUID)),
_rx(BLEUUID(CHARACTERISTIC_UUID_RX), BLEWrite, nullptr, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED),
_tx(BLEUUID(CHARACTERISTIC_UUID_TX), BLERead | BLENotify, nullptr, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED)
{
_isEnabled = false;
_tx_pending = false;
send_queue_len = 0;
recv_queue_len = 0;
memset(&_can_send, 0, sizeof(_can_send));
_rx.setCallbacks(this);
addCharacteristic(&_rx);
addCharacteristic(&_tx);
}
void SerialBLEInterface::begin(const char* prefix, char* name, uint32_t pin_code) {
// JustWorks here only makes the server request pairing on connect; caps are overridden below
BLE.setSecurity(BLESecurityJustWorks);
// adv data carries the 128-bit service UUID, leaving room for only 8 name chars;
// the full name goes in the scan response
BLE.begin(prefix);
if (strcmp(name, "@@MAC") == 0) {
bd_addr_t a;
gap_local_bd_addr(a);
sprintf(name, "%02X%02X%02X%02X%02X%02X", a[0], a[1], a[2], a[3], a[4], a[5]); // modify (IN-OUT param)
}
char dev_name[32+16];
snprintf(dev_name, sizeof(dev_name), "%s%s", prefix, name);
BLE.server()->setName(dev_name); // GAP device name characteristic
BLE.server()->addService(this);
BLE.server()->setCallbacks(this);
// static passkey pairing with MITM protection, matching the esp32/nrf52 interfaces
sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY);
sm_set_authentication_requirements(SM_AUTHREQ_MITM_PROTECTION | SM_AUTHREQ_BONDING);
sm_use_fixed_passkey_in_display_role(pin_code);
size_t n = strlen(dev_name);
if (n > sizeof(_scan_rsp) - 2) n = sizeof(_scan_rsp) - 2;
_scan_rsp[0] = n + 1;
_scan_rsp[1] = BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME;
memcpy(&_scan_rsp[2], dev_name, n);
gap_scan_response_set_data(n + 2, _scan_rsp);
BLE_DEBUG_PRINTLN("begin: name=%s", dev_name);
}
void SerialBLEInterface::clearBuffers() {
send_queue_len = 0;
recv_queue_len = 0;
_tx_pending = false; // a stale registration just fires into an empty queue; BTstack ignores double-adds
}
void SerialBLEInterface::onConnect(BLEServer* s) {
BLE_DEBUG_PRINTLN("connected handle=0x%04X", _tx.conHandle());
clearBuffers();
}
void SerialBLEInterface::onDisconnect(BLEServer* s) {
BLE_DEBUG_PRINTLN("disconnected");
clearBuffers(); // BTstack re-enables advertising on its own
}
void SerialBLEInterface::onWrite(BLECharacteristic* c) {
if (c != &_rx) return;
size_t len = _rx.valueLen();
if (len == 0 || len > MAX_FRAME_SIZE) {
BLE_DEBUG_PRINTLN("onWrite: bad frame len=%u", (unsigned)len);
return;
}
if (recv_queue_len >= FRAME_QUEUE_SIZE) {
BLE_DEBUG_PRINTLN("onWrite: recv queue full, dropping frame");
return;
}
recv_queue[recv_queue_len].len = len;
memcpy(recv_queue[recv_queue_len].buf, _rx.valueData(), len);
recv_queue_len++;
}
// caller holds the BT lock (or is in the BT context)
void SerialBLEInterface::kickSend() {
if (_tx_pending) return;
_tx_pending = true;
_can_send.callback = onCanSend;
_can_send.context = this;
if (att_server_register_can_send_now_callback(&_can_send, _tx.conHandle()) != 0) {
_tx_pending = false;
}
}
// BT context: one notification per can-send-now, re-arm while frames remain
void SerialBLEInterface::sendNext() {
_tx_pending = false;
if (send_queue_len == 0) return;
if (!isConnected()) {
BLE_DEBUG_PRINTLN("sendNext: not connected, clearing send queue");
send_queue_len = 0;
return;
}
uint16_t h = _tx.conHandle();
Frame& f = send_queue[0];
uint16_t mtu = att_server_get_mtu(h);
if (f.len + 3 > mtu) {
// att would silently truncate; drop instead (client must negotiate MTU >= MAX_FRAME_SIZE+3)
BLE_DEBUG_PRINTLN("sendNext: frame len=%u exceeds mtu=%u, dropping", f.len, mtu);
} else {
uint8_t err = att_server_notify(h, _tx.valueHandle(), f.buf, f.len);
if (err == BTSTACK_ACL_BUFFERS_FULL) {
kickSend();
return;
}
if (err) {
BLE_DEBUG_PRINTLN("sendNext: notify failed err=%u, dropping", err);
} else {
BLE_DEBUG_PRINTLN("writeBytes: sz=%u, hdr=%u", f.len, f.buf[0]);
}
}
send_queue_len--;
memmove(&send_queue[0], &send_queue[1], send_queue_len * sizeof(Frame));
if (send_queue_len > 0) kickSend();
}
void SerialBLEInterface::enable() {
if (_isEnabled) return;
_isEnabled = true;
clearBuffers();
BLE.startAdvertising(true);
}
void SerialBLEInterface::disconnect() {
uint16_t h = _tx.conHandle();
if (h) gap_disconnect(h);
}
void SerialBLEInterface::disable() {
_isEnabled = false;
BLE_DEBUG_PRINTLN("disable");
disconnect();
BLE.stopAdvertising();
}
bool SerialBLEInterface::isConnected() const {
// notifications can only be enabled once the link is authenticated (CCCD inherits the perms)
return _isEnabled && _tx.conHandle() != 0 && _tx.notifyEnabled();
}
bool SerialBLEInterface::isWriteBusy() const {
return send_queue_len >= (FRAME_QUEUE_SIZE * 2 / 3);
}
size_t SerialBLEInterface::writeFrame(const uint8_t src[], size_t len) {
if (len == 0 || len > MAX_FRAME_SIZE) {
BLE_DEBUG_PRINTLN("writeFrame(), frame too big, len=%u", (unsigned)len);
return 0;
}
if (!isConnected()) return 0;
BluetoothLock lock;
if (send_queue_len >= FRAME_QUEUE_SIZE) {
BLE_DEBUG_PRINTLN("writeFrame(), send_queue is full!");
return 0;
}
send_queue[send_queue_len].len = len;
memcpy(send_queue[send_queue_len].buf, src, len);
send_queue_len++;
kickSend();
return len;
}
size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) {
BluetoothLock lock;
if (recv_queue_len == 0) return 0;
size_t len = recv_queue[0].len;
memcpy(dest, recv_queue[0].buf, len);
recv_queue_len--;
memmove(&recv_queue[0], &recv_queue[1], recv_queue_len * sizeof(Frame));
BLE_DEBUG_PRINTLN("readBytes: sz=%u, hdr=%u", (unsigned)len, dest[0]);
return len;
}
#endif
+75
View File
@@ -0,0 +1,75 @@
#pragma once
#include "../BaseSerialInterface.h"
#include <BLE.h>
#include <btstack.h>
// Nordic UART service over the arduino-pico BLE library (BTstack on the CYW43).
// Build with -D PIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH so the core links liblwip-bt.
class SerialBLEInterface : public BaseSerialInterface, BLEService, BLEServerCallbacks, BLECharacteristicCallbacks {
// subclass only to reach the protected connection/notify state
struct Characteristic : public BLECharacteristic {
using BLECharacteristic::BLECharacteristic;
uint16_t valueHandle() const { return _valueHandle; }
uint16_t conHandle() const { return con_handle; }
bool notifyEnabled() const { return _notificationEnabled; }
};
struct Frame {
uint8_t len;
uint8_t buf[MAX_FRAME_SIZE];
};
#define FRAME_QUEUE_SIZE 8
Characteristic _rx;
Characteristic _tx;
bool _isEnabled;
bool _tx_pending; // a can-send-now callback is registered
btstack_context_callback_registration_t _can_send;
uint8_t _scan_rsp[31]; // complete local name; BTstack keeps the pointer
uint8_t send_queue_len;
Frame send_queue[FRAME_QUEUE_SIZE];
uint8_t recv_queue_len;
Frame recv_queue[FRAME_QUEUE_SIZE];
void clearBuffers();
void kickSend();
void sendNext();
static void onCanSend(void* ctx) { ((SerialBLEInterface*)ctx)->sendNext(); }
// BLE library callbacks (run in the BT context)
void onWrite(BLECharacteristic* c) override;
void onConnect(BLEServer* s) override;
void onDisconnect(BLEServer* s) override;
public:
SerialBLEInterface();
/**
* init the BLE interface.
* @param prefix a prefix for the device name
* @param name IN/OUT - a name for the device (combined with prefix). If "@@MAC", is modified and returned
* @param pin_code the BLE security pin
*/
void begin(const char* prefix, char* name, uint32_t pin_code);
void disconnect();
void enable() override;
void disable() override;
bool isEnabled() const override { return _isEnabled; }
bool isConnected() const override;
bool isWriteBusy() const override;
size_t writeFrame(const uint8_t src[], size_t len) override;
size_t checkRecvFrame(uint8_t dest[]) override;
};
#if BLE_DEBUG_LOGGING && ARDUINO
#include <Arduino.h>
#define BLE_DEBUG_PRINT(F, ...) Serial.printf("BLE: " F, ##__VA_ARGS__)
#define BLE_DEBUG_PRINTLN(F, ...) Serial.printf("BLE: " F "\n", ##__VA_ARGS__)
#else
#define BLE_DEBUG_PRINT(...) {}
#define BLE_DEBUG_PRINTLN(...) {}
#endif
@@ -185,6 +185,47 @@ TEST(ConfigSerializer, LoadSerial_IgnoreUnknowns) {
EXPECT_TRUE(match);
}
class TestNested : public ConfigSerializer {
class Inner : public ConfigSerializer {
protected:
void structure() override { } // no properties, so it writes as '{}'
};
Inner inner;
protected:
void structure() override {
def("age", age);
def("inner", inner);
def("name", name, sizeof(name)); // comes *after* the empty sub-object
}
public:
int32_t age;
char name[16];
};
TEST(ConfigSerializer, LoadSerial_EmptyObject) {
MockInputStream s("{age:" TEST_INT_S ",inner:{},name:\"Scott\"}");
TestNested data;
data.name[0] = 0;
bool success = data.loadSerial(s);
EXPECT_TRUE(success);
EXPECT_EQ(TEST_INT, data.age);
bool match = strcmp("Scott", data.name) == 0;
EXPECT_TRUE(match); // properties after an empty object must still load
}
TEST(ConfigSerializer, LoadSerial_EmptyObjectWithWhitespace) {
MockInputStream s("{age:" TEST_INT_S ",inner:{ },name:\"Scott\"}");
TestNested data;
data.name[0] = 0;
bool success = data.loadSerial(s);
EXPECT_TRUE(success);
bool match = strcmp("Scott", data.name) == 0;
EXPECT_TRUE(match);
}
TEST(DynamicConfigSerializer, GetSet_Basic) {
DynamicConfigSerializer data;
+4
View File
@@ -173,6 +173,7 @@ extends = Heltec_RC32
build_flags =
${Heltec_RC32.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D DISPLAY_CLASS=NullDisplayDriver
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -185,6 +186,7 @@ build_src_filter = ${Heltec_RC32.build_src_filter}
+<helpers/ui/buzzer.cpp>
+<helpers/ui/NullDisplayDriver.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
@@ -314,6 +316,7 @@ extends = Heltec_RC32_with_display
build_flags =
${Heltec_RC32_with_display.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D UI_HAS_ROTARY_INPUT
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -324,6 +327,7 @@ build_flags =
build_src_filter = ${Heltec_RC32_with_display.build_src_filter}
+<helpers/ui/buzzer.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
@@ -182,6 +182,7 @@ extends = Heltec_tracker_v2
build_flags =
${Heltec_tracker_v2.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=ST7735Display
@@ -195,6 +196,7 @@ build_src_filter = ${Heltec_tracker_v2.build_src_filter}
+<helpers/ui/ST7735Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
+2
View File
@@ -178,6 +178,7 @@ extends = Heltec_lora32_v2
build_flags =
${Heltec_lora32_v2.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D DISPLAY_CLASS=SSD1306Display
-D MAX_CONTACTS=160
-D MAX_GROUP_CHANNELS=8
@@ -189,6 +190,7 @@ build_flags =
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v2.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<helpers/ui/SSD1306Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<../examples/companion_radio/*.cpp>
+4
View File
@@ -185,6 +185,7 @@ extends = Heltec_lora32_v3
build_flags =
${Heltec_lora32_v3.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=SSD1306Display
@@ -198,6 +199,7 @@ build_src_filter = ${Heltec_lora32_v3.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
@@ -340,6 +342,7 @@ lib_deps =
extends = Heltec_lora32_v3
build_flags =
${Heltec_lora32_v3.build_flags}
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D WIFI_DEBUG_LOGGING=1
@@ -350,6 +353,7 @@ build_flags =
; -D MESH_DEBUG=1
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps =
${Heltec_lora32_v3.lib_deps}
+4
View File
@@ -228,6 +228,7 @@ extends = heltec_v4_oled
build_flags =
${heltec_v4_oled.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -241,6 +242,7 @@ build_src_filter = ${heltec_v4_oled.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
@@ -393,6 +395,7 @@ extends = heltec_v4_tft
build_flags =
${heltec_v4_tft.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -406,6 +409,7 @@ build_src_filter = ${heltec_v4_tft.build_src_filter}
+<helpers/ui/ST7789LCDDisplay.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
+4
View File
@@ -175,6 +175,7 @@ extends = heltec_v4_r8_oled
build_flags =
${heltec_v4_r8_oled.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -186,6 +187,7 @@ build_src_filter = ${heltec_v4_r8_oled.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
@@ -300,6 +302,7 @@ extends = heltec_v4_r8_tft
build_flags =
${heltec_v4_r8_tft.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -311,6 +314,7 @@ build_src_filter = ${heltec_v4_r8_tft.build_src_filter}
+<helpers/ui/ST7789LCDDisplay.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
+2
View File
@@ -153,6 +153,7 @@ extends = LilyGo_TBeam_1W
build_flags =
${LilyGo_TBeam_1W.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -165,6 +166,7 @@ build_flags =
; -D MESH_DEBUG=1
build_src_filter = ${LilyGo_TBeam_1W.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
@@ -148,6 +148,7 @@ extends = T_Beam_S3_Supreme_SX1262
build_flags =
${T_Beam_S3_Supreme_SX1262.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -160,6 +161,7 @@ build_flags =
; -D CORE_DEBUG_LEVEL=4
build_src_filter = ${T_Beam_S3_Supreme_SX1262.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
@@ -132,6 +132,7 @@ extends = LilyGo_TLora_V2_1_1_6
build_flags =
${LilyGo_TLora_V2_1_1_6.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=160
-D MAX_GROUP_CHANNELS=8
-D WIFI_SSID='"ssid"'
@@ -140,6 +141,7 @@ build_flags =
-D OFFLINE_QUEUE_SIZE=128
build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
+2
View File
@@ -171,6 +171,7 @@ extends = meshnology_w12
build_flags =
${meshnology_w12.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -184,6 +185,7 @@ build_src_filter = ${meshnology_w12.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
@@ -143,6 +143,7 @@ extends = nibble_screen_connect_base
build_flags =
${nibble_screen_connect_base.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D DISPLAY_CLASS=SSD1306Display
-D MAX_CONTACTS=300
-D MAX_GROUP_CHANNELS=8
@@ -154,6 +155,7 @@ build_src_filter = ${nibble_screen_connect_base.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
@@ -140,6 +140,7 @@ extends = nibble_zero_connect_base
build_flags =
${nibble_zero_connect_base.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D DISPLAY_CLASS=SSD1306Display
-D MAX_CONTACTS=300
-D MAX_GROUP_CHANNELS=8
@@ -150,6 +151,7 @@ build_src_filter = ${nibble_zero_connect_base.build_src_filter}
+<helpers/ui/SSD1306Display.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
+2
View File
@@ -172,6 +172,7 @@ extends = rak3112
build_flags =
${rak3112.build_flags}
-I examples/companion_radio/ui-orig
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D WIFI_DEBUG_LOGGING=1
@@ -182,6 +183,7 @@ build_flags =
; -D MESH_DEBUG=1
build_src_filter = ${rak3112.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-orig/*.cpp>
lib_deps =
+53 -27
View File
@@ -67,34 +67,60 @@ lib_deps = ${rpi_picow.lib_deps}
densaugeo/base64 @ ~1.4.0
lib_ignore = BLE
; [env:PicoW_companion_radio_ble]
; extends = rpi_picow
; build_flags = ${rpi_picow.build_flags}
; -D MAX_CONTACTS=100
; -D MAX_GROUP_CHANNELS=8
; -D BLE_PIN_CODE=123456
; -D BLE_DEBUG_LOGGING=1
; ; -D MESH_PACKET_LOGGING=1
; ; -D MESH_DEBUG=1
; build_src_filter = ${rpi_picow.build_src_filter}
; +<../examples/companion_radio/*.cpp>
; lib_deps = ${rpi_picow.lib_deps}
; densaugeo/base64 @ ~1.4.0
[env:PicoW_companion_radio_ble]
extends = rpi_picow
build_flags = ${rpi_picow.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D PIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${rpi_picow.build_src_filter}
+<helpers/rp2040/SerialBLEInterface.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps = ${rpi_picow.lib_deps}
densaugeo/base64 @ ~1.4.0
; [env:PicoW_companion_radio_wifi]
; extends = rpi_picow
; build_flags = ${rpi_picow.build_flags}
; -D MAX_CONTACTS=100
; -D MAX_GROUP_CHANNELS=8
; -D WIFI_DEBUG_LOGGING=1
; -D WIFI_SSID='"myssid"'
; -D WIFI_PWD='"mypwd"'
; ; -D MESH_PACKET_LOGGING=1
; ; -D MESH_DEBUG=1
; build_src_filter = ${rpi_picow.build_src_filter}
; +<../examples/companion_radio/*.cpp>
; lib_deps = ${rpi_picow.lib_deps}
; densaugeo/base64 @ ~1.4.0
; USB + WiFi + BLE together; the interface manager fans frames out to all of them
[env:PicoW_companion_radio]
extends = rpi_picow
build_flags = ${rpi_picow.build_flags}
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D ENABLE_USB_INTERFACE
-D ENABLE_WIFI_INTERFACE
-D PIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH
-D BLE_PIN_CODE=123456
; NOTE: DO NOT ENABLE --> -D BLE_DEBUG_LOGGING=1 (shares Serial with the USB interface)
; NOTE: DO NOT ENABLE --> -D WIFI_DEBUG_LOGGING=1
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${rpi_picow.build_src_filter}
+<helpers/rp2040/SerialBLEInterface.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps = ${rpi_picow.lib_deps}
densaugeo/base64 @ ~1.4.0
[env:PicoW_companion_radio_wifi]
extends = rpi_picow
build_flags = ${rpi_picow.build_flags}
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D WIFI_DEBUG_LOGGING=1
-D WIFI_SSID='""' ; no default network, configure with 'set wifi.ssid' / 'set wifi.pwd'
-D WIFI_PWD='""'
; -D MESH_PACKET_LOGGING=1
; -D MESH_DEBUG=1
build_src_filter = ${rpi_picow.build_src_filter}
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
lib_deps = ${rpi_picow.lib_deps}
densaugeo/base64 @ ~1.4.0
lib_ignore = BLE
[env:PicoW_terminal_chat]
extends = rpi_picow
+2
View File
@@ -224,6 +224,7 @@ extends = Station_G2
build_flags =
${Station_G2.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D WIFI_DEBUG_LOGGING=1
@@ -234,6 +235,7 @@ build_flags =
; -D MESH_DEBUG=1
build_src_filter = ${Station_G2.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
+2
View File
@@ -139,6 +139,7 @@ extends = Station_G3_ESP32
build_flags =
${Station_G3_ESP32.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D WIFI_DEBUG_LOGGING=1
@@ -149,6 +150,7 @@ build_flags =
; -D MESH_DEBUG=1
build_src_filter = ${Station_G3_ESP32.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
lib_deps =
+2
View File
@@ -176,6 +176,7 @@ extends = ThinkNode_M2
build_flags =
${ThinkNode_M2.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -184,6 +185,7 @@ build_flags =
-D WIFI_PWD='"mypwd"'
build_src_filter = ${ThinkNode_M2.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/ui/buzzer.cpp>
+<../examples/companion_radio/*.cpp>
+2
View File
@@ -190,6 +190,7 @@ extends = ThinkNode_M5
build_flags =
${ThinkNode_M5.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
@@ -198,6 +199,7 @@ build_flags =
-D WIFI_PWD='"mypwd"'
build_src_filter = ${ThinkNode_M5.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<../examples/companion_radio/*.cpp>
+<../examples/companion_radio/ui-new/*.cpp>
+2
View File
@@ -135,6 +135,7 @@ extends = ThinkNode_M7
build_flags =
${ThinkNode_M7.build_flags}
-I examples/companion_radio/ui-orig
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D DISPLAY_CLASS=NullDisplayDriver
@@ -145,6 +146,7 @@ build_flags =
; -D MESH_PACKET_LOGGING=1
build_src_filter = ${ThinkNode_M7.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<helpers/ui/NullDisplayDriver.cpp>
+<../examples/companion_radio/*.cpp>
+2
View File
@@ -137,6 +137,7 @@ extends = ThinkNode_M9
build_flags =
${ThinkNode_M9.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D WIFI_DEBUG_LOGGING=1
@@ -146,6 +147,7 @@ build_flags =
; -D MESH_PACKET_LOGGING=1
build_src_filter = ${ThinkNode_M9.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<helpers/ui/buzzer.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<../examples/companion_radio/*.cpp>
+2
View File
@@ -115,8 +115,10 @@ extends = Xiao_esp32_C3
build_src_filter = ${Xiao_esp32_C3.build_src_filter}
+<../examples/companion_radio/*.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
build_flags =
${Xiao_esp32_C3.build_flags}
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256
+2
View File
@@ -202,11 +202,13 @@ extends = Xiao_S3_WIO
build_src_filter = ${Xiao_S3_WIO.build_src_filter}
+<helpers/ui/NullDisplayDriver.cpp>
+<helpers/esp32/*.cpp>
+<helpers/wifi/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
+<../examples/companion_radio/*.cpp>
build_flags =
${Xiao_S3_WIO.build_flags}
-I examples/companion_radio/ui-new
-D ENABLE_WIFI_INTERFACE
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-D OFFLINE_QUEUE_SIZE=256