use rf4463::{ config::{RADIO_CONFIG_500_2, RADIO_CONFIG_5_4}, Rf4463, TransferError, }; use rppal::{ gpio::{Gpio, OutputPin}, hal::Delay, spi::{self, Bus, Mode, SlaveSelect, Spi}, }; use serial::{unix::TTYPort, BaudRate::BaudOther, SerialPort}; use std::{ io::{Read, Write}, thread::sleep, time::Duration, }; 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 pub struct UartRadio { uart: TTYPort, } impl UartRadio { pub fn new(uart: &str) -> anyhow::Result<Self> { let mut uart = serial::open(uart)?; uart.reconfigure(&|settings| settings.set_baud_rate(BaudOther(921_600)))?; Ok(Self { uart }) } 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(()) } } pub struct SpiRadio { radio: Rf4463<Spi, OutputPin, OutputPin, Delay>, failures: u32, total: u32, } impl SpiRadio { pub fn new() -> anyhow::Result<Self> { let spi = Spi::new(Bus::Spi0, SlaveSelect::Ss0, 10_000_000, Mode::Mode0)?; let gpio = Gpio::new()?; let sdn = gpio.get(22)?.into_output(); let cs = gpio.get(24)?.into_output(); let delay = Delay::new(); // todo fix this unwrap let radio = Rf4463::new(spi, sdn, cs, delay, &mut RADIO_CONFIG_500_2.clone()).unwrap(); Ok(Self { radio, failures: 0, total: 0, }) } pub fn send_packet(&mut self, packet: &FecPacket) -> anyhow::Result<()> { self.total += 1; // todo fix this unwrap if self.actually_send(packet, 3).is_err() { self.failures += 1; println!( "{} % fail rate", (self.failures as f64) / (self.total as f64) ); } Ok(()) } fn actually_send( &mut self, packet: &FecPacket, tries: u32, ) -> Result<(), TransferError<spi::Error>> { if tries == 0 { return Err(TransferError::FifoOverflow); } match self.radio.tx(&mut packet.0.clone()) { Ok(()) => Ok(()), Err(TransferError::FifoOverflow) => self.actually_send(packet, tries - 1), Err(e) => Err(e), } } }