PowerSaving17: Cleanup for RX PowerSaving

This commit is contained in:
Kevin Le committed 2026-08-05 22:06:23 +07:00
1 parent 1fe531e6a4
commit 6160509efc
18 files changed
+208 -298

No files matched your search

+71 -128
View File
@@ -1,48 +1,51 @@
# sh ./build-repeaters-iotthinks.sh
export FIRMWARE_VERSION="PowerSaving16"
export FIRMWARE_VERSION="PowerSaving17"
############# Repeaters #############
# Commonly-used boards
## ESP32 - 17 boards
sh build.sh build-firmware \
Heltec_ct62_repeater \
Heltec_E290_repeater \
Heltec_v3_repeater \
Heltec_WSL3_repeater \
heltec_v4_repeater \
heltec_tracker_v2_repeater \
Heltec_Wireless_Paper_repeater \
Heltec_Wireless_Tracker_repeater \
Heltec_WSL3_repeater \
LilyGo_T3S3_sx1262_repeater \
LilyGo_TBeam_1W_repeater \
Station_G2_repeater \
T_Beam_S3_Supreme_SX1262_repeater \
Tbeam_SX1262_repeater \
LilyGo_T3S3_sx1262_repeater \
Xiao_S3_WIO_repeater \
Xiao_C3_repeater \
Xiao_C6_repeater_ \
Heltec_E290_repeater \
Heltec_Wireless_Tracker_repeater \
LilyGo_TBeam_1W_repeater \
Xiao_S3_repeater \
heltec_tracker_v2_repeater \
Heltec_Wireless_Paper_repeater \
Heltec_ct62_repeater
Xiao_S3_WIO_repeater
## NRF52 - 17 boards
## NRF52 - 21 boards
sh build.sh build-firmware \
RAK_4631_repeater \
Heltec_t114_repeater \
Xiao_nrf52_repeater \
Heltec_mesh_solar_repeater \
ProMicro_repeater \
SenseCap_Solar_repeater \
t1000e_repeater \
LilyGo_T-Echo_repeater \
WioTrackerL1_repeater \
RAK_3401_repeater \
RAK_WisMesh_Tag_repeater \
GAT562_30S_Mesh_Kit_repeater \
GAT562_Mesh_Tracker_Pro_repeater \
Heltec_mesh_solar_repeater \
Heltec_t096_repeater \
Heltec_t1_repeater \
Heltec_t114_repeater \
ikoka_nano_nrf_22dbm_repeater \
ikoka_nano_nrf_30dbm_repeater \
ikoka_nano_nrf_33dbm_repeater \
LilyGo_T-Echo_repeater \
ProMicro_repeater \
RAK_3401_repeater \
RAK_4631_repeater \
RAK_WisMesh_Tag_repeater \
SenseCap_Solar_repeater \
t1000e_repeater \
ThinkNode_M1_repeater \
Heltec_t096_repeater
ThinkNode_M3_repeater \
ThinkNode_M6_repeater \
WioTrackerL1_repeater \
Xiao_nrf52_repeater
## ESP32, SX1276 - 3 boards
sh build.sh build-firmware \
@@ -55,62 +58,63 @@ Tbeam_SX1276_repeater
sh build.sh build-firmware \
Heltec_v3_room_server \
heltec_v4_room_server \
LilyGo_TBeam_1W_room_server \
Heltec_WSL3_room_server \
Xiao_S3_room_server \
heltec_tracker_v2_room_server \
Heltec_Wireless_Paper_room_server
Heltec_Wireless_Paper_room_server \
Heltec_WSL3_room_server \
LilyGo_TBeam_1W_room_server \
Xiao_S3_room_server
# NRF52 - 6 boards
# NRF52 - 7 boards
sh build.sh build-firmware \
RAK_4631_room_server \
Heltec_t096_room_server \
Heltec_t114_room_server \
Xiao_nrf52_room_server \
RAK_3401_room_server \
RAK_4631_room_server \
t1000e_room_server \
WioTrackerL1_room_server \
RAK_3401_room_server \
Heltec_t096_room_server
Xiao_nrf52_room_server
############# Companions BLE #############
# NRF52 - 12 boards
# NRF52 - 15 boards
sh build.sh build-firmware \
RAK_4631_companion_radio_ble \
Heltec_t096_companion_radio_ble \
Heltec_t096_companion_radio_ble_femoff \
Heltec_t1_companion_radio_ble \
Heltec_t114_companion_radio_ble \
Xiao_nrf52_companion_radio_ble \
t1000e_companion_radio_ble \
LilyGo_T-Echo_companion_radio_ble \
WioTrackerL1_companion_radio_ble \
RAK_3401_companion_radio_ble \
RAK_4631_companion_radio_ble \
RAK_WisMesh_Tag_companion_radio_ble \
SenseCap_Solar_companion_radio_ble \
t1000e_companion_radio_ble \
ThinkNode_M1_companion_radio_ble \
Heltec_t096_companion_radio_ble \
Heltec_t096_companion_radio_ble_femoff
ThinkNode_M3_companion_radio_ble \
ThinkNode_M6_companion_radio_ble \
WioTrackerL1_companion_radio_ble \
Xiao_nrf52_companion_radio_ble
############# Companions BLE PS #############
# ESP32 - 18 boards
# ESP32 - 19 boards
sh build.sh build-firmware \
Heltec_v3_companion_radio_ble_ps \
heltec_v4_companion_radio_ble_ps \
heltec_v4_3_companion_radio_ble_ps_femoff \
Xiao_C3_companion_radio_ble_ps \
Xiao_S3_companion_radio_ble_ps \
Xiao_S3_WIO_companion_radio_ble_ps \
Heltec_v2_companion_radio_ble_ps \
LilyGo_TBeam_1W_companion_radio_ble_ps \
Heltec_WSL3_companion_radio_ble_ps \
Heltec_Wireless_Tracker_companion_radio_ble_ps \
heltec_tracker_v2_companion_radio_ble_ps \
Heltec_Wireless_Paper_companion_radio_ble_ps \
LilyGo_TLora_V2_1_1_6_companion_radio_ble_ps \
Heltec_ct62_companion_radio_ble_ps \
heltec_tracker_v2_companion_radio_ble_ps \
Heltec_v2_companion_radio_ble_ps \
Heltec_v3_companion_radio_ble_ps \
heltec_v4_3_companion_radio_ble_ps_femoff \
heltec_v4_companion_radio_ble_ps \
heltec_v4_expansionkit_tft_companion_radio_ble_ps \
Heltec_Wireless_Paper_companion_radio_ble_ps \
Heltec_Wireless_Tracker_companion_radio_ble_ps \
Heltec_WSL3_companion_radio_ble_ps \
LilyGo_T3S3_sx1262_companion_radio_ble_ps \
LilyGo_TBeam_1W_companion_radio_ble_ps \
LilyGo_TLora_V2_1_1_6_companion_radio_ble_ps \
T_Beam_S3_Supreme_SX1262_companion_radio_ble_ps \
Tbeam_SX1262_companion_radio_ble_ps \
heltec_v4_expansionkit_tft_companion_radio_ble_ps \
LilyGo_T3S3_sx1262_companion_radio_ble_ps
# Not working
Tbeam_SX1276_companion_radio_ble_ps \
Xiao_C3_companion_radio_ble_ps \
Xiao_S3_companion_radio_ble_ps \
Xiao_S3_WIO_companion_radio_ble_ps
############# Companions USB #############
sh build.sh build-firmware \
@@ -119,78 +123,17 @@ Heltec_t096_companion_radio_usb
############# Sample builds #############
# 14 boards
sh build.sh build-firmware \
Heltec_v3_repeater \
heltec_v4_repeater \
Xiao_C3_repeater \
Xiao_C6_repeater_ \
RAK_4631_repeater \
Heltec_t096_repeater \
Heltec_v3_companion_radio_ble_ps \
heltec_v4_companion_radio_ble_ps \
heltec_v4_3_companion_radio_ble_ps_femoff \
Xiao_C3_companion_radio_ble_ps \
Xiao_C6_companion_radio_ble_ \
RAK_4631_companion_radio_ble \
Heltec_t096_companion_radio_ble \
Heltec_t096_companion_radio_ble_femoff
############# GPS PowerSaving #############
export FIRMWARE_VERSION="PowerSaving16.1.1"
sh build.sh build-firmware \
heltec_v4_repeater \
Heltec_t114_repeater \
Heltec_t096_repeater \
WioTrackerL1_repeater \
LilyGo_T-Echo_repeater \
Station_G2_repeater \
Heltec_Wireless_Tracker_repeater \
heltec_tracker_v2_repeater \
Heltec_mesh_solar_repeater \
SenseCap_Solar_repeater
sh build.sh build-firmware \
Heltec_t114_companion_radio_ble \
t1000e_companion_radio_ble \
LilyGo_T-Echo_companion_radio_ble \
WioTrackerL1_companion_radio_ble \
SenseCap_Solar_companion_radio_ble \
Heltec_t096_companion_radio_ble \
Heltec_t096_companion_radio_ble_femoff \
heltec_v4_companion_radio_ble_ps \
Heltec_t096_repeater \
Heltec_v3_companion_radio_ble_ps \
Heltec_v3_repeater \
heltec_v4_3_companion_radio_ble_ps_femoff \
LilyGo_TBeam_1W_companion_radio_ble_ps \
Heltec_Wireless_Tracker_companion_radio_ble_ps \
heltec_tracker_v2_companion_radio_ble_ps \
T_Beam_S3_Supreme_SX1262 \
Tbeam_SX1262_companion_radio_ble_ps \
heltec_v4_expansionkit_tft_companion_radio_ble_ps
export FIRMWARE_VERSION="PowerSaving16.1.2"
sh build.sh build-firmware \
RAK_4631_repeater \
RAK_3401_repeater \
RAK_WisMesh_Tag_repeater \
GAT562_30S_Mesh_Kit_repeater \
GAT562_Mesh_Tracker_Pro_repeater \
heltec_v4_companion_radio_ble_ps \
heltec_v4_repeater \
RAK_4631_companion_radio_ble \
RAK_3401_companion_radio_ble \
RAK_WisMesh_Tag_companion_radio_ble
export FIRMWARE_VERSION="PowerSaving16.1.2"
sh build.sh build-firmware \
Tbeam_SX1262_repeater \
T_Beam_S3_Supreme_SX1262_repeater \
LilyGo_TBeam_1W_repeater \
Tbeam_SX1262_companion_radio_ble_ps \
T_Beam_S3_Supreme_SX1262_companion_radio_ble_ps \
LilyGo_TBeam_1W_companion_radio_ble_ps
export FIRMWARE_VERSION="PowerSaving16.1.2"
sh build.sh build-firmware \
t1000e_repeater \
t1000e_companion_radio_ble \
Heltec_mesh_solar_repeater \
Heltec_mesh_solar_companion_radio_ble \
Heltec_Wireless_Tracker_repeater \
Heltec_Wireless_Tracker_companion_radio_ble_ps \
RAK_4631_repeater \
Xiao_C3_companion_radio_ble_ps \
Xiao_C3_repeater \
Xiao_C6_companion_radio_ble_ \
Xiao_C6_repeater_
+12 -38
View File
@@ -2,6 +2,7 @@
#include <Arduino.h> // needed for PlatformIO
#include <Mesh.h>
#include "helpers/radiolib/RXPowerSaving.h"
#define CMD_APP_START 1
#define CMD_SEND_TXT_MSG 2
@@ -279,47 +280,19 @@ bool MyMesh::getCADEnabled() const {
#endif
#endif
// RX PowerSaving
#ifdef RXPS_FIXED_ENABLED
static uint32_t ceilPositiveFloat(float value) {
uint32_t rounded = (uint32_t)value;
return value > (float)rounded ? rounded + 1 : rounded;
}
static bool calcFixedRxPowerSaving(uint8_t sf, float bw, uint32_t* rx_us, uint32_t* sleep_us) {
if (RXPS_FIXED_LEVEL < 1 || RXPS_FIXED_LEVEL > 10 || sf < 5 || sf > 12 ||
bw <= 0.0f || (RXPS_FIXED_PREAMBLE != 16 && RXPS_FIXED_PREAMBLE != 32)) {
return false;
}
const float symbol_us = (1000.0f * (float)(1UL << sf)) / bw;
const float amount = (float)(RXPS_FIXED_LEVEL - 1) / 9.0f;
const float rx_start_symbols = RXPS_FIXED_PREAMBLE == 16 ? 12.0f : 16.0f;
const float sleep_start_symbols = RXPS_FIXED_PREAMBLE == 16 ? 2.0f : 15.0f;
const float rx_edge_symbols = 8.0f;
const float sleep_edge_symbols = (float)RXPS_FIXED_PREAMBLE + 4.25f - 8.0f;
const float rx_symbols = rx_start_symbols + amount * (rx_edge_symbols - rx_start_symbols);
const float sleep_symbols = sleep_start_symbols + amount * (sleep_edge_symbols - sleep_start_symbols);
*rx_us = ceilPositiveFloat(rx_symbols * symbol_us);
*sleep_us = (uint32_t)(sleep_symbols * symbol_us);
return true;
}
static void applyFixedRxPowerSaving(uint8_t sf, float bw) {
uint32_t rx_us, sleep_us;
if (!calcFixedRxPowerSaving(sf, bw, &rx_us, &sleep_us)) {
MESH_DEBUG_PRINTLN("RX Power Saving fixed profile invalid");
if (!calcRxPowerSavingLevel(RXPS_FIXED_LEVEL, sf, bw, RXPS_FIXED_PREAMBLE, &rx_us, &sleep_us)) {
POWERSAVING_DEBUG_PRINTLN("RX Power Saving fixed profile invalid");
return;
}
bool ok = radio_driver.setRxPowerSaving(true, rx_us, sleep_us);
MESH_DEBUG_PRINTLN("RX Power Saving fixed level %d p%d: %s (%lu/%lu us)",
RXPS_FIXED_LEVEL,
RXPS_FIXED_PREAMBLE,
ok ? "Enabled" : "Unsupported",
(unsigned long)rx_us,
(unsigned long)sleep_us);
POWERSAVING_DEBUG_PRINTLN("RX Power Saving fixed level %d p%d: %s (%lu/%lu us)", RXPS_FIXED_LEVEL,
RXPS_FIXED_PREAMBLE, ok ? "Enabled" : "Unsupported", (unsigned long)rx_us,
(unsigned long)sleep_us);
}
#endif
@@ -1028,11 +1001,12 @@ void MyMesh::begin(bool has_display) {
radio_driver.setTxPower(_prefs.tx_power_dbm);
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain);
#ifdef RXPS_FIXED_ENABLED
applyFixedRxPowerSaving(_prefs.sf, _prefs.bw);
#endif
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled");
#ifdef RXPS_FIXED_ENABLED
applyFixedRxPowerSaving(_prefs.sf, _prefs.bw); // RX PowerSaving
#endif
}
const char *MyMesh::getNodeName() {
@@ -1457,7 +1431,7 @@ void MyMesh::handleCmdFrame(size_t len) {
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
#ifdef RXPS_FIXED_ENABLED
applyFixedRxPowerSaving(_prefs.sf, _prefs.bw);
applyFixedRxPowerSaving(_prefs.sf, _prefs.bw); // RX PowerSaving
#endif
MESH_DEBUG_PRINTLN("OK: CMD_SET_RADIO_PARAMS: f=%d, bw=%d, sf=%d, cr=%d", freq, bw, (uint32_t)sf,
(uint32_t)cr);
+3 -2
View File
@@ -1,5 +1,6 @@
#include "MyMesh.h"
#include <algorithm>
#include "helpers/radiolib/RXPowerSaving.h"
/* ------------------------------ Config -------------------------------- */
@@ -896,8 +897,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
_prefs.flood_max_advert = 8;
_prefs.interference_threshold = 0; // disabled
_prefs.cad_enabled = 0; // hardware CAD before TX (off by default; 'set cad on')
_prefs.rx_ps_rx_us = RX_POWERSAVING_DEFAULT_RX_US;
_prefs.rx_ps_sleep_us = RX_POWERSAVING_DEFAULT_SLEEP_US;
_prefs.rx_ps_rx_us = RX_POWERSAVING_DEFAULT_RX_US; // RX PowerSaving
_prefs.rx_ps_sleep_us = RX_POWERSAVING_DEFAULT_SLEEP_US; // RX PowerSaving
// bridge defaults
_prefs.bridge_enabled = 1; // enabled
-8
View File
@@ -13,14 +13,6 @@ extra_configs =
variants/*/platformio.ini
platformio.local.ini
[companion_rxps]
custom_rxps_level = 5
custom_rxps_preamble = 16
build_flags =
-D RXPS_FIXED_ENABLED=1
-D RXPS_FIXED_LEVEL=${companion_rxps.custom_rxps_level}
-D RXPS_FIXED_PREAMBLE=${companion_rxps.custom_rxps_preamble}
[arduino_base]
framework = arduino
monitor_speed = 115200
+17 -84
View File
@@ -11,6 +11,8 @@
#define BRIDGE_MAX_BAUD 115200
#endif
#include <helpers/radiolib/RXPowerSaving.h>
// Believe it or not, this std C function is busted on some platforms!
static uint32_t _atoi(const char* sp) {
uint32_t n = 0;
@@ -29,80 +31,6 @@ static bool isValidName(const char *n) {
return true;
}
static bool isValidRxPowerSavingPeriod(uint32_t us) {
return us >= RX_POWERSAVING_MIN_PERIOD_US && us <= RX_POWERSAVING_MAX_PERIOD_US;
}
// MeshCore preamble convention used for the RX powersaving timing calculation.
// Must stay in sync with RadioLibWrapper::preambleLengthForSF() (the value the
// radio actually transmits); kept local here because CommonCLI is radio-agnostic.
static uint16_t rxPowerSavingPreambleForSF(uint8_t sf) {
return sf <= 8 ? 32 : 16;
}
static bool isNumeric(const char* sp) {
if (!sp || !*sp) return false;
while (*sp) {
if (*sp < '0' || *sp > '9') return false;
sp++;
}
return true;
}
static uint32_t ceilPositiveFloat(float value) {
uint32_t rounded = (uint32_t)value;
return value > (float)rounded ? rounded + 1 : rounded;
}
static bool calcRxPowerSavingLevel(uint32_t level, uint8_t sf, float bw, uint32_t preamble,
uint32_t* rx_us, uint32_t* sleep_us) {
if (level < 1 || level > 10 || sf < 5 || sf > 12 || bw <= 0.0f || (preamble != 16 && preamble != 32)) {
return false;
}
const float symbol_us = (1000.0f * (float)(1UL << sf)) / bw;
const float amount = (float)(level - 1) / 9.0f;
const float rx_start_symbols = preamble == 16 ? 12.0f : 16.0f;
const float sleep_start_symbols = preamble == 16 ? 2.0f : 15.0f;
const float rx_edge_symbols = 8.0f;
const float sleep_edge_symbols = (float)preamble + 4.25f - 8.0f;
const float rx_symbols = rx_start_symbols + amount * (rx_edge_symbols - rx_start_symbols);
const float sleep_symbols = sleep_start_symbols + amount * (sleep_edge_symbols - sleep_start_symbols);
*rx_us = ceilPositiveFloat(rx_symbols * symbol_us);
*sleep_us = (uint32_t)(sleep_symbols * symbol_us);
return true;
}
static void ensureRxPowerSavingDefaults(NodePrefs* prefs) {
if (!isValidRxPowerSavingPeriod(prefs->rx_ps_rx_us)) {
prefs->rx_ps_rx_us = RX_POWERSAVING_DEFAULT_RX_US;
}
if (!isValidRxPowerSavingPeriod(prefs->rx_ps_sleep_us)) {
prefs->rx_ps_sleep_us = RX_POWERSAVING_DEFAULT_SLEEP_US;
}
}
// Recomputes rx_ps_rx_us/rx_ps_sleep_us from the stored level and the current
// radio SF/BW. No-op (returns false) for manual timings (rx_ps_level == 0).
// Lets level-based RX powersaving auto-retune when SF/BW change.
static bool recalcRxPowerSavingFromLevel(NodePrefs* prefs) {
if (prefs->rx_ps_level < 1 || prefs->rx_ps_level > 10) return false; // manual: nothing to recompute
uint32_t preamble = prefs->rx_ps_preamble ? prefs->rx_ps_preamble
: rxPowerSavingPreambleForSF(prefs->sf);
uint32_t rx_us, sleep_us;
if (!calcRxPowerSavingLevel(prefs->rx_ps_level, prefs->sf, prefs->bw, preamble, &rx_us, &sleep_us)) {
return false;
}
if (!isValidRxPowerSavingPeriod(rx_us) || !isValidRxPowerSavingPeriod(sleep_us)) {
return false;
}
prefs->rx_ps_rx_us = rx_us;
prefs->rx_ps_sleep_us = sleep_us;
return true;
}
void CommonCLI::loadPrefs(FILESYSTEM* fs) {
if (fs->exists("/com_prefs")) {
loadPrefsInt(fs, "/com_prefs"); // new filename
@@ -208,13 +136,16 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
_prefs->rx_boosted_gain = constrain(_prefs->rx_boosted_gain, 0, 1); // boolean
_prefs->radio_fem_rxgain = constrain(_prefs->radio_fem_rxgain, 0, 1); // boolean
_prefs->cad_enabled = constrain(_prefs->cad_enabled, 0, 1); // boolean
_prefs->rx_powersaving_enabled = constrain(_prefs->rx_powersaving_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; // 0 = auto (derive from SF)
}
ensureRxPowerSavingDefaults(_prefs);
recalcRxPowerSavingFromLevel(_prefs); // retune level-based timings to the loaded SF/BW
ensureRxPowerSavingDefaults(&_prefs->rx_ps_rx_us, &_prefs->rx_ps_sleep_us);
recalcRxPowerSavingFromLevel(_prefs->rx_ps_level, _prefs->sf, _prefs->bw, _prefs->rx_ps_preamble,
&_prefs->rx_ps_rx_us,
&_prefs->rx_ps_sleep_us); // retune level-based timings to the loaded SF/BW
file.close();
}
@@ -761,17 +692,17 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
} else {
strcpy(reply, "Error: state must be on or off");
}
} else if (memcmp(config, "radio.rxps ", 11) == 0) {
} else if (memcmp(config, "radio.rxps ", 11) == 0) { // RX PowerSaving
const char* value = &config[11];
uint8_t enable = _prefs->rx_powersaving_enabled;
uint32_t rx_us = _prefs->rx_ps_rx_us;
uint32_t sleep_us = _prefs->rx_ps_sleep_us;
uint32_t level = 0;
uint32_t preamble = rxPowerSavingPreambleForSF(_prefs->sf);
uint8_t level = 0;
uint8_t preamble = rxPowerSavingPreambleForSF(_prefs->sf);
bool level_requested = false;
bool preamble_overridden = false;
ensureRxPowerSavingDefaults(_prefs);
ensureRxPowerSavingDefaults(&_prefs->rx_ps_rx_us, &_prefs->rx_ps_sleep_us);
rx_us = _prefs->rx_ps_rx_us;
sleep_us = _prefs->rx_ps_sleep_us;
@@ -875,7 +806,9 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
_prefs->bw = bw;
// Retune level-based RX powersaving to the new SF/BW. Persist only; the
// radio itself is "reboot to apply", and begin() re-arms the timings then.
bool rxps_retuned = recalcRxPowerSavingFromLevel(_prefs);
bool rxps_retuned = recalcRxPowerSavingFromLevel(
_prefs->rx_ps_level, _prefs->sf, _prefs->bw, _prefs->rx_ps_preamble, &_prefs->rx_ps_rx_us,
&_prefs->rx_ps_sleep_us); // retune level-based timings to the loaded SF/BW
_callbacks->savePrefs();
strcpy(reply, rxps_retuned ? "OK - reboot to apply (rxps retuned)" : "OK - reboot to apply");
} else {
@@ -915,7 +848,7 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
strcpy(reply, "OK");
} else {
strcpy(reply, "Error, max 64");
}
}
} else if (memcmp(config, "flood.max.advert ", 17) == 0) {
uint8_t m = atoi(&config[17]);
if (m <= 64) {
@@ -1121,8 +1054,8 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
} else {
sprintf(reply, "> %s", _board->isLoRaFemLnaEnabled() ? "on" : "off");
}
} else if (memcmp(config, "radio.rxps", 10) == 0) {
ensureRxPowerSavingDefaults(_prefs);
} else if (memcmp(config, "radio.rxps", 10) == 0) { // RX PowerSaving
ensureRxPowerSavingDefaults(&_prefs->rx_ps_rx_us, &_prefs->rx_ps_sleep_us);
sprintf(reply, "> %s,%lu,%lu", _prefs->rx_powersaving_enabled ? "on" : "off",
(unsigned long)_prefs->rx_ps_rx_us, (unsigned long)_prefs->rx_ps_sleep_us);
} else if (memcmp(config, "rxps.wd", 7) == 0) {
+1 -12
View File
@@ -19,18 +19,6 @@
#define LOOP_DETECT_MODERATE 2
#define LOOP_DETECT_STRICT 3
#define RX_POWERSAVING_DEFAULT_RX_US 65625UL
#define RX_POWERSAVING_DEFAULT_SLEEP_US 60000UL
#define RX_POWERSAVING_MIN_PERIOD_US 1000UL
#define RX_POWERSAVING_MAX_PERIOD_US 30000000UL
// The named profiles are level presets pinned to a 16-symbol preamble: most
// deployed senders still transmit 16-symbol preambles regardless of the newer
// SF-based rule (32 for SF <= 8). Revisit once the field has largely migrated.
#define RX_POWERSAVING_CONSERVATIVE_LEVEL 1UL
#define RX_POWERSAVING_BALANCED_LEVEL 5UL
#define RX_POWERSAVING_PROFILE_PREAMBLE 16UL
struct NodePrefs { // persisted to file
float airtime_factor;
char node_name[32];
@@ -133,6 +121,7 @@ public:
// no op by default
};
// RX PowerSaving
virtual bool setRxPowerSaving(bool enable, uint32_t rx_us, uint32_t sleep_us) {
return !enable;
};
+103
View File
@@ -0,0 +1,103 @@
#pragma once
#include <Arduino.h>
#define RX_POWERSAVING_DEFAULT_RX_US 65625UL
#define RX_POWERSAVING_DEFAULT_SLEEP_US 60000UL
#define RX_POWERSAVING_MIN_PERIOD_US 1000UL
#define RX_POWERSAVING_MAX_PERIOD_US 30000000UL
// The named profiles are level presets pinned to a 16-symbol preamble: most
// deployed senders still transmit 16-symbol preambles regardless of the newer
// SF-based rule (32 for SF <= 8). Revisit once the field has largely migrated.
#define RX_POWERSAVING_CONSERVATIVE_LEVEL 1
#define RX_POWERSAVING_BALANCED_LEVEL 5
#define RX_POWERSAVING_PROFILE_PREAMBLE 16
// Fixed settings for companions
#define RXPS_FIXED_ENABLED 1
#define RXPS_FIXED_LEVEL RX_POWERSAVING_BALANCED_LEVEL
#define RXPS_FIXED_PREAMBLE RX_POWERSAVING_PROFILE_PREAMBLE
inline bool isValidRxPowerSavingPeriod(uint32_t us) {
return us >= RX_POWERSAVING_MIN_PERIOD_US && us <= RX_POWERSAVING_MAX_PERIOD_US;
}
// MeshCore preamble convention used for the RX powersaving timing calculation.
// Must stay in sync with RadioLibWrapper::preambleLengthForSF() (the value the
// radio actually transmits); kept local here because CommonCLI is radio-agnostic.
inline uint8_t rxPowerSavingPreambleForSF(uint8_t sf) {
return sf <= 8 ? 32 : 16;
}
inline bool isNumeric(const char *sp) {
if (!sp || !*sp) return false;
while (*sp) {
if (*sp < '0' || *sp > '9') return false;
sp++;
}
return true;
}
inline uint32_t ceilPositiveFloat(float value) {
uint32_t rounded = (uint32_t)value;
return value > (float)rounded ? rounded + 1 : rounded;
}
inline bool calcRxPowerSavingLevel(uint8_t level, uint8_t sf, float bw, uint8_t preamble, uint32_t *rx_us,
uint32_t *sleep_us) {
if (level < 1 || level > 10 || sf < 5 || sf > 12 || bw <= 0.0f || (preamble != 16 && preamble != 32)) {
return false;
}
const float symbol_us = (1000.0f * (float)(1UL << sf)) / bw;
const float amount = (float)(level - 1) / 9.0f;
const float rx_start_symbols = preamble == 16 ? 12.0f : 16.0f;
const float sleep_start_symbols = preamble == 16 ? 2.0f : 15.0f;
const float rx_edge_symbols = 8.0f;
const float sleep_edge_symbols = (float)preamble + 4.25f - 8.0f;
const float rx_symbols = rx_start_symbols + amount * (rx_edge_symbols - rx_start_symbols);
const float sleep_symbols = sleep_start_symbols + amount * (sleep_edge_symbols - sleep_start_symbols);
*rx_us = ceilPositiveFloat(rx_symbols * symbol_us);
*sleep_us = (uint32_t)(sleep_symbols * symbol_us);
return true;
}
inline void ensureRxPowerSavingDefaults(uint32_t *rx_ps_rx_us, uint32_t *rx_ps_sleep_us) {
if (!isValidRxPowerSavingPeriod(*rx_ps_rx_us)) {
*rx_ps_rx_us = RX_POWERSAVING_DEFAULT_RX_US;
}
if (!isValidRxPowerSavingPeriod(*rx_ps_sleep_us)) {
*rx_ps_sleep_us = RX_POWERSAVING_DEFAULT_SLEEP_US;
}
}
// Recomputes rx_ps_rx_us/rx_ps_sleep_us from the stored level and the current
// radio SF/BW. No-op (returns false) for manual timings (rx_ps_level == 0).
// Lets level-based RX powersaving auto-retune when SF/BW change.
inline bool recalcRxPowerSavingFromLevel(uint8_t level, uint8_t sf, float bw, uint8_t preamble,
uint32_t *rx_ps_rx_us, uint32_t *rx_ps_sleep_us) {
if (level < 1 || level > 10) {
return false; // manual: nothing to recompute
}
if (preamble == 0) {
preamble = rxPowerSavingPreambleForSF(sf);
}
uint32_t rx_us, sleep_us;
if (!calcRxPowerSavingLevel(level, sf, bw, preamble, &rx_us, &sleep_us)) {
return false;
}
if (!isValidRxPowerSavingPeriod(rx_us) || !isValidRxPowerSavingPeriod(sleep_us)) {
return false;
}
*rx_ps_rx_us = rx_us;
*rx_ps_sleep_us = sleep_us;
return true;
}
@@ -292,6 +292,7 @@ bool RadioLibWrapper::isInRecvMode() const {
return (state & ~STATE_INT_READY) == STATE_RX;
}
// RX PowerSaving
bool RadioLibWrapper::setRxPowerSaving(bool enabled, uint32_t rx_us, uint32_t sleep_us) {
if (enabled && !supportsRxPowerSaving()) {
return false;
-2
View File
@@ -127,7 +127,6 @@ board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${Heltec_t096.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -158,7 +157,6 @@ board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${Heltec_t096.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-4
View File
@@ -99,7 +99,6 @@ board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${Heltec_t114.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D DISPLAY_CLASS=NullDisplayDriver
-D MAX_CONTACTS=350
@@ -123,7 +122,6 @@ board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${Heltec_t114.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D DISPLAY_CLASS=NullDisplayDriver
-D MAX_CONTACTS=350
@@ -213,7 +211,6 @@ board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${Heltec_t114_with_display.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -238,7 +235,6 @@ board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${Heltec_t114_with_display.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -136,7 +136,6 @@ lib_deps =
extends = Heltec_tracker_v2
build_flags =
${Heltec_tracker_v2.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -156,7 +155,6 @@ lib_deps =
extends = Heltec_tracker_v2
build_flags =
${Heltec_tracker_v2.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -186,7 +184,6 @@ platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
extends = Heltec_tracker_v2
build_flags =
${Heltec_tracker_v2.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-3
View File
@@ -184,7 +184,6 @@ lib_deps =
extends = heltec_v4_oled
build_flags =
${heltec_v4_oled.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -204,7 +203,6 @@ lib_deps =
extends = heltec_v4_oled
build_flags =
${heltec_v4_oled.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -239,7 +237,6 @@ build_flags =
extends = heltec_v4_oled
build_flags =
${heltec_v4_oled.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-2
View File
@@ -123,7 +123,6 @@ board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${rak4631.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D PIN_USER_BTN=9
-D PIN_USER_BTN_ANA=31
@@ -145,7 +144,6 @@ board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 712704
build_flags =
${rak4631.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D PIN_USER_BTN=9
-D PIN_USER_BTN_ANA=31
-2
View File
@@ -73,7 +73,6 @@ extends = t1000-e
board_build.ldscript = boards/nrf52840_s140_v7_extrafs.ld
board_upload.maximum_size = 708608
build_flags = ${t1000-e.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-orig
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -97,7 +96,6 @@ extends = t1000-e
board_build.ldscript = boards/nrf52840_s140_v7_extrafs.ld
board_upload.maximum_size = 708608
build_flags = ${t1000-e.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-orig
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-2
View File
@@ -75,7 +75,6 @@ extends = ThinkNode_M3
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 708608
build_flags = ${ThinkNode_M3.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-orig
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -99,7 +98,6 @@ extends = ThinkNode_M3
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
board_upload.maximum_size = 708608
build_flags = ${ThinkNode_M3.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-orig
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-2
View File
@@ -46,7 +46,6 @@ board_build.ldscript = boards/nrf52840_s140_v7_extrafs.ld
board_upload.maximum_size = 708608
build_flags =
${Xiao_nrf52.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-orig
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -70,7 +69,6 @@ board_build.ldscript = boards/nrf52840_s140_v7_extrafs.ld
board_upload.maximum_size = 708608
build_flags =
${Xiao_nrf52.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-orig
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-2
View File
@@ -94,7 +94,6 @@ lib_deps =
extends = Xiao_S3
build_flags =
${Xiao_S3.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -123,7 +122,6 @@ platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
extends = Xiao_S3
build_flags =
${Xiao_S3.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
-4
View File
@@ -132,7 +132,6 @@ lib_deps =
extends = Xiao_S3_WIO
build_flags =
${Xiao_S3_WIO.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -155,7 +154,6 @@ lib_deps =
extends = Xiao_S3_WIO
build_flags =
${Xiao_S3_WIO.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -184,7 +182,6 @@ platform_packages = framework-arduinoespressif32 @ symlink://D:/esp32-2.0.17
extends = Xiao_S3_WIO
build_flags =
${Xiao_S3_WIO.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40
@@ -213,7 +210,6 @@ build_src_filter = ${Xiao_S3_WIO.build_src_filter}
+<../examples/companion_radio/*.cpp>
build_flags =
${Xiao_S3_WIO.build_flags}
${companion_rxps.build_flags}
-I examples/companion_radio/ui-new
-D MAX_CONTACTS=350
-D MAX_GROUP_CHANNELS=40