diff --git a/src/control.rs b/src/control.rs index 407d1a8daeb216e029c33c012d7697ff273e4982..59762fb220cac952af6a61d64036f5a6cd144fb7 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 9a5a91aa2633bdef0f47a0b4005d8502cad2ba1d..6a40ca3aee985273a37c7b8c36debfab61eaaa3c 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 c05d167de559bc6eb4b2923498943095bc6b7beb..3d6174844e7d9a29c09502d81c6326a6ecbab882 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(()) } }