Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
197db23
Add power settings for SX126X: current limit and boosted gain
jbrazio Nov 25, 2025
67b1124
Add support for SX126X current limit and boosted gain settings
jbrazio Nov 30, 2025
9203761
Update ebyte_eora_s3 board
jbrazio Nov 30, 2025
3c30f8f
Update heltec_ct62 board
jbrazio Nov 30, 2025
d5e75e2
Update heltec_e213 board
jbrazio Nov 30, 2025
1eebdbe
Update heltec_e290 board
jbrazio Nov 30, 2025
80274d9
Update heltec_mesh_solar board
jbrazio Nov 30, 2025
ca4380c
Update heltec_t114 board
jbrazio Nov 30, 2025
3c7d3c6
Update heltec_t190 board
jbrazio Nov 30, 2025
92ab535
Update heltec_tracker
jbrazio Nov 30, 2025
a031907
Updated mesh_pocket board
jbrazio Nov 30, 2025
79cebd7
Updated thinknode_m1 board
jbrazio Nov 30, 2025
f8c9864
Updated promicro board
jbrazio Nov 30, 2025
a33f6c5
Updated thinknode_m2 board
jbrazio Nov 30, 2025
56a98a1
Updated xiao_rp2040 board
jbrazio Nov 30, 2025
dbd53d4
Updated ikoka_nano_nrf board
jbrazio Nov 30, 2025
8ba8ca2
Updated xiao_c3 board
jbrazio Nov 30, 2025
ab3296d
Updated heltec_tracker_v2 board
jbrazio Nov 30, 2025
923a41c
Updated waveshare_rp2040_lora board
jbrazio Nov 30, 2025
8d96df0
Updated lilygo_techo board
jbrazio Nov 30, 2025
aa51eea
Updated sensecap_solar board
jbrazio Nov 30, 2025
47a85d4
Updated wio-tracker-l1 board
jbrazio Nov 30, 2025
23a1722
Updated ikoka_stick_nrf board
jbrazio Nov 30, 2025
a6676f1
Updated tenstar_c3 board
jbrazio Nov 30, 2025
617c8e6
Fix preprocessor conditions when building SX1276
jbrazio Nov 30, 2025
8160688
Updated heltec_v2 board
jbrazio Nov 30, 2025
8a7b214
Updates lilygo_t3s3_sx1276 board
jbrazio Nov 30, 2025
7341c34
Updated lilygo_tbeam_SX1276 board
jbrazio Nov 30, 2025
77779aa
Updated lilygo_tlora_v2_1 board
jbrazio Nov 30, 2025
4148661
Cleanup
jbrazio Nov 30, 2025
66ea8ef
Merge remote-tracking branch 'upstream/dev' into jbrazio/2025_9ea280c9
jbrazio Nov 30, 2025
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
27 changes: 27 additions & 0 deletions examples/simple_repeater/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,23 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;

_prefs.adc_multiplier = 0.0f; // 0.0f means use default board multiplier

#if defined(USE_SX1262) || defined(USE_SX1268) || defined(USE_SX1276)
#if defined(SX126X_CURRENT_LIMIT)
_prefs.sx12xx_current_limit = SX126X_CURRENT_LIMIT;
#elif defined(SX127X_CURRENT_LIMIT)
_prefs.sx12xx_current_limit = SX127X_CURRENT_LIMIT;
#else
_prefs.sx12xx_current_limit = 140; // mA
#endif
#if defined(USE_SX1262) || defined(USE_SX1268)
#ifdef SX126X_RX_BOOSTED_GAIN
_prefs.sx126x_rx_boosted_gain = SX126X_RX_BOOSTED_GAIN;
#else
_prefs.sx126x_rx_boosted_gain = 1; // enabled by default;
#endif
#endif
#endif
}

void MyMesh::begin(FILESYSTEM *fs) {
Expand All @@ -736,6 +753,16 @@ void MyMesh::begin(FILESYSTEM *fs) {
radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
radio_set_tx_power(_prefs.tx_power_dbm);

#if defined(USE_SX1262) || defined(USE_SX1268) || defined(USE_SX1276)
radio_set_current_limit(_prefs.sx12xx_current_limit);
MESH_DEBUG_PRINTLN("SX12xx Current Limit: %d mA", radio_get_current_limit());
#if defined(USE_SX1262) || defined(USE_SX1268)
radio_set_rx_boosted_gain_mode(_prefs.sx126x_rx_boosted_gain);
MESH_DEBUG_PRINTLN("SX126x RX Boosted Gain Mode: %s",
radio_get_rx_boosted_gain_mode() ? "Enabled" : "Disabled");
#endif
#endif

updateAdvertTimer();
updateFloodAdvertTimer();

Expand Down
11 changes: 11 additions & 0 deletions examples/simple_repeater/MyMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,15 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
bridge.begin();
}
#endif

#if defined(USE_SX1262) || defined(USE_SX1268) || defined(USE_SX1276)
void setCurrentLimit(uint8_t ma) override {
radio_set_current_limit(ma);
}
#if defined(USE_SX1262) || defined(USE_SX1268)
void setRxBoostedGain(bool enable) override {
radio_set_rx_boosted_gain_mode(enable);
}
#endif
#endif
};
54 changes: 43 additions & 11 deletions src/helpers/CommonCLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
file.read((uint8_t *)&_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
file.read((uint8_t *)&_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
file.read((uint8_t *)&_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
file.read((uint8_t *)pad, 1); // 79 was 'unused'
file.read((uint8_t *)pad, 1); // 79 : 1 byte unused
file.read((uint8_t *)&_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
file.read((uint8_t *)&_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
file.read((uint8_t *)&_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
file.read((uint8_t *)&_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
file.read(pad, 4); // 108
file.read(pad, 4); // 108 : 4 bytes unused
file.read((uint8_t *)&_prefs->sf, sizeof(_prefs->sf)); // 112
file.read((uint8_t *)&_prefs->cr, sizeof(_prefs->cr)); // 113
file.read((uint8_t *)&_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
file.read((uint8_t *)&_prefs->multi_acks, sizeof(_prefs->multi_acks)); // 115
file.read((uint8_t *)&_prefs->bw, sizeof(_prefs->bw)); // 116
file.read((uint8_t *)&_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
file.read(pad, 3); // 121
file.read(pad, 3); // 121 : 3 bytes unused
file.read((uint8_t *)&_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
file.read((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
file.read((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
Expand All @@ -65,13 +65,16 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
file.read((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
file.read(pad, 4); // 152
file.read(pad, 4); // 152 : 4 bytes unused
file.read((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
file.read((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
file.read((uint8_t *)&_prefs->advert_loc_policy, sizeof (_prefs->advert_loc_policy)); // 161
file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
// 170
file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
file.read(pad, 4); // 169 : 4 bytes unused
file.read((uint8_t *)&_prefs->sx12xx_current_limit, sizeof(_prefs->sx12xx_current_limit)); // 173
file.read((uint8_t *)&_prefs->sx126x_rx_boosted_gain, sizeof(_prefs->sx126x_rx_boosted_gain)); // 174
// next: 175

// sanitise bad pref values
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
Expand All @@ -96,6 +99,10 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
_prefs->gps_enabled = constrain(_prefs->gps_enabled, 0, 1);
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, 0, 2);

// sanitise power settings
_prefs->sx12xx_current_limit = constrain(_prefs->sx12xx_current_limit, 0, 140); // mA
_prefs->sx126x_rx_boosted_gain = constrain(_prefs->sx126x_rx_boosted_gain, 0, 1); // boolean

file.close();
}
}
Expand Down Expand Up @@ -123,19 +130,19 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
file.write((uint8_t *)&_prefs->tx_power_dbm, sizeof(_prefs->tx_power_dbm)); // 76
file.write((uint8_t *)&_prefs->disable_fwd, sizeof(_prefs->disable_fwd)); // 77
file.write((uint8_t *)&_prefs->advert_interval, sizeof(_prefs->advert_interval)); // 78
file.write((uint8_t *)pad, 1); // 79 was 'unused'
file.write((uint8_t *)pad, 1); // 79 : 1 byte unused
file.write((uint8_t *)&_prefs->rx_delay_base, sizeof(_prefs->rx_delay_base)); // 80
file.write((uint8_t *)&_prefs->tx_delay_factor, sizeof(_prefs->tx_delay_factor)); // 84
file.write((uint8_t *)&_prefs->guest_password[0], sizeof(_prefs->guest_password)); // 88
file.write((uint8_t *)&_prefs->direct_tx_delay_factor, sizeof(_prefs->direct_tx_delay_factor)); // 104
file.write(pad, 4); // 108
file.write(pad, 4); // 108 : 4 byte unused
file.write((uint8_t *)&_prefs->sf, sizeof(_prefs->sf)); // 112
file.write((uint8_t *)&_prefs->cr, sizeof(_prefs->cr)); // 113
file.write((uint8_t *)&_prefs->allow_read_only, sizeof(_prefs->allow_read_only)); // 114
file.write((uint8_t *)&_prefs->multi_acks, sizeof(_prefs->multi_acks)); // 115
file.write((uint8_t *)&_prefs->bw, sizeof(_prefs->bw)); // 116
file.write((uint8_t *)&_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval)); // 120
file.write(pad, 3); // 121
file.write(pad, 3); // 121 : 3 bytes unused
file.write((uint8_t *)&_prefs->flood_max, sizeof(_prefs->flood_max)); // 124
file.write((uint8_t *)&_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval)); // 125
file.write((uint8_t *)&_prefs->interference_threshold, sizeof(_prefs->interference_threshold)); // 126
Expand All @@ -145,13 +152,16 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
file.write((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
file.write(pad, 4); // 152
file.write(pad, 4); // 152 : 4 bytes unused
file.write((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
file.write((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
file.write((uint8_t *)&_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy)); // 161
file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
// 170
file.write(pad, 4); // 169 : 4 bytes unused
file.write((uint8_t *)&_prefs->sx12xx_current_limit, sizeof(_prefs->sx12xx_current_limit)); // 173
file.write((uint8_t *)&_prefs->sx126x_rx_boosted_gain, sizeof(_prefs->sx126x_rx_boosted_gain)); // 174
// next: 175

file.close();
}
Expand Down Expand Up @@ -284,6 +294,14 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->node_lat));
} else if (memcmp(config, "lon", 3) == 0) {
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->node_lon));
#if defined(USE_SX1262) || defined(USE_SX1268) || defined(USE_SX1276)
} else if (memcmp(config, "radio.current", 13) == 0) {
sprintf(reply, "> %d mA", (uint8_t)_prefs->sx12xx_current_limit);
#if defined(USE_SX1262) || defined(USE_SX1268)
} else if (memcmp(config, "radio.rxbgm", 11) == 0) {
sprintf(reply, "> %s", _prefs->sx126x_rx_boosted_gain ? "on" : "off");
#endif
#endif
} else if (memcmp(config, "radio", 5) == 0) {
char freq[16], bw[16];
strcpy(freq, StrHelper::ftoa(_prefs->freq));
Expand Down Expand Up @@ -413,6 +431,20 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
_prefs->disable_fwd = memcmp(&config[7], "off", 3) == 0;
savePrefs();
strcpy(reply, _prefs->disable_fwd ? "OK - repeat is now OFF" : "OK - repeat is now ON");
#if defined(USE_SX1262) || defined(USE_SX1268) || defined(USE_SX1276)
} else if (memcmp(config, "radio.current ", 14) == 0) {
_prefs->sx12xx_current_limit = atoi(&config[14]);
strcpy(reply, "OK");
savePrefs();
_callbacks->setCurrentLimit(_prefs->sx12xx_current_limit);
#if defined(USE_SX1262) || defined(USE_SX1268)
} else if (memcmp(config, "radio.rxbgm ", 12) == 0) {
_prefs->sx126x_rx_boosted_gain = memcmp(&config[12], "on", 2) == 0;
strcpy(reply, "OK");
savePrefs();
_callbacks->setRxBoostedGain(_prefs->sx126x_rx_boosted_gain);
#endif
#endif
} else if (memcmp(config, "radio ", 6) == 0) {
strcpy(tmp, &config[6]);
const char *parts[4];
Expand Down
11 changes: 11 additions & 0 deletions src/helpers/CommonCLI.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ struct NodePrefs { // persisted to file
uint8_t advert_loc_policy;
uint32_t discovery_mod_timestamp;
float adc_multiplier;
// Power settings
uint8_t sx12xx_current_limit;
uint8_t sx126x_rx_boosted_gain;
};

class CommonCLICallbacks {
Expand Down Expand Up @@ -83,6 +86,14 @@ class CommonCLICallbacks {
virtual void restartBridge() {
// no op by default
};

virtual void setCurrentLimit(uint8_t ma) {
// no op by default
};

virtual void setRxBoostedGain(bool enable) {
// no op by default
};
};

class CommonCLI {
Expand Down
10 changes: 9 additions & 1 deletion src/helpers/radiolib/CustomSX1262.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

#include <RadioLib.h>

#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04

#define USE_SX1262

class CustomSX1262 : public SX1262 {
public:
CustomSX1262(Module *mod) : SX1262(mod) { }
Expand Down Expand Up @@ -84,4 +86,10 @@ class CustomSX1262 : public SX1262 {
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
return detected;
}

uint8_t getRxBoostedGainMode() {
uint8_t rxGain = 0;
readRegister(RADIOLIB_SX126X_REG_RX_GAIN, &rxGain, 1);
return rxGain;
}
};
10 changes: 9 additions & 1 deletion src/helpers/radiolib/CustomSX1268.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

#include <RadioLib.h>

#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
#define SX126X_IRQ_HEADER_VALID 0b0000010000 // 4 4 valid LoRa header received
#define SX126X_IRQ_PREAMBLE_DETECTED 0x04

#define USE_SX1268

class CustomSX1268 : public SX1268 {
public:
CustomSX1268(Module *mod) : SX1268(mod) { }
Expand Down Expand Up @@ -84,4 +86,10 @@ class CustomSX1268 : public SX1268 {
bool detected = (irq & SX126X_IRQ_HEADER_VALID) || (irq & SX126X_IRQ_PREAMBLE_DETECTED);
return detected;
}

uint8_t getRxBoostedGainMode() {
uint8_t rxGain = 0;
readRegister(RADIOLIB_SX126X_REG_RX_GAIN, &rxGain, 1);
return rxGain;
}
};
28 changes: 28 additions & 0 deletions src/helpers/radiolib/CustomSX1276.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#define RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED 0x02
#define RH_RF95_MODEM_STATUS_SIGNAL_DETECTED 0x01

#define USE_SX1276

class CustomSX1276 : public SX1276 {
public:
CustomSX1276(Module *mod) : SX1276(mod) { }
Expand Down Expand Up @@ -87,4 +89,30 @@ class CustomSX1276 : public SX1276 {
}
return 0; // timed out
}

int16_t getCurrentLimit() {
// read the OCP register
int16_t state = this->mod->SPIgetRegValue(RADIOLIB_SX127X_REG_OCP);
if (state < 0) {
return (state);
}
uint8_t regVal = (uint8_t)state;

// check if OCP is enabled
if ((regVal & RADIOLIB_SX127X_OCP_ON) == 0) {
return (0);
}

// get the raw value (bits 0-4)
uint8_t raw = regVal & 0x1F;

// determine the current limit based on the raw value
if (raw <= 15) {
// low range: currentLimit = 45 + raw * 5
return (45 + raw * 5);
} else {
// high range: currentLimit = raw * 10 - 30
return (raw * 10 - 30);
}
}
};
16 changes: 16 additions & 0 deletions variants/ebyte_eora_s3/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,19 @@ mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

void radio_set_current_limit(uint8_t ma) {
radio.setCurrentLimit(ma);
}

uint8_t radio_get_current_limit() {
return radio.getCurrentLimit();
}

void radio_set_rx_boosted_gain_mode(bool rxbgm) {
radio.setRxBoostedGainMode(rxbgm);
}

bool radio_get_rx_boosted_gain_mode() {
return radio.getRxBoostedGainMode();
}
5 changes: 5 additions & 0 deletions variants/ebyte_eora_s3/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();

bool radio_get_rx_boosted_gain_mode();
uint8_t radio_get_current_limit();
void radio_set_current_limit(uint8_t ma);
void radio_set_rx_boosted_gain_mode(bool rxbgm);
16 changes: 16 additions & 0 deletions variants/heltec_ct62/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,20 @@ void radio_set_tx_power(uint8_t dbm) {
mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

void radio_set_current_limit(uint8_t ma) {
radio.setCurrentLimit(ma);
}

uint8_t radio_get_current_limit() {
return radio.getCurrentLimit();
}

void radio_set_rx_boosted_gain_mode(bool rxbgm) {
radio.setRxBoostedGainMode(rxbgm);
}

bool radio_get_rx_boosted_gain_mode() {
return radio.getRxBoostedGainMode();
}
7 changes: 6 additions & 1 deletion variants/heltec_ct62/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);
void radio_set_tx_power(uint8_t dbm);
mesh::LocalIdentity radio_new_identity();
mesh::LocalIdentity radio_new_identity();

bool radio_get_rx_boosted_gain_mode();
uint8_t radio_get_current_limit();
void radio_set_current_limit(uint8_t ma);
void radio_set_rx_boosted_gain_mode(bool rxbgm);
16 changes: 16 additions & 0 deletions variants/heltec_e213/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,19 @@ mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); // create new random identity
}

void radio_set_current_limit(uint8_t ma) {
radio.setCurrentLimit(ma);
}

uint8_t radio_get_current_limit() {
return radio.getCurrentLimit();
}

void radio_set_rx_boosted_gain_mode(bool rxbgm) {
radio.setRxBoostedGainMode(rxbgm);
}

bool radio_get_rx_boosted_gain_mode() {
return radio.getRxBoostedGainMode();
}
Loading