From ed95edbc7276795687385e3f594ce08b5e6c1c73 Mon Sep 17 00:00:00 2001 From: Stephen D <webmaster@scd31.com> Date: Sun, 5 Nov 2023 13:19:22 -0400 Subject: [PATCH] fixes --- src/internal_state.rs | 5 ++-- src/lib.rs | 58 ++++++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/internal_state.rs b/src/internal_state.rs index ef64e3b..ec1edc9 100644 --- a/src/internal_state.rs +++ b/src/internal_state.rs @@ -1,6 +1,6 @@ // Tracks the state of our instance, *not* the state of the radio. #[derive(Debug)] -pub enum InternalState<'a, const PACKET_LEN: usize> { +pub enum InternalState<'a, const PACKET_LEN: usize, T: AsRef<[u8]>> { Idle, Rx { data: &'a mut [u8; PACKET_LEN], @@ -9,8 +9,9 @@ pub enum InternalState<'a, const PACKET_LEN: usize> { rssi: Option<f64>, }, Tx { - data: &'a [u8], + data: T, i: usize, len: usize, + finished: bool, }, } diff --git a/src/lib.rs b/src/lib.rs index 1f46b82..ce9c5fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,9 +22,9 @@ use state::State; use crate::internal_radio::InternalRadio; -pub struct Rf4463<'a, const MAX_PACKET_LEN: usize, Spi, SdnPin, CsPin, Delay> { +pub struct Rf4463<'a, const MAX_PACKET_LEN: usize, Spi, SdnPin, CsPin, Delay, T: AsRef<[u8]>> { radio: InternalRadio<Spi, SdnPin, CsPin, Delay>, - state: InternalState<'a, MAX_PACKET_LEN>, + state: InternalState<'a, MAX_PACKET_LEN, T>, rx_forever: bool, channel: u8, } @@ -36,7 +36,8 @@ impl< SdnPin: OutputPin<Error = Infallible>, CsPin: OutputPin<Error = Infallible>, Delay: DelayUs<u16>, - > Rf4463<'a, MAX_PACKET_LEN, Spi, SdnPin, CsPin, Delay> + T: AsRef<[u8]>, + > Rf4463<'a, MAX_PACKET_LEN, Spi, SdnPin, CsPin, Delay, T> where Spi::Error: Debug, { @@ -179,14 +180,13 @@ where } /// Panics if data length is > 8191 - pub fn start_tx(&mut self, data: &'a [u8]) -> Result<(), TxError<Spi::Error>> { + 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" ); - let len = data.len(); - if len > MAX_PACKET_LEN { + if len > data.as_ref().len() { return Err(TxError::TooMuchData); } @@ -194,9 +194,9 @@ where self.radio.clear_ph_and_modem_interrupts().txe()?; // 128-byte TX buffer - let i = data.len().min(128); + let i = len.min(128); let mut segment = [0; 128]; - segment[..i].copy_from_slice(&data[..i]); + segment[..i].copy_from_slice(&data.as_ref()[..i]); self.radio.with_cs(|s| { s.spi_transfer_byte(WRITE_TX_FIFO).txe()?; @@ -217,11 +217,36 @@ where ]) .txe()?; - self.state = InternalState::Tx { data, i, len }; + self.state = InternalState::Tx { + data, + i, + len, + finished: false, + }; 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>> { if self.radio.fifo_underflow_pending().te()? { return Err(TransferError::FifoOverflow); @@ -247,9 +272,9 @@ where } } - InternalState::Tx { .. } => { + InternalState::Tx { finished, .. } => { if self.radio.packet_sent_pending().te()? { - self.state = InternalState::Idle; + *finished = true; } if let Err(e) = self.tx_step() { @@ -304,13 +329,18 @@ where } fn tx_step(&mut self) -> Result<(), TransferError<Spi::Error>> { - let (data, i) = match &mut self.state { - InternalState::Tx { data, i, len } => (&data[0..*len], i), + let (data, data_len, i) = match &mut self.state { + InternalState::Tx { + data, + i, + len, + finished, + } if !*finished => (data, *len, i), _ => return Ok(()), }; // only look at the slice we haven't sent yet - let data = &data[*i..]; + let data = &data.as_ref()[*i..data_len]; let len: usize = self.radio.tx_fifo_space().te()?.into(); let len = len.min(data.len()); -- GitLab