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