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
     }
 }