mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-01 21:08:19 +00:00
clamp TX on station G2, refactor "set af"
This commit is contained in:
@@ -256,6 +256,24 @@ config ZEPHCORE_RADIO_LR1110
|
||||
|
||||
endchoice
|
||||
|
||||
config ZEPHCORE_DEFAULT_TX_POWER_DBM
|
||||
int "Default TX power (dBm)"
|
||||
default 22
|
||||
range -9 22
|
||||
help
|
||||
Default SX1262 TX power in dBm for fresh devices (no saved prefs).
|
||||
Boards with external PA should set this lower to avoid overdriving.
|
||||
Example: Station G2 with 20dB PA gain uses 15 dBm (→ 35 dBm output).
|
||||
|
||||
config ZEPHCORE_MAX_TX_POWER_DBM
|
||||
int "Maximum TX power (dBm)"
|
||||
default 22
|
||||
range -9 22
|
||||
help
|
||||
Hard cap on SX1262 TX power. The radio adapter clamps any value
|
||||
above this, protecting external PAs from damage.
|
||||
Example: Station G2 caps at 19 dBm to stay below PA P1dB (35 dBm).
|
||||
|
||||
endmenu # Radio Configuration
|
||||
|
||||
menu "Board Configuration"
|
||||
|
||||
@@ -186,6 +186,11 @@ void LoRaRadioBase::buildModemConfig(struct lora_modem_config &cfg, bool tx)
|
||||
cfg.preamble_len = LoRaConfig::PREAMBLE_LEN;
|
||||
cfg.tx_power = _prefs ? (int8_t)_prefs->tx_power_dbm
|
||||
: LoRaConfig::TX_POWER_DBM;
|
||||
#ifdef CONFIG_ZEPHCORE_MAX_TX_POWER_DBM
|
||||
if (cfg.tx_power > CONFIG_ZEPHCORE_MAX_TX_POWER_DBM) {
|
||||
cfg.tx_power = CONFIG_ZEPHCORE_MAX_TX_POWER_DBM;
|
||||
}
|
||||
#endif
|
||||
cfg.tx = tx;
|
||||
cfg.iq_inverted = false;
|
||||
cfg.public_network = false;
|
||||
|
||||
@@ -17,5 +17,11 @@ CONFIG_BT_DIS_MODEL_NUMBER_STR="BQ Station G2"
|
||||
# Radio type — SX1262 via Zephyr native LoRa driver
|
||||
CONFIG_ZEPHCORE_RADIO_NATIVE=y
|
||||
|
||||
# TX power limits — Station G2 has ~20dB external PA.
|
||||
# Default 15 dBm → ~35 dBm output (P1dB point).
|
||||
# Cap at 19 dBm → ~39 dBm absolute max (matches Arduino MAX_LORA_TX_POWER).
|
||||
CONFIG_ZEPHCORE_DEFAULT_TX_POWER_DBM=15
|
||||
CONFIG_ZEPHCORE_MAX_TX_POWER_DBM=19
|
||||
|
||||
# Flash size — 16MB (override Zephyr default)
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||
|
||||
@@ -111,6 +111,11 @@ void CommonCLI::loadPrefs(const char* path) {
|
||||
_prefs->sf = constrain(_prefs->sf, (uint8_t)5, (uint8_t)12);
|
||||
_prefs->cr = constrain(_prefs->cr, (uint8_t)5, (uint8_t)8);
|
||||
_prefs->tx_power_dbm = constrain(_prefs->tx_power_dbm, (uint8_t)1, (uint8_t)30);
|
||||
#ifdef CONFIG_ZEPHCORE_MAX_TX_POWER_DBM
|
||||
if (_prefs->tx_power_dbm > CONFIG_ZEPHCORE_MAX_TX_POWER_DBM) {
|
||||
_prefs->tx_power_dbm = (uint8_t)CONFIG_ZEPHCORE_MAX_TX_POWER_DBM;
|
||||
}
|
||||
#endif
|
||||
_prefs->multi_acks = constrain(_prefs->multi_acks, (uint8_t)0, (uint8_t)1);
|
||||
_prefs->adc_multiplier = constrain(_prefs->adc_multiplier, 0.0f, 10.0f);
|
||||
_prefs->powersaving_enabled = constrain(_prefs->powersaving_enabled, (uint8_t)0, (uint8_t)1);
|
||||
@@ -317,7 +322,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
} else if (memcmp(command, "get ", 4) == 0) {
|
||||
const char* config = &command[4];
|
||||
if (memcmp(config, "af", 2) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %.0f%%", (double)_prefs->airtime_factor);
|
||||
int dc = (_prefs->airtime_factor == 0.0f) ? 100 : (int)_prefs->airtime_factor;
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> Duty Cycle: %d%%", dc);
|
||||
} else if (memcmp(config, "int.thresh", 10) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %u", (uint32_t)_prefs->interference_threshold);
|
||||
} else if (memcmp(config, "agc.reset.interval", 18) == 0) {
|
||||
@@ -391,9 +397,15 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
} else if (memcmp(command, "set ", 4) == 0) {
|
||||
const char* config = &command[4];
|
||||
if (memcmp(config, "af ", 3) == 0) {
|
||||
_prefs->airtime_factor = atof(&config[3]);
|
||||
int val = atoi(&config[3]);
|
||||
if (val <= 0 || val >= 100) {
|
||||
_prefs->airtime_factor = 0.0f;
|
||||
} else {
|
||||
_prefs->airtime_factor = (float)val;
|
||||
}
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
int dc = (_prefs->airtime_factor == 0.0f) ? 100 : (int)_prefs->airtime_factor;
|
||||
snprintf(reply, CLI_REPLY_SIZE, "Duty Cycle set: %d%%", dc);
|
||||
} else if (memcmp(config, "int.thresh ", 11) == 0) {
|
||||
_prefs->interference_threshold = atoi(&config[11]);
|
||||
savePrefs();
|
||||
@@ -532,10 +544,16 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else if (memcmp(config, "tx ", 3) == 0) {
|
||||
_prefs->tx_power_dbm = atoi(&config[3]);
|
||||
int val = atoi(&config[3]);
|
||||
#ifdef CONFIG_ZEPHCORE_MAX_TX_POWER_DBM
|
||||
if (val > CONFIG_ZEPHCORE_MAX_TX_POWER_DBM) {
|
||||
val = CONFIG_ZEPHCORE_MAX_TX_POWER_DBM;
|
||||
}
|
||||
#endif
|
||||
_prefs->tx_power_dbm = (uint8_t)val;
|
||||
savePrefs();
|
||||
_callbacks->setTxPower(_prefs->tx_power_dbm);
|
||||
strcpy(reply, "OK");
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - tx power=%u dBm", (uint32_t)_prefs->tx_power_dbm);
|
||||
} else if (sender_timestamp == 0 && memcmp(config, "freq ", 5) == 0) {
|
||||
_prefs->freq = atof(&config[5]);
|
||||
savePrefs();
|
||||
|
||||
@@ -90,7 +90,11 @@ static inline void initNodePrefs(NodePrefs* prefs) {
|
||||
prefs->bw = 62.5f; // LoRaConfig::BANDWIDTH
|
||||
prefs->sf = 8; // LoRaConfig::SPREADING_FACTOR
|
||||
prefs->cr = 8; // CR 4/8 (MeshCore uses 5-8 for CR 4/5 through 4/8)
|
||||
#ifdef CONFIG_ZEPHCORE_DEFAULT_TX_POWER_DBM
|
||||
prefs->tx_power_dbm = CONFIG_ZEPHCORE_DEFAULT_TX_POWER_DBM;
|
||||
#else
|
||||
prefs->tx_power_dbm = 22; // LoRaConfig::TX_POWER_DBM
|
||||
#endif
|
||||
prefs->disable_fwd = 0;
|
||||
prefs->advert_interval = 60; // 2 minutes (value / 2)
|
||||
prefs->flood_advert_interval = 12; // 12 hours
|
||||
|
||||
Reference in New Issue
Block a user