diff --git a/.cargo/config.toml b/.cargo/config.toml index 0687b20267f03d161ac856f7d088f1a2d8ae7956..de8eca6872180644052c69f949fd82647b52b12b 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,7 @@ [target.thumbv7em-none-eabihf] rustflags = [ "-C", "link-arg=-Tlink.x", + "-C", "linker=flip-link", ] [build] diff --git a/Cargo.lock b/Cargo.lock index 8c4eb877ad13c12890c82754f1cb5d3cce3cd8fb..0b0da39fe408847709c63c8435d0e34f3b1989dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -306,7 +306,7 @@ dependencies = [ [[package]] name = "ham-cats" version = "0.1.0" -source = "git+https://gitlab.scd31.com/cats/ham-cats/#d32d0a72f3e5633a25cc6495b2fe7daed139fc84" +source = "git+https://gitlab.scd31.com/cats/ham-cats/#97ff918c4e3aaa6e15dadbaa1ab9c12b1fdb5655" dependencies = [ "arrayvec", "bitvec", @@ -413,11 +413,12 @@ checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] name = "nmea" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea2ae8b47e91d2e007edeeaad399231258b67fdbeecebec0cc2ccd6c275771a" +checksum = "53d5ae624a2d6d1f119eb99fbc433dcaa660e283e3abdfa67e3094418978a9fb" dependencies = [ "arrayvec", + "cfg-if", "chrono", "heapless", "nom", diff --git a/Cargo.toml b/Cargo.toml index c0645686eb0bccae4d594ec44fc49b2c633b49c3..a888f86cf670cf5757cdc4d649c2ffc01aa21f53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,8 @@ rf4463 = { git = "https://gitlab.scd31.com/stephen/rf4463-lib" } systick-monotonic = "1.0.1" ham-cats = { git = "https://gitlab.scd31.com/cats/ham-cats/" } half = { version = "2.3.1", default-features = false } -nmea = { version = "0.4.0", default-features = false } +# TODO can get rid of some of these features +nmea = { version = "0.6.0", default-features = false, features = ["VTG", "GGA", "RMC", "GNS", "GLL"] } arrayvec = { version = "0.7.4", default-features = false } ushell = "0.3.6" usbd-serial = "0.1.1" diff --git a/README.md b/README.md index 4ee18fee291fe8fd7029a42208b79f58b4a70d42..c621ef79412dbe8d418640bdc5e294a2a63cc5a3 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ git clone https://gitlab.scd31.com/cats/mobile-transceiver-software cd mobile-transceiver-software git pull # make sure we're up to date rustup target add thumbv7em-none-eabihf # add our board architecture, if needed +cargo install flip-link # needed for building cargo install cargo-dfu # needed for flashing ``` diff --git a/src/main.rs b/src/main.rs index 02a60c258d90dfbed98c71b8375ee4d70a883077..eb29d54a2d075007b975194916016a140c2e2b4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ mod app { }; use half::f16; use ham_cats::{ + buffer::Buffer, packet::Packet, whisker::{Gps, Route}, }; @@ -225,7 +226,7 @@ mod app { ) } - #[task(priority = 2, local = [], shared = [red, radio, config, status])] + #[task(priority = 3, local = [], shared = [red, radio, config, status])] fn radio_tick(mut ctx: radio_tick::Context) { (ctx.shared.radio, ctx.shared.config).lock(|r, c| { r.as_mut() @@ -263,7 +264,8 @@ mod app { }; if should_transmit { - let mut cats: Packet<MAX_PACKET_LEN> = Packet::default(); + let mut buf = [0; MAX_PACKET_LEN]; + let mut cats = Packet::new(&mut buf); config.lock(|config| { cats.add_identification(ham_cats::whisker::Identification { @@ -292,18 +294,14 @@ mod app { .unwrap(); } - let x = cats.fully_encode().unwrap(); - let buf = ctx.local.buf; - buf[..x.len()].copy_from_slice(&x); - - let tx_buf = &buf[..x.len()]; + let mut x = Buffer::new_empty(buf); + cats.fully_encode(&mut x).unwrap(); - ctx.shared.radio.lock(|radio| { - radio - .as_mut() + (ctx.shared.radio, config).lock(|r, c| { + r.as_mut() .unwrap() - .tx(&mut ctx.shared.red, tx_buf) + .tx(&mut ctx.shared.red, &x, Some((&c.callsign, c.ssid))) .unwrap(); }); } @@ -313,7 +311,7 @@ mod app { } } - #[task(priority = 9, local = [green, usb_detect], shared = [red, status])] + #[task(priority = 3, local = [green, usb_detect], shared = [red, status])] fn led_handler(mut ctx: led_handler::Context) { led_handler::spawn_after(LED_BLINK_RATE.millis()).unwrap(); diff --git a/src/radio.rs b/src/radio.rs index 3817e00eb74f5a62dd01ac7678c61286b19bff77..f1a6a7fc8e74a94bdb6c5da9d8f303a9ecd4fe06 100644 --- a/src/radio.rs +++ b/src/radio.rs @@ -1,4 +1,5 @@ use ham_cats::{ + buffer::Buffer, packet::Packet, whisker::{Route, RouteNode}, }; @@ -39,8 +40,7 @@ impl<'a> RadioManager<'a> { // sets us up for the default CATS frequency, 430.500 MHz radio.set_channel(20); - // perpetual mode - radio.start_rx(None, true).ok()?; + radio.start_rx(None, false).ok()?; Some(Self { radio, @@ -51,11 +51,19 @@ impl<'a> RadioManager<'a> { // call me every 20-ish ms // technically needs to be every 100ms, tops + // digipeats only if ident is Some, + // otherwise the packet is discarded pub fn tick<P: OutputPin, M: Mutex<T = P>>( &mut self, led: &mut M, ident: Option<(&str, u8)>, ) -> Result<(), TransferError<spi::Error>> { + if self.radio.is_idle() { + self.radio + .start_rx(None, false) + .map_err(TransferError::SpiError)?; + } + self.radio.interrupt(Some(self.buf), None)?; if let Some(data) = self @@ -65,25 +73,32 @@ impl<'a> RadioManager<'a> { { if self.enable_digipeating { if let Some((callsign, ssid)) = ident { - if let Ok(packet) = Packet::fully_decode(data.data()) { + let mut buf = [0; MAX_PACKET_LEN]; + if let Ok(packet) = Packet::fully_decode(data.data(), &mut buf) { self.handle_packet_rx(led, packet, callsign, ssid); - }; + } } } - // Only needed if the radio gets confused self.radio - .start_rx(None, true) + .start_rx(None, false) .map_err(TransferError::SpiError)?; } Ok(()) } - pub fn tx<P: OutputPin, M: Mutex<T = P>>(&mut self, led: &mut M, data: &[u8]) -> Option<()> { + // digipeats only if ident is Some, + // otherwise the rx'd packet is discarded + pub fn tx<P: OutputPin, M: Mutex<T = P>>( + &mut self, + led: &mut M, + data: &[u8], + ident: Option<(&str, u8)>, + ) -> Option<()> { // don't want to transmit on top of a packet while self.radio.is_busy_rxing().ok()? { - self.tick(led, None).ok()?; + self.tick(led, ident).ok()?; } led.lock(|l| l.set_high().ok()); @@ -94,15 +109,9 @@ impl<'a> RadioManager<'a> { } led.lock(|l| l.set_low().ok()); - self.radio - .start_rx(None, true) - .map_err(TransferError::SpiError) - .ok(); - Some(()) } - // Not great - lots of copies, and therefore stack usage here fn handle_packet_rx<P: OutputPin, M: Mutex<T = P>>( &mut self, led: &mut M, @@ -115,8 +124,10 @@ impl<'a> RadioManager<'a> { return; } - if let Ok(buf) = packet.fully_encode() { - self.tx(led, &buf); + let mut buf = [0; MAX_PACKET_LEN]; + let mut buf = Buffer::new_empty(&mut buf); + if packet.fully_encode(&mut buf).is_ok() { + self.tx(led, &buf, None); } } }