Skip to content
Snippets Groups Projects
Commit 5b2696fd authored by Stephen D's avatar Stephen D
Browse files

support variable length packets

parent 978bc249
No related branches found
No related tags found
1 merge request!2Variable packet length
Pipeline #3220 passed
...@@ -23,12 +23,21 @@ pub enum TransferError<SE: Debug> { ...@@ -23,12 +23,21 @@ pub enum TransferError<SE: Debug> {
SpiError(SE), SpiError(SE),
} }
#[derive(Debug)]
pub enum TxError<SE: Debug> {
// Given slice was bigger than the maximum packet size
TooMuchData,
SpiError(SE),
}
pub(crate) trait SpiErrorToOtherError<T, E: Debug> { pub(crate) trait SpiErrorToOtherError<T, E: Debug> {
fn re(self) -> Result<T, RfError<E>> fn re(self) -> Result<T, RfError<E>>
where where
Self: Sized; Self: Sized;
fn te(self) -> Result<T, TransferError<E>>; fn te(self) -> Result<T, TransferError<E>>;
fn txe(self) -> Result<T, TxError<E>>;
} }
impl<T, E: Debug> SpiErrorToOtherError<T, E> for Result<T, E> { impl<T, E: Debug> SpiErrorToOtherError<T, E> for Result<T, E> {
...@@ -39,4 +48,8 @@ impl<T, E: Debug> SpiErrorToOtherError<T, E> for Result<T, E> { ...@@ -39,4 +48,8 @@ impl<T, E: Debug> SpiErrorToOtherError<T, E> for Result<T, E> {
fn te(self) -> Result<T, TransferError<E>> { fn te(self) -> Result<T, TransferError<E>> {
self.map_err(|e| TransferError::SpiError(e)) self.map_err(|e| TransferError::SpiError(e))
} }
fn txe(self) -> Result<T, TxError<E>> {
self.map_err(|e| TxError::SpiError(e))
}
} }
...@@ -11,5 +11,6 @@ pub enum InternalState<const PACKET_LEN: usize> { ...@@ -11,5 +11,6 @@ pub enum InternalState<const PACKET_LEN: usize> {
Tx { Tx {
data: [u8; PACKET_LEN], data: [u8; PACKET_LEN],
i: usize, i: usize,
len: usize,
}, },
} }
...@@ -5,6 +5,7 @@ mod consts; ...@@ -5,6 +5,7 @@ mod consts;
pub mod error; pub mod error;
mod internal_radio; mod internal_radio;
mod internal_state; mod internal_state;
pub mod rx;
pub(crate) mod state; pub(crate) mod state;
use core::{convert::Infallible, fmt::Debug}; use core::{convert::Infallible, fmt::Debug};
...@@ -14,25 +15,26 @@ use embedded_hal::{ ...@@ -14,25 +15,26 @@ use embedded_hal::{
}; };
use consts::*; use consts::*;
use error::{RfError, SpiErrorToOtherError, TransferError}; use error::{RfError, SpiErrorToOtherError, TransferError, TxError};
use internal_state::InternalState; use internal_state::InternalState;
use rx::RxPacket;
use state::State; use state::State;
use crate::internal_radio::InternalRadio; use crate::internal_radio::InternalRadio;
pub struct Rf4463<const PACKET_LEN: usize, Spi, SdnPin, CsPin, Delay> { pub struct Rf4463<const MAX_PACKET_LEN: usize, Spi, SdnPin, CsPin, Delay> {
radio: InternalRadio<Spi, SdnPin, CsPin, Delay>, radio: InternalRadio<Spi, SdnPin, CsPin, Delay>,
state: InternalState<PACKET_LEN>, state: InternalState<MAX_PACKET_LEN>,
rx_forever: bool, rx_forever: bool,
} }
impl< impl<
const PACKET_LEN: usize, const MAX_PACKET_LEN: usize,
Spi: Transfer<u8>, Spi: Transfer<u8>,
SdnPin: OutputPin<Error = Infallible>, SdnPin: OutputPin<Error = Infallible>,
CsPin: OutputPin<Error = Infallible>, CsPin: OutputPin<Error = Infallible>,
Delay: DelayUs<u16>, Delay: DelayUs<u16>,
> Rf4463<PACKET_LEN, Spi, SdnPin, CsPin, Delay> > Rf4463<MAX_PACKET_LEN, Spi, SdnPin, CsPin, Delay>
where where
Spi::Error: Debug, Spi::Error: Debug,
{ {
...@@ -44,7 +46,7 @@ where ...@@ -44,7 +46,7 @@ where
config: &mut [u8], config: &mut [u8],
) -> Result<Self, RfError<Spi::Error>> { ) -> Result<Self, RfError<Spi::Error>> {
assert!( assert!(
PACKET_LEN < 8192, MAX_PACKET_LEN < 8192,
"Packet length cannot be above 8191 bytes" "Packet length cannot be above 8191 bytes"
); );
...@@ -78,7 +80,7 @@ where ...@@ -78,7 +80,7 @@ where
self.radio.clear_ph_and_modem_interrupts()?; self.radio.clear_ph_and_modem_interrupts()?;
self.state = InternalState::Rx { self.state = InternalState::Rx {
data: [0; PACKET_LEN], data: [0; MAX_PACKET_LEN],
i: 0, i: 0,
received: false, received: false,
rssi: None, rssi: None,
...@@ -88,8 +90,8 @@ where ...@@ -88,8 +90,8 @@ where
START_RX, START_RX,
0, 0,
0, 0,
(PACKET_LEN >> 8).try_into().unwrap(), (MAX_PACKET_LEN >> 8).try_into().unwrap(),
(PACKET_LEN & 0xff).try_into().unwrap(), (MAX_PACKET_LEN & 0xff).try_into().unwrap(),
State::Rx.into(), State::Rx.into(),
if rx_forever { if rx_forever {
State::Rx.into() State::Rx.into()
...@@ -104,26 +106,26 @@ where ...@@ -104,26 +106,26 @@ where
Ok(()) Ok(())
} }
pub fn finish_rx(&mut self) -> Result<Option<([u8; PACKET_LEN], f64)>, Spi::Error> { pub fn finish_rx(&mut self) -> Result<Option<RxPacket<MAX_PACKET_LEN>>, Spi::Error> {
let pkt = match self.state { let pkt = match self.state {
InternalState::Rx { InternalState::Rx {
data, data,
received, received,
i, i,
rssi, rssi,
} if i == PACKET_LEN && received => { } if received => {
let rssi = match rssi { let rssi = match rssi {
Some(x) => x, Some(x) => x,
None => self.get_rssi()?, None => self.get_rssi()?,
}; };
let ret = Some((data, rssi)); let ret = Some(RxPacket::new(data, i, rssi));
if self.rx_forever { if self.rx_forever {
self.radio.clear_ph_and_modem_interrupts()?; self.radio.clear_ph_and_modem_interrupts()?;
self.state = InternalState::Rx { self.state = InternalState::Rx {
data: [0; PACKET_LEN], data: [0; MAX_PACKET_LEN],
i: 0, i: 0,
received: false, received: false,
rssi: None, rssi: None,
...@@ -141,31 +143,46 @@ where ...@@ -141,31 +143,46 @@ where
Ok(pkt) Ok(pkt)
} }
pub fn start_tx(&mut self, mut data: [u8; PACKET_LEN]) -> Result<(), Spi::Error> { pub fn start_tx(&mut self, data: &[u8]) -> Result<(), TxError<Spi::Error>> {
self.radio.clear_fifo()?; let len = data.len();
self.radio.clear_ph_and_modem_interrupts()?; if len > MAX_PACKET_LEN {
return Err(TxError::TooMuchData);
}
self.radio.clear_fifo().txe()?;
self.radio.clear_ph_and_modem_interrupts().txe()?;
// 128-byte TX buffer // 128-byte TX buffer
let i = data.len().min(128); let i = data.len().min(128);
let mut segment = [0; 128];
segment[..i].copy_from_slice(&data[..i]);
self.radio.with_cs(|s| { self.radio.with_cs(|s| {
s.spi_transfer_byte(WRITE_TX_FIFO)?; s.spi_transfer_byte(WRITE_TX_FIFO).txe()?;
s.spi.transfer(&mut data[0..i])?; s.spi.transfer(&mut segment[..i]).txe()?;
Ok(()) Ok(())
})?; })?;
self.radio.send_command::<0>(&mut [ self.radio
START_TX, .send_command::<0>(&mut [
0, START_TX,
u8::from(State::Sleep) << 4, 0,
(PACKET_LEN >> 8).try_into().unwrap(), u8::from(State::Sleep) << 4,
(PACKET_LEN & 0xff).try_into().unwrap(), (MAX_PACKET_LEN >> 8).try_into().unwrap(),
0, (MAX_PACKET_LEN & 0xff).try_into().unwrap(),
0, 0,
])?; 0,
])
self.state = InternalState::Tx { data, i }; .txe()?;
let mut padded_data = [0; MAX_PACKET_LEN];
padded_data[0..len].copy_from_slice(data);
self.state = InternalState::Tx {
data: padded_data,
i,
len,
};
Ok(()) Ok(())
} }
...@@ -219,12 +236,12 @@ where ...@@ -219,12 +236,12 @@ where
_ => return Ok(()), _ => return Ok(()),
}; };
let len: usize = self.radio.rx_fifo_len().te()?.into(); let fifo_len: usize = self.radio.rx_fifo_len().te()?.into();
if len == 0 { if fifo_len == 0 {
return Ok(()); return Ok(());
} }
if len + *i > PACKET_LEN { if fifo_len + *i > MAX_PACKET_LEN {
return Err(TransferError::TooMuchData); return Err(TransferError::TooMuchData);
} }
...@@ -232,7 +249,7 @@ where ...@@ -232,7 +249,7 @@ where
return Err(TransferError::FifoOverflow); return Err(TransferError::FifoOverflow);
} }
let data = &mut data[*i..(*i + len)]; let data = &mut data[*i..(*i + fifo_len)];
self.radio self.radio
.with_cs(|s| { .with_cs(|s| {
s.spi_transfer_byte(READ_RX_FIFO)?; s.spi_transfer_byte(READ_RX_FIFO)?;
...@@ -246,14 +263,14 @@ where ...@@ -246,14 +263,14 @@ where
*rssi = Some(self.radio.get_rssi().te()?) *rssi = Some(self.radio.get_rssi().te()?)
} }
*i += len; *i += fifo_len;
Ok(()) Ok(())
} }
fn tx_step(&mut self) -> Result<(), TransferError<Spi::Error>> { fn tx_step(&mut self) -> Result<(), TransferError<Spi::Error>> {
let (data, i) = match &mut self.state { let (data, i) = match &mut self.state {
InternalState::Tx { data, i, .. } => (data, i), InternalState::Tx { data, i, len } => (&mut data[0..*len], i),
_ => return Ok(()), _ => return Ok(()),
}; };
......
pub struct RxPacket<const N: usize> {
data: [u8; N],
i: usize,
rssi: f64,
}
impl<const N: usize> RxPacket<N> {
pub(crate) fn new(data: [u8; N], i: usize, rssi: f64) -> Self {
Self { data, i, rssi }
}
pub fn data(&self) -> &[u8] {
&self.data[..self.i]
}
pub fn rssi(&self) -> f64 {
self.rssi
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment