diff --git a/src/internal_state.rs b/src/internal_state.rs index ec1edc9556f7537d6098cb07a9a2655989dfe552..b4365630d6eece59ff3d42eb6e30cd1437e5c630 100644 --- a/src/internal_state.rs +++ b/src/internal_state.rs @@ -1,17 +1,14 @@ // Tracks the state of our instance, *not* the state of the radio. #[derive(Debug)] -pub enum InternalState<'a, const PACKET_LEN: usize, T: AsRef<[u8]>> { +pub enum InternalState { Idle, Rx { - data: &'a mut [u8; PACKET_LEN], i: usize, received: bool, rssi: Option<f64>, }, Tx { - data: T, i: usize, len: usize, - finished: bool, }, } diff --git a/src/lib.rs b/src/lib.rs index ce9c5fd17408069e04e7d0b985bcdfd1b0e27f70..3b79878bf01ac22ffe7b409dd74cb7605c69f429 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,22 +22,23 @@ use state::State; use crate::internal_radio::InternalRadio; -pub struct Rf4463<'a, const MAX_PACKET_LEN: usize, Spi, SdnPin, CsPin, Delay, T: AsRef<[u8]>> { +/// All the rx_buf methods MUST be passed the same rx_buf +/// All the tx_buf methods MUST be passed the same tx_buf +/// We do this because we don't keep that data locally for space reasons +/// And we don't keep references to it for lifetime reasons! +pub struct Rf4463<Spi, SdnPin, CsPin, Delay> { radio: InternalRadio<Spi, SdnPin, CsPin, Delay>, - state: InternalState<'a, MAX_PACKET_LEN, T>, + state: InternalState, rx_forever: bool, channel: u8, } impl< - 'a, - const MAX_PACKET_LEN: usize, Spi: Transfer<u8>, SdnPin: OutputPin<Error = Infallible>, CsPin: OutputPin<Error = Infallible>, Delay: DelayUs<u16>, - T: AsRef<[u8]>, - > Rf4463<'a, MAX_PACKET_LEN, Spi, SdnPin, CsPin, Delay, T> + > Rf4463<Spi, SdnPin, CsPin, Delay> where Spi::Error: Debug, { @@ -48,11 +49,6 @@ where delay: Delay, config: &mut [u8], ) -> Result<Self, RfError<Spi::Error>> { - assert!( - MAX_PACKET_LEN < 8192, - "Packet length cannot be above 8191 bytes" - ); - cs.set_high().unwrap(); Ok(Self { @@ -93,19 +89,13 @@ where } // Len is none when using a variable-length packet - pub fn start_rx( - &mut self, - buf: &'a mut [u8; MAX_PACKET_LEN], - len: Option<usize>, - rx_forever: bool, - ) -> Result<(), Spi::Error> { + pub fn start_rx(&mut self, len: Option<usize>, rx_forever: bool) -> Result<(), Spi::Error> { self.radio.clear_fifo()?; self.radio.clear_ph_and_modem_interrupts()?; let len = len.unwrap_or(0); self.state = InternalState::Rx { - data: buf, i: 0, received: false, rssi: None, @@ -131,72 +121,52 @@ where Ok(()) } - /// Panics if rx_forever is true and new_buf is None - pub fn finish_rx( + pub fn finish_rx<'a>( &mut self, - new_buf: Option<&'a mut [u8; MAX_PACKET_LEN]>, - ) -> Result<Option<RxPacket<MAX_PACKET_LEN>>, Spi::Error> { - let mut old_state = InternalState::Idle; - core::mem::swap(&mut old_state, &mut self.state); - - let ret = match old_state { - InternalState::Rx { - data, - received, - i, - rssi, - } if received => { - let ret_rssi = match rssi { + rx_buf: &'a mut [u8], + ) -> Result<Option<RxPacket<'a>>, Spi::Error> { + let pkt = match self.state { + InternalState::Rx { received, i, rssi } if received => { + let rssi = match rssi { Some(x) => x, - None => self.radio.get_rssi()?, + None => self.get_rssi()?, }; + let ret = Some(RxPacket::new(rx_buf, i, rssi)); + if self.rx_forever { - let new_buf = new_buf.expect("rx_forever=true and no replacement buffer given"); self.radio.clear_ph_and_modem_interrupts()?; self.state = InternalState::Rx { - data: new_buf, i: 0, received: false, rssi: None, }; + } else { + self.state = InternalState::Idle; } - // state is implicitly Idle now if rx_forever=false, based on the mem::swap we did above - - Some(RxPacket::new(data, i, ret_rssi)) + ret } - _ => { - // swap our states back - core::mem::swap(&mut old_state, &mut self.state); - - None - } + _ => None, }; - Ok(ret) + Ok(pkt) } /// Panics if data length is > 8191 - pub fn start_tx(&mut self, data: T, len: usize) -> Result<(), TxError<Spi::Error>> { - assert!( - MAX_PACKET_LEN < 8192, - "Packet length cannot be above 8191 bytes" - ); - - if len > data.as_ref().len() { - return Err(TxError::TooMuchData); - } + pub fn start_tx(&mut self, tx_buf: &[u8]) -> Result<(), TxError<Spi::Error>> { + let len = tx_buf.len(); + assert!(len < 8192, "Packet length cannot be above 8191 bytes"); self.radio.clear_fifo().txe()?; self.radio.clear_ph_and_modem_interrupts().txe()?; // 128-byte TX buffer - let i = len.min(128); + let i = tx_buf.len().min(128); let mut segment = [0; 128]; - segment[..i].copy_from_slice(&data.as_ref()[..i]); + segment[..i].copy_from_slice(&tx_buf[..i]); self.radio.with_cs(|s| { s.spi_transfer_byte(WRITE_TX_FIFO).txe()?; @@ -217,37 +187,18 @@ where ]) .txe()?; - self.state = InternalState::Tx { - data, - i, - len, - finished: false, - }; + self.state = InternalState::Tx { i, len }; Ok(()) } - pub fn finish_tx(&mut self) -> Option<T> { - let mut old_state = InternalState::Idle; - core::mem::swap(&mut self.state, &mut old_state); - - match old_state { - InternalState::Tx { data, finished, .. } if finished => { - self.state = InternalState::Idle; - - Some(data) - } - - _ => { - // swap them back so that the state is left untouched - core::mem::swap(&mut self.state, &mut old_state); - - None - } - } - } - - pub fn interrupt(&mut self) -> Result<(), TransferError<Spi::Error>> { + /// You only *need* to pass in rx_buf or tx_buf depending on what we're doing, + /// But you're free to pass in both without any issues + pub fn interrupt( + &mut self, + rx_buf: Option<&mut [u8]>, + tx_buf: Option<&[u8]>, + ) -> Result<(), TransferError<Spi::Error>> { if self.radio.fifo_underflow_pending().te()? { return Err(TransferError::FifoOverflow); } @@ -263,7 +214,8 @@ where *received = true; } - if let Err(e) = self.rx_step() { + if let Err(e) = self.rx_step(rx_buf.expect("We're receiving but there's no rx buf")) + { // something went wrong. Go back to idle self.state = InternalState::Idle; let _ = self.radio.sleep(); @@ -272,12 +224,14 @@ where } } - InternalState::Tx { finished, .. } => { + InternalState::Tx { .. } => { if self.radio.packet_sent_pending().te()? { - *finished = true; + self.state = InternalState::Idle; } - if let Err(e) = self.tx_step() { + if let Err(e) = + self.tx_step(tx_buf.expect("We've transmitting but there's no tx buf")) + { // something went wrong. Go back to idle self.state = InternalState::Idle; let _ = self.radio.sleep(); @@ -290,9 +244,9 @@ where Ok(()) } - fn rx_step(&mut self) -> Result<(), TransferError<Spi::Error>> { - let (data, i, rssi) = match &mut self.state { - InternalState::Rx { data, i, rssi, .. } => (data, i, rssi), + fn rx_step(&mut self, rx_buf: &mut [u8]) -> Result<(), TransferError<Spi::Error>> { + let (i, rssi) = match &mut self.state { + InternalState::Rx { i, rssi, .. } => (i, rssi), _ => return Ok(()), }; @@ -301,7 +255,7 @@ where return Ok(()); } - if fifo_len + *i > MAX_PACKET_LEN { + if fifo_len + *i > rx_buf.len() { return Err(TransferError::TooMuchData); } @@ -309,7 +263,7 @@ where return Err(TransferError::FifoOverflow); } - let data = &mut data[*i..(*i + fifo_len)]; + let data = &mut rx_buf[*i..(*i + fifo_len)]; self.radio .with_cs(|s| { s.spi_transfer_byte(READ_RX_FIFO)?; @@ -328,19 +282,14 @@ where Ok(()) } - fn tx_step(&mut self) -> Result<(), TransferError<Spi::Error>> { - let (data, data_len, i) = match &mut self.state { - InternalState::Tx { - data, - i, - len, - finished, - } if !*finished => (data, *len, i), + fn tx_step(&mut self, tx_buf: &[u8]) -> Result<(), TransferError<Spi::Error>> { + let (data_len, i) = match &mut self.state { + InternalState::Tx { i, len } => (*len, i), _ => return Ok(()), }; // only look at the slice we haven't sent yet - let data = &data.as_ref()[*i..data_len]; + let data = &tx_buf[*i..data_len]; let len: usize = self.radio.tx_fifo_space().te()?.into(); let len = len.min(data.len()); diff --git a/src/rx.rs b/src/rx.rs index 644281d0d513475631b85f965320d05390e99b60..75026ab8fcf49a7f9e16f787f29d50b5b2bb6e1f 100644 --- a/src/rx.rs +++ b/src/rx.rs @@ -1,12 +1,12 @@ #[derive(Debug)] -pub struct RxPacket<'a, const N: usize> { - data: &'a mut [u8; N], +pub struct RxPacket<'a> { + data: &'a mut [u8], i: usize, rssi: f64, } -impl<'a, const N: usize> RxPacket<'a, N> { - pub(crate) fn new(data: &'a mut [u8; N], i: usize, rssi: f64) -> Self { +impl<'a> RxPacket<'a> { + pub(crate) fn new(data: &'a mut [u8], i: usize, rssi: f64) -> Self { Self { data, i, rssi } } @@ -18,7 +18,7 @@ impl<'a, const N: usize> RxPacket<'a, N> { self.rssi } - pub fn into_buf(self) -> &'a mut [u8; N] { + pub fn into_buf(self) -> &'a mut [u8] { self.data } }