Skip to content

Commit

Permalink
extend PhyRxTx to handle antenna gain and max power
Browse files Browse the repository at this point in the history
  • Loading branch information
lthiery committed Nov 6, 2023
1 parent a5d1824 commit 3857fec
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 10 deletions.
18 changes: 16 additions & 2 deletions device/src/async_device/lora_radio.rs
Expand Up @@ -14,14 +14,20 @@ where
{
pub(crate) lora: LoRa<RK, DLY>,
rx_pkt_params: Option<lora_phy::mod_params::PacketParams>,
antenna_gain: i8,
max_radio_power: u8,
}
impl<RK, DLY> LoRaRadio<RK, DLY>
where
RK: RadioKind,
DLY: DelayUs,
{
pub fn new(lora: LoRa<RK, DLY>) -> Self {
Self { lora, rx_pkt_params: None }
/// The antenna gain in dBi should also take into account any board losses.
///
/// The max power the radio can be instructed to transmit at. When preparing an instruction
/// for the radio, this max power will be used an upper bound.
pub fn new(lora: LoRa<RK, DLY>, antenna_gain: i8, max_radio_power: u8) -> Self {
Self { lora, antenna_gain, max_radio_power, rx_pkt_params: None }
}
}

Expand Down Expand Up @@ -70,6 +76,14 @@ where
{
type PhyError = Error;

fn get_antenna_gain(&self) -> i8 {
self.antenna_gain
}

fn max_radio_power(&self) -> u8 {
self.max_radio_power
}

async fn tx(&mut self, config: TxConfig, buffer: &[u8]) -> Result<u32, Self::PhyError> {
let mdltn_params = self.lora.create_modulation_params(
config.rf.bb.sf,
Expand Down
8 changes: 6 additions & 2 deletions device/src/async_device/mod.rs
Expand Up @@ -195,12 +195,14 @@ where
pub async fn join(&mut self, join_mode: &JoinMode) -> Result<JoinResponse, Error<R::PhyError>> {
match join_mode {
JoinMode::OTAA { deveui, appeui, appkey } => {
let (tx_config, _) = self.mac.join_otaa::<C, G, N>(
let (mut tx_config, _) = self.mac.join_otaa::<C, G, N>(
&mut self.rng,
NetworkCredentials::new(*appeui, *deveui, *appkey),
&mut self.radio_buffer,
);

tx_config.adjust_power(self.radio.get_antenna_gain(), self.radio.max_radio_power());

// Transmit the join payload
let ms = self
.radio
Expand Down Expand Up @@ -233,11 +235,13 @@ where
confirmed: bool,
) -> Result<SendResponse, Error<R::PhyError>> {
// Prepare transmission buffer
let (tx_config, _fcnt_up) = self.mac.send::<C, G, N>(
let (mut tx_config, _fcnt_up) = self.mac.send::<C, G, N>(
&mut self.rng,
&mut self.radio_buffer,
&SendData { data, fport, confirmed },
)?;
tx_config.adjust_power(self.radio.get_antenna_gain(), self.radio.max_radio_power());

// Transmit our data packet
let ms = self
.radio
Expand Down
8 changes: 8 additions & 0 deletions device/src/async_device/radio.rs
Expand Up @@ -29,6 +29,14 @@ pub trait PhyRxTx: Sized {
#[cfg(not(feature = "defmt"))]
type PhyError;

fn get_antenna_gain(&self) -> i8 {
0
}

/// The max power the radio can be instructed to transmit at. When preparing an instruction
/// for the radio, this max power will be used an upper bound.
fn max_radio_power(&self) -> u8;

/// Transmit data buffer with the given transceiver configuration. The returned future
/// should only complete once data have been transmitted.
async fn tx(&mut self, config: TxConfig, buf: &[u8]) -> Result<u32, Self::PhyError>;
Expand Down
3 changes: 3 additions & 0 deletions device/src/async_device/test/radio.rs
Expand Up @@ -31,6 +31,9 @@ pub struct TestRadio {
impl PhyRxTx for TestRadio {
type PhyError = &'static str;

fn max_radio_power(&self) -> u8 {
26
}
async fn tx(&mut self, config: TxConfig, buffer: &[u8]) -> Result<u32, Self::PhyError> {
let length = buffer.len();
// stash the uplink, to be consumed by channel or by rx handler
Expand Down
4 changes: 2 additions & 2 deletions device/src/nb_device/mod.rs
Expand Up @@ -13,7 +13,7 @@ type TimestampMs = u32;

pub struct Device<R, C, RNG, const N: usize>
where
R: radio::PhyRxTx + Timings,
R: PhyRxTx + Timings,
C: CryptoFactory + Default,
RNG: RngCore,
{
Expand Down Expand Up @@ -108,7 +108,7 @@ where
}
}

pub(crate) struct Shared<R: radio::PhyRxTx + Timings, RNG: RngCore, const N: usize> {
pub(crate) struct Shared<R: PhyRxTx + Timings, RNG: RngCore, const N: usize> {
pub(crate) radio: R,
pub(crate) rng: RNG,
pub(crate) tx_buffer: RadioBuffer<N>,
Expand Down
9 changes: 9 additions & 0 deletions device/src/nb_device/radio.rs
Expand Up @@ -33,6 +33,15 @@ pub trait PhyRxTx {
type PhyError: fmt::Debug;
type PhyResponse: fmt::Debug;

/// Returns the antenna gain in dBi. You should take into account any board losses here.
fn get_antenna_gain(&self) -> i8 {
0
}

/// The max power the radio can be instructed to transmit at. When preparing an instruction
/// for the radio, this max power will be used an upper bound.
fn max_radio_power(&self) -> u8;

fn get_mut_radio(&mut self) -> &mut Self;

// we require mutability so we may decrypt in place
Expand Down
10 changes: 6 additions & 4 deletions device/src/nb_device/state.rs
Expand Up @@ -149,18 +149,20 @@ impl Idle {
let response = match event {
// tolerate unexpected timeout
Event::Join(creds) => {
let (tx_config, dev_nonce) = mac.join_otaa::<C, RNG, N>(rng, creds, buf);
let (mut tx_config, dev_nonce) = mac.join_otaa::<C, RNG, N>(rng, creds, buf);
tx_config.adjust_power(radio.get_antenna_gain(), radio.max_radio_power());
IntermediateResponse::RadioTx((Frame::Join, tx_config, dev_nonce as u32))
}
Event::TimeoutFired => IntermediateResponse::EarlyReturn(Ok(Response::NoUpdate)),
Event::RadioEvent(_radio_event) => {
IntermediateResponse::EarlyReturn(Err(Error::RadioEventWhileIdle.into()))
}
Event::SendDataRequest(send_data) => {
let tx_config = mac.send::<C, RNG, N>(rng, buf, &send_data);
match tx_config {
let result = mac.send::<C, RNG, N>(rng, buf, &send_data);
match result {
Err(e) => IntermediateResponse::EarlyReturn(Err(e.into())),
Ok((tx_config, fcnt_up)) => {
Ok((mut tx_config, fcnt_up)) => {
tx_config.adjust_power(radio.get_antenna_gain(), radio.max_radio_power());
IntermediateResponse::RadioTx((Frame::Data, tx_config, fcnt_up))
}
}
Expand Down
4 changes: 4 additions & 0 deletions device/src/nb_device/test/util.rs
Expand Up @@ -45,6 +45,10 @@ impl PhyRxTx for TestRadio {
type PhyError = &'static str;
type PhyResponse = ();

fn max_radio_power(&self) -> u8 {
26
}

fn get_mut_radio(&mut self) -> &mut Self {
self
}
Expand Down
7 changes: 7 additions & 0 deletions device/src/radio.rs
Expand Up @@ -14,6 +14,13 @@ pub struct TxConfig {
pub rf: RfConfig,
}

impl TxConfig {
pub fn adjust_power(&mut self, antenna_gain: i8, max_power: u8) {
self.pw -= antenna_gain;
self.pw = core::cmp::min(self.pw, max_power as i8);
}
}

#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct RxQuality {
Expand Down
1 change: 1 addition & 0 deletions device/src/region/fixed_channel_plans/mod.rs
Expand Up @@ -58,6 +58,7 @@ impl<const D: usize, F: FixedChannelRegion<D>> FixedChannelPlan<D, F> {
self.channel_mask.set_bank(7, mask);
}

#[allow(unused)]
pub fn get_max_payload_length(datarate: DR, repeater_compatible: bool, dwell_time: bool) -> u8 {
F::get_max_payload_length(datarate, repeater_compatible, dwell_time)
}
Expand Down

0 comments on commit 3857fec

Please sign in to comment.