feat: per-board TX power range, TX_POWER_MAX sentinel (-128)

- Each board exports TX_POWER_RANGE constant (min, max dBm)
- RadioConfig::validate() uses the board's range, not hardcoded limits
- TX_POWER_MAX sentinel (-128 on the wire) means "use board's maximum"
  — resolved to the actual max before storing config
- GetConfig returns the resolved actual power, not the sentinel
- Default configs in examples use TX_POWER_MAX
- Protocol docs updated
This commit is contained in:
swaits committed 2026-03-29 20:42:58 -06:00
1 parent 0b4eb04591
commit ebe9197d04
8 files changed
+46 -14

No files matched your search

+7 -5
View File
@@ -24,11 +24,12 @@ use embassy_time::Delay;
use lora_phy::mod_params::RadioError;
use lora_phy::{LoRa, RxMode};
use crate::board::{RadioDriver, RadioParts};
use crate::board::{RadioDriver, RadioParts, TX_POWER_RANGE};
use crate::channel::{CommandChannel, RadioState, RadioStatus, ResponseChannel, StatusWatch};
use crate::protocol::{self, Command, ErrorCode, RadioConfig, Response};
const MAX_PAYLOAD: usize = protocol::MAX_PAYLOAD;
const POWER_RANGE: (i8, i8) = TX_POWER_RANGE;
type Radio = LoRa<RadioDriver, Delay>;
@@ -173,13 +174,14 @@ async fn handle_cmd(
}
}
Command::SetConfig(cfg) => {
if let Err(reason) = cfg.validate() {
if let Err(reason) = cfg.validate(POWER_RANGE) {
warn!("SetConfig rejected: {}", reason);
responses
.send(Response::Error(ErrorCode::InvalidConfig))
.await;
} else {
state.config = Some(cfg);
// Resolve TX_POWER_MAX sentinel to board's actual max
state.config = Some(cfg.resolve_power(POWER_RANGE));
status.sender().send(state.clone());
responses.send(Response::Ok).await;
}
@@ -215,9 +217,9 @@ async fn handle_cmd(
}
Command::DisplayOn | Command::DisplayOff => {}
Command::Transmit { config, payload } => {
let tx_config = config.or(state.config);
let tx_config = config.map(|c| c.resolve_power(POWER_RANGE)).or(state.config);
if let Some(cfg) = tx_config {
if let Err(reason) = cfg.validate() {
if let Err(reason) = cfg.validate(POWER_RANGE) {
warn!("TX config rejected: {}", reason);
responses
.send(Response::Error(ErrorCode::InvalidConfig))