From 7b9fd2443a7369a47710fb734e626f5faab5ae7f Mon Sep 17 00:00:00 2001
From: Stephen <webmaster@scd31.com>
Date: Mon, 15 May 2023 11:08:09 -0300
Subject: [PATCH] uart improvements

---
 src/control.rs | 15 +++++++++------
 src/packet.rs  |  3 ++-
 src/radio.rs   | 40 ++++++++++++++++++++++------------------
 3 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/src/control.rs b/src/control.rs
index 407d1a8..59762fb 100644
--- a/src/control.rs
+++ b/src/control.rs
@@ -79,22 +79,25 @@ impl Controller {
     }
 
     // manages our transceiver
-    // TODO currently very hacky, because we're going to rip
-    // most of this out when we stop using a lobotomized NPR-70
-    // and move to just accessing the RF4463 directly over SPI
     fn tx_thread(image_rx: Receiver<FecPacket>, telem_rx: Receiver<Packet>) {
-        let mut radio = UartRadio::new("/dev/ttyACM0");
+        let mut radio = UartRadio::new("/dev/ttyAMA0").expect("Could not initialize radio");
 
         let mut text_msg_id = 0;
         loop {
             while let Ok(tm) = telem_rx.try_recv() {
                 let tm = tm.into_raw(&mut text_msg_id).into();
 
-                radio.send_packet(&tm);
+                if let Err(e) = radio.send_packet(&tm) {
+                    eprintln!("Could not send packet: {}", e);
+                }
             }
 
             if let Ok(img) = image_rx.try_recv() {
-                radio.send_packet(&img);
+                println!("start send packet");
+                if let Err(e) = radio.send_packet(&img) {
+                    eprintln!("Could not send packet: {}", e);
+                }
+                println!("end send packet");
             } else {
                 thread::sleep(Duration::from_millis(5));
             }
diff --git a/src/packet.rs b/src/packet.rs
index 9a5a91a..6a40ca3 100644
--- a/src/packet.rs
+++ b/src/packet.rs
@@ -3,6 +3,7 @@ use crc::{Crc, CRC_16_IBM_3740};
 use crate::ldpc::ldpc_encode;
 
 const TEXT_MESSAGE_LEN: usize = 252;
+const FEC_PACKET_LEN: usize = 256 + 2 + 65;
 
 pub enum Packet {
     TextMessage(u8, [u8; TEXT_MESSAGE_LEN]),
@@ -55,7 +56,7 @@ impl Packet {
 
 pub struct RawPacket(pub [u8; 256]);
 
-pub struct FecPacket(pub [u8; 256 + 2 + 65]);
+pub struct FecPacket(pub [u8; FEC_PACKET_LEN]);
 
 impl From<RawPacket> for FecPacket {
     fn from(value: RawPacket) -> Self {
diff --git a/src/radio.rs b/src/radio.rs
index c05d167..3d61748 100644
--- a/src/radio.rs
+++ b/src/radio.rs
@@ -1,6 +1,7 @@
 use serial::{unix::TTYPort, BaudRate::BaudOther, SerialPort};
 use std::{
     io::{Read, Write},
+    thread::sleep,
     time::Duration,
 };
 
@@ -8,33 +9,36 @@ use crate::packet::FecPacket;
 
 // Used for talking to an RF4463 via a microcontroller
 // The microcontroller takes in packet data over UART and sends it to the RF4463
-// Note that this is a little hacky. It's only intended to be used
-// for debugging, and not for an actual balloon flight
 pub struct UartRadio {
     uart: TTYPort,
 }
 
 impl UartRadio {
-    pub fn new(uart: &str) -> Self {
-        let mut uart = serial::open(uart).unwrap();
-        uart.reconfigure(&|settings| settings.set_baud_rate(BaudOther(921600)))
-            .unwrap();
-        uart.set_timeout(Duration::from_millis(5)).unwrap();
+    pub fn new(uart: &str) -> anyhow::Result<Self> {
+        let mut uart = serial::open(uart)?;
+        uart.reconfigure(&|settings| settings.set_baud_rate(BaudOther(921_600)))?;
 
-        Self { uart }
+        Ok(Self { uart })
     }
 
-    pub fn send_packet(&mut self, packet: &FecPacket) {
-        self.uart.write_all(&packet.0).unwrap();
-        let mut buf = [0; 1];
-        if let Ok(1) = self.uart.read(&mut buf) {
-            if buf[0] == b'F' {
-                // uC is full. Need to wait until we receive
-                // the empty signal
-                while buf[0] != b'E' {
-                    let _ = self.uart.read(&mut buf);
-                }
+    pub fn send_packet(&mut self, packet: &FecPacket) -> anyhow::Result<()> {
+        loop {
+            self.uart.write_all(&[0x00])?;
+            self.uart.flush()?;
+
+            let mut buf = [0; 1];
+            self.uart.read_exact(&mut buf)?;
+
+            if buf == [0x02] {
+                break; // enough space for packet
+            } else {
+                sleep(Duration::from_millis(10));
             }
         }
+
+        self.uart.write_all(&[0x01])?;
+        self.uart.write_all(&packet.0)?;
+
+        Ok(())
     }
 }
-- 
GitLab