Unify full firmware profiles and add dual USB logging

This commit is contained in:
mikecarper committed 2026-08-23 19:22:45 -07:00
1 parent b699e552ec
commit f2d4ffbb7e
56 files changed
+1652 -361

No files matched your search

+7
View File
@@ -349,6 +349,10 @@ void DataStore::loadPrefsInt(const char *filename, CompanionNodePrefs& _prefs, d
if (file.available() >= (int)sizeof(_prefs.powersaving_policy_version)) {
file.read((uint8_t *)&_prefs.powersaving_policy_version,
sizeof(_prefs.powersaving_policy_version)); // 139
if (file.available() >= (int)sizeof(_prefs.usb_logging_enabled)) {
file.read((uint8_t *)&_prefs.usb_logging_enabled,
sizeof(_prefs.usb_logging_enabled)); // 140
}
}
}
}
@@ -421,6 +425,9 @@ bool DataStore::savePrefs(const CompanionNodePrefs& _prefs, double node_lat, dou
success = success && file.write((uint8_t *)&_prefs.powersaving_policy_version,
sizeof(_prefs.powersaving_policy_version))
== sizeof(_prefs.powersaving_policy_version); // 139
success = success && file.write((uint8_t *)&_prefs.usb_logging_enabled,
sizeof(_prefs.usb_logging_enabled))
== sizeof(_prefs.usb_logging_enabled); // 140
#if defined(NRF52_PLATFORM)
success = file.commit(success);
+16 -4
View File
@@ -1437,6 +1437,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
_prefs.powersaving_enabled = 1;
_prefs.powersaving_policy_version = 0;
_prefs.wifi_enabled = 1;
_prefs.usb_logging_enabled = 1;
recalcRxPowerSavingFromLevel(_prefs.rx_ps_level, _prefs.sf, _prefs.bw,
_prefs.rx_ps_preamble, &_prefs.rx_ps_rx_us,
&_prefs.rx_ps_sleep_us);
@@ -1531,6 +1532,7 @@ void MyMesh::begin(bool has_display, bool radio_available) {
_prefs.rx_powersaving_enabled = constrain(_prefs.rx_powersaving_enabled, 0, 1);
_prefs.powersaving_enabled = constrain(_prefs.powersaving_enabled, 0, 1);
_prefs.wifi_enabled = constrain(_prefs.wifi_enabled, 0, 1);
_prefs.usb_logging_enabled = constrain(_prefs.usb_logging_enabled, 0, 1);
_prefs.rx_ps_level = constrain(_prefs.rx_ps_level, 0, 10);
if (_prefs.rx_ps_preamble != 16 && _prefs.rx_ps_preamble != 32) {
_prefs.rx_ps_preamble = 0;
@@ -1542,6 +1544,9 @@ void MyMesh::begin(bool has_display, bool radio_available) {
if (power_saving_default_migrated) {
_store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon);
}
#if MESH_USB_LOGGING_AVAILABLE
mesh::setUsbLoggingEnabled(_prefs.usb_logging_enabled != 0);
#endif
#ifdef BLE_PIN_CODE // 123456 by default
if (_prefs.ble_pin == 0) {
@@ -2085,9 +2090,10 @@ void MyMesh::serviceMQTT(const char* wifi_ssid, const char* wifi_password) {
_mqtt_started = true; // begin is one-shot; avoid retrying partial allocations
_mqtt_bridge->begin();
if (_mqtt_bridge->isRunning()) {
Serial.println("MQTT companion: bridge started");
mesh::usbLoggingPort().println("MQTT companion: bridge started");
} else {
Serial.println("MQTT companion: bridge could not start");
mesh::usbLoggingPort().println(
"MQTT companion: bridge could not start");
}
}
}
@@ -4976,9 +4982,15 @@ void MyMesh::handleTerminalCommand(char* command) {
terminalOutput().print(" ERROR: use set usb.logging <on|off>\r\n");
} else {
const bool enabled = strcmp(value, "on") == 0;
_prefs.usb_logging_enabled = enabled ? 1 : 0;
mesh::setUsbLoggingEnabled(enabled);
terminalOutput().printf(" OK - USB logging %s until reboot\r\n",
enabled ? "on" : "off");
if (savePrefs()) {
terminalOutput().printf(" OK - USB logging %s (saved)\r\n",
enabled ? "on" : "off");
} else {
terminalOutput().print(
" ERROR: USB logging changed for this boot but save failed\r\n");
}
}
} else
#endif
+3 -1
View File
@@ -263,7 +263,9 @@ protected:
}
public:
void savePrefs() { _store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon); }
bool savePrefs() {
return _store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon);
}
#if ENV_INCLUDE_GPS == 1
void applyGpsPrefs() {
+1
View File
@@ -53,6 +53,7 @@ struct CompanionNodePrefs { // persisted to file
uint8_t powersaving_enabled; // device CPU/GPS idle power saving
uint8_t wifi_enabled; // Companion WiFi radio and services
uint8_t powersaving_policy_version; // one-time default migration marker
uint8_t usb_logging_enabled; // live USB packet/debug output
// Keep the upstream repeat API while retaining the existing binary prefs
// layout used by this branch.
+28 -21
View File
@@ -153,16 +153,17 @@ static void serviceCompanionRadioRecovery() {
|| (long)(millis() - companion_radio_retry_at) < 0) return;
companion_radio_retry_at = millis() + COMPANION_RADIO_RETRY_MS;
Serial.println("Radio recovery probe starting");
mesh::usbLoggingPort().println("Radio recovery probe starting");
board.powerCycleRadio();
if (!radio_init()) {
Serial.println("Radio recovery probe failed; companion services remain available");
mesh::usbLoggingPort().println(
"Radio recovery probe failed; companion services remain available");
return;
}
companion_radio_available = true;
the_mesh.activateRadio();
Serial.println("Radio recovered; mesh transport is active");
mesh::usbLoggingPort().println("Radio recovered; mesh transport is active");
}
#endif
@@ -207,8 +208,8 @@ static bool applyCompanionPowerSaving(bool enabled) {
esp_err_t pm_result = esp_pm_configure(&pm_config);
if (pm_result != ESP_OK) {
Serial.printf("Device power saving failed: %s\r\n",
esp_err_to_name(pm_result));
mesh::usbLoggingPort().printf("Device power saving failed: %s\r\n",
esp_err_to_name(pm_result));
return false;
}
#else
@@ -216,8 +217,9 @@ static bool applyCompanionPowerSaving(bool enabled) {
// which case esp_pm_configure() is a stub returning ESP_ERR_NOT_SUPPORTED.
// Keep frequency throttling functional instead of retrying that stub.
if (!setCpuFrequencyMhz(max_mhz)) {
Serial.printf("Device power saving failed: CPU %lu MHz is unsupported\r\n",
(unsigned long)max_mhz);
mesh::usbLoggingPort().printf(
"Device power saving failed: CPU %lu MHz is unsupported\r\n",
(unsigned long)max_mhz);
return false;
}
#endif
@@ -226,20 +228,21 @@ static bool applyCompanionPowerSaving(bool enabled) {
esp_err_t bt_result = enabled ? esp_bt_sleep_enable()
: esp_bt_sleep_disable();
if (bt_result != ESP_OK) {
Serial.printf("Bluetooth sleep %s failed: %s\r\n",
enabled ? "enable" : "disable",
esp_err_to_name(bt_result));
mesh::usbLoggingPort().printf("Bluetooth sleep %s failed: %s\r\n",
enabled ? "enable" : "disable",
esp_err_to_name(bt_result));
}
#endif
#if COMPANION_IDF_PM_AVAILABLE
Serial.printf("Device power saving %s: CPU %lu-%lu MHz, automatic light sleep %s\r\n",
enabled ? "on" : "off", (unsigned long)min_mhz,
(unsigned long)max_mhz,
automatic_light_sleep ? "on" : "off");
mesh::usbLoggingPort().printf(
"Device power saving %s: CPU %lu-%lu MHz, automatic light sleep %s\r\n",
enabled ? "on" : "off", (unsigned long)min_mhz,
(unsigned long)max_mhz, automatic_light_sleep ? "on" : "off");
#else
Serial.printf("Device power saving %s: CPU %lu MHz\r\n",
enabled ? "on" : "off", (unsigned long)max_mhz);
mesh::usbLoggingPort().printf("Device power saving %s: CPU %lu MHz\r\n",
enabled ? "on" : "off",
(unsigned long)max_mhz);
#endif
return true;
}
@@ -949,12 +952,13 @@ void halt() {
static void startCompanionBluetooth() {
if (companion_bluetooth_initialized) return;
Serial.println("Companion: starting Bluetooth");
mesh::usbLoggingPort().println("Companion: starting Bluetooth");
bluetooth_interface.begin(BLE_NAME_PREFIX, the_mesh.getNodePrefs()->node_name,
the_mesh.getBLEPin());
if (!interface_manager.addInterface(InterfaceType::Bluetooth,
&bluetooth_interface)) {
Serial.println("Companion: no interface slot available for Bluetooth");
mesh::usbLoggingPort().println(
"Companion: no interface slot available for Bluetooth");
return;
}
companion_bluetooth_initialized = true;
@@ -973,7 +977,7 @@ void halt() {
#if defined(ESP32_PLATFORM) && defined(COMPANION_RADIO_FULL)
static void logFullCompanionMemory(const char* stage) {
Serial.printf(
mesh::usbLoggingPort().printf(
"Full Companion memory %s: heap=%u largest_internal=%u psram_free=%u/%u offline_queue=%d\r\n",
stage, (unsigned)ESP.getFreeHeap(),
(unsigned)heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL),
@@ -984,6 +988,7 @@ void halt() {
void setup() {
Serial.begin(115200);
mesh::beginUsbLoggingPort();
board.begin();
#ifdef HAS_EXTERNAL_WATCHDOG
@@ -1015,7 +1020,8 @@ void setup() {
#if defined(TBEAM_1W)
// Continue into a recovery-capable Companion instead of trapping native
// USB in a reboot loop. The main loop retries the radio independently.
Serial.println("Radio unavailable; starting display, USB, BLE, and WiFi recovery services");
mesh::usbLoggingPort().println(
"Radio unavailable; starting display, USB, BLE, and WiFi recovery services");
break;
#else
MESH_DEBUG_PRINTLN("Radio init failed 3x - rebooting");
@@ -1148,7 +1154,8 @@ void setup() {
#if defined(ESP32) && defined(COMPANION_RADIO_FULL) && defined(WIFI_SSID)
companion_bluetooth_start_at = millis() + 2000UL;
if (companion_bluetooth_start_at == 0) companion_bluetooth_start_at = 1;
Serial.println("Companion: Bluetooth starts in 2 seconds");
mesh::usbLoggingPort().println(
"Companion: Bluetooth starts in 2 seconds");
#else
startCompanionBluetooth();
#endif
+5 -4
View File
@@ -1024,10 +1024,11 @@ void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) {
#if MESH_PACKET_LOGGING
if (mesh::isUsbLoggingEnabled()) {
// Logging builds prefer backpressure over silently losing a packet record.
Serial.print(getLogDateTime());
Serial.print(" RAW: ");
mesh::Utils::printHex(Serial, raw, len);
Serial.println();
Stream& logging_port = mesh::usbLoggingPort();
logging_port.print(getLogDateTime());
logging_port.print(" RAW: ");
mesh::Utils::printHex(logging_port, raw, len);
logging_port.println();
}
#endif
+5 -4
View File
@@ -266,10 +266,11 @@ void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) {
#if MESH_PACKET_LOGGING
if (mesh::isUsbLoggingEnabled()) {
// Logging builds prefer backpressure over silently losing a packet record.
Serial.print(getLogDateTime());
Serial.print(" RAW: ");
mesh::Utils::printHex(Serial, raw, len);
Serial.println();
Stream& logging_port = mesh::usbLoggingPort();
logging_port.print(getLogDateTime());
logging_port.print(" RAW: ");
mesh::Utils::printHex(logging_port, raw, len);
logging_port.println();
}
#endif
+3 -2
View File
@@ -819,8 +819,9 @@ bool SensorMesh::handleIncomingMsg(ClientInfo& from, uint32_t timestamp, uint8_t
MESH_DEBUG_PRINT("handleIncomingMsg: unhandled msg from ");
#ifdef MESH_DEBUG
if (mesh::isUsbLoggingEnabled()) {
mesh::Utils::printHex(Serial, from.id.pub_key, PUB_KEY_SIZE);
Serial.printf(": %s\n", data);
Stream& logging_port = mesh::usbLoggingPort();
mesh::Utils::printHex(logging_port, from.id.pub_key, PUB_KEY_SIZE);
logging_port.printf(": %s\n", data);
}
#endif
return false;