From 66e1bb44e733e0cced3eaeed535bef796504c10b Mon Sep 17 00:00:00 2001 From: Stephen D <webmaster@scd31.com> Date: Sat, 8 Jul 2023 15:28:57 -0300 Subject: [PATCH] basic SPI working --- Cargo.lock | 10 ++++ Cargo.toml | 2 +- src/control.rs | 7 ++- src/packet.rs | 9 ++-- src/radio.rs | 130 +++++++++++++++++++++++++++---------------------- 5 files changed, 90 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 350ec80..96fec44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,6 +40,7 @@ dependencies = [ "crc", "image", "kiss-tnc", + "rppal", "serde", "serial", "sha3", @@ -687,6 +688,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rppal" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612e1a22e21f08a246657c6433fe52b773ae43d07c9ef88ccfc433cc8683caba" +dependencies = [ + "libc", +] + [[package]] name = "scopeguard" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index a78d03c..6783760 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,10 +23,10 @@ bitvec = "1.0.1" crc = "3.0.1" image = "0.24.6" kiss-tnc = "0.2.2" +rppal = "0.14.1" serde = { version = "1.0.160", features = ["derive"] } serial = "0.4.0" sha3 = "0.10.7" subprocess = "0.2.9" tokio = { version = "1.27.0", features = ["full"] } toml = "0.7.3" - diff --git a/src/control.rs b/src/control.rs index 761d59f..e48b27e 100644 --- a/src/control.rs +++ b/src/control.rs @@ -11,7 +11,7 @@ use crate::{ config::Config, img::ImgManager, packet::{FecPacket, Packet}, - radio::UartRadio, + radio::McuRadio, ssdv::ssdv_encode, }; @@ -93,7 +93,7 @@ impl Controller { telem_rx: Receiver<Packet>, ) { let mut radio = loop { - let r = UartRadio::new(&uart); + let r = McuRadio::new(&uart); match r { Ok(r) => break r, @@ -122,6 +122,9 @@ impl Controller { eprintln!("Could not send packet: {}", e); } } else { + if let Err(e) = radio.flush() { + eprintln!("Could not flush radio: {}", e); + } thread::sleep(Duration::from_millis(50)); } diff --git a/src/packet.rs b/src/packet.rs index 8bd7b63..1d52ce6 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -23,16 +23,13 @@ impl Packet { .iter() .chain(b": ".iter()) .chain(msg.as_bytes().iter()); + let mut len = 0; for (i, b) in iter.enumerate().take(TEXT_MESSAGE_LEN) { out[i] = *b; + len += 1; } - let len = msg - .as_bytes() - .len() - .min(TEXT_MESSAGE_LEN) - .try_into() - .unwrap(); + let len = len.min(TEXT_MESSAGE_LEN).try_into().unwrap(); Self::TextMessage(len, out) } diff --git a/src/radio.rs b/src/radio.rs index 8c33842..9da61cc 100644 --- a/src/radio.rs +++ b/src/radio.rs @@ -1,9 +1,5 @@ -use serial::{unix::TTYPort, BaudRate::BaudOther, SerialPort}; -use std::{ - io::{self, Read, Write}, - thread::sleep, - time::Duration, -}; +use rppal::spi::{Bus, Mode, SlaveSelect, Spi}; +use std::{thread::sleep, time::Duration}; use crate::packet::FecPacket; @@ -11,44 +7,44 @@ const BUFFER_STATUS_CMD: u8 = 0x00; const SEND_PACKET_CMD: u8 = 0x01; const GET_TEMP_CMD: u8 = 0x02; const SYNC_CMD: u8 = 0x03; +const NOP_CMD: u8 = 0x55; const PACKET_SPACE: u8 = 0x02; // 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, +// The microcontroller takes in packet data over SPI and sends it to the RF4463 +pub struct McuRadio { + spi: Spi, } -impl UartRadio { +// TODO reset mcu on initialization +impl McuRadio { pub fn new(uart: &str) -> anyhow::Result<Self> { - let mut uart = serial::open(uart)?; - uart.reconfigure(&|settings| settings.set_baud_rate(BaudOther(921_600)))?; + let spi = Spi::new(Bus::Spi0, SlaveSelect::Ss1, 1_000_000, Mode::Mode0)?; - Ok(Self { uart }) + Ok(Self { spi }) } pub fn send_packet(&mut self, packet: &FecPacket) -> anyhow::Result<()> { - self.uart.write_all(&[SEND_PACKET_CMD])?; - self.uart.write_all(&packet.0)?; - - let mut buf = [0; 1]; - self.uart.read_exact(&mut buf)?; - - // wait until we have space for packets + // wait until we have packet space + let mut buf = [0]; + self.spi.transfer(&mut buf, &[NOP_CMD])?; while buf != [PACKET_SPACE] { sleep(Duration::from_millis(10)); - // poll to see if the buffer has emptied yet - self.uart.write_all(&[BUFFER_STATUS_CMD])?; - - self.uart.read_exact(&mut buf)?; + self.spi.transfer(&mut buf, &[NOP_CMD])?; } + self.spi.write(&[SEND_PACKET_CMD])?; + self.spi.write(&packet.0)?; + Ok(()) } pub fn get_temp(&mut self) -> anyhow::Result<f32> { + // todo need to figure this out + + /* self.uart.write_all(&[GET_TEMP_CMD])?; let mut buf = [0; 4]; @@ -56,46 +52,62 @@ impl UartRadio { let temp = f32::from_le_bytes(buf); - Ok(temp) + Ok(temp) */ + + Ok(12.34) } pub fn sync(&mut self) -> anyhow::Result<()> { - // clear any pending packets - let mut tries = 0; - let mut buf = [0; 100]; - loop { - match self.uart.read(&mut buf) { - Ok(0) => break, - Ok(_) => { - tries += 1; - } - Err(e) if matches!(e.kind(), io::ErrorKind::TimedOut) => break, - Err(e) => { - return Err(e.into()); - } - } - } - - if tries > 0 { - eprintln!("[WARN] Sync had pending packets(tries={tries})"); - } + // todo need to figure this out + + /* + + // clear any pending packets + let mut tries = 0; + let mut buf = [0; 100]; + loop { + match self.uart.read(&mut buf) { + Ok(0) => break, + Ok(_) => { + tries += 1; + } + Err(e) if matches!(e.kind(), io::ErrorKind::TimedOut) => break, + Err(e) => { + return Err(e.into()); + } + } + } + + if tries > 0 { + eprintln!("[WARN] Sync had pending packets(tries={tries})"); + } + + tries = 0; + let mut buf = [0; 10]; + loop { + self.uart.write_all(&[SYNC_CMD; 10])?; + match self.uart.read_exact(&mut buf) { + Ok(()) => break, + Err(e) if matches!(e.kind(), io::ErrorKind::TimedOut) => { + tries += 1; + } + Err(e) => { + return Err(e.into()); + } + } + } + + eprintln!("Synced in {tries} tries"); + + Ok(()) + */ - tries = 0; - let mut buf = [0; 10]; - loop { - self.uart.write_all(&[SYNC_CMD; 10])?; - match self.uart.read_exact(&mut buf) { - Ok(()) => break, - Err(e) if matches!(e.kind(), io::ErrorKind::TimedOut) => { - tries += 1; - } - Err(e) => { - return Err(e.into()); - } - } - } + Ok(()) + } - eprintln!("Synced in {tries} tries"); + // sends a bunch of nops over SPI to clear out its DMA buffer + pub fn flush(&mut self) -> anyhow::Result<()> { + self.spi.write(&[NOP_CMD; 256])?; Ok(()) } -- GitLab