From 284036ffdcaf9fe9460f0f50dad833f827b5e29b Mon Sep 17 00:00:00 2001 From: Brendan <2bndy5@gmail.com> Date: Wed, 29 Jan 2025 05:14:18 -0800 Subject: [PATCH] start rust examples in linux --- examples/rust/Cargo.toml | 5 -- examples/rust/Embed.toml | 0 examples/rust/src/lib.rs | 2 - examples/rust/src/linux.rs | 6 ++- examples/rust/src/main.rs | 91 ++++++++++++++++++++++++++++++------- examples/rust/src/rp2040.rs | 42 ----------------- 6 files changed, 79 insertions(+), 67 deletions(-) delete mode 100644 examples/rust/Embed.toml delete mode 100644 examples/rust/src/rp2040.rs diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml index 3828d03..7e73fca 100644 --- a/examples/rust/Cargo.toml +++ b/examples/rust/Cargo.toml @@ -9,14 +9,9 @@ rf24-rs = {path = "../../crates/rf24-rs"} embedded-hal = "1.0.0" anyhow = {version = "1.0.95", default-features = false } linux-embedded-hal = {version = "0.4.0", optional = true} -embassy-rp = {version = "0.2.0", optional = true} -embassy-sync = {version = "0.6.1", optional = true} -embassy-embedded-hal = {version = "0.2.0", optional = true} [features] default = ["linux"] -# default = ["rp2040"] -rp2040 = ["dep:embassy-rp", "dep:embassy-sync", "dep:embassy-embedded-hal", "rf24-rs/defmt"] linux = ["dep:linux-embedded-hal", "rf24-rs/std"] [[bin]] diff --git a/examples/rust/Embed.toml b/examples/rust/Embed.toml deleted file mode 100644 index e69de29..0000000 diff --git a/examples/rust/src/lib.rs b/examples/rust/src/lib.rs index c3f6090..d159741 100644 --- a/examples/rust/src/lib.rs +++ b/examples/rust/src/lib.rs @@ -1,5 +1,3 @@ #![no_std] #[cfg(feature = "linux")] pub mod linux; -#[cfg(feature = "rp2040")] -pub mod rp2040; diff --git a/examples/rust/src/linux.rs b/examples/rust/src/linux.rs index c7e29e3..74bc21a 100644 --- a/examples/rust/src/linux.rs +++ b/examples/rust/src/linux.rs @@ -9,10 +9,12 @@ pub struct BoardHardware { gpio: Chip, } -#[cfg(target_os = "linux")] +#[cfg(feature = "linux")] extern crate std; -#[cfg(target_os = "linux")] +#[cfg(feature = "linux")] use std::{format, string::ToString}; +#[cfg(feature = "linux")] +pub use std::{print, println}; impl BoardHardware { pub fn new(dev_gpio_chip: u8) -> Result { diff --git a/examples/rust/src/main.rs b/examples/rust/src/main.rs index d791251..bd40fa9 100644 --- a/examples/rust/src/main.rs +++ b/examples/rust/src/main.rs @@ -1,18 +1,21 @@ #![no_std] use core::{f32, time::Duration}; +use std::{io::Write, string::ToString}; use anyhow::{anyhow, Result}; +use embedded_hal::delay::DelayNs; use rf24::{ radio::{prelude::*, RF24}, PaLevel, }; #[cfg(feature = "linux")] use rf24_rs_examples::linux::{ - BoardHardware, CdevPin as DigitalOutImpl, Delay as DelayImpl, SpidevDevice as SpiImpl, + print, println, BoardHardware, CdevPin as DigitalOutImpl, Delay as DelayImpl, + SpidevDevice as SpiImpl, }; -#[cfg(feature = "rp2040")] -use rf24_rs_examples::rp2040::BoardHardware; +#[cfg(feature = "linux")] +extern crate std; /// A struct to drive our example app struct App { @@ -46,7 +49,7 @@ impl App { /// Setup the radio for this example. /// /// This will initialize and configure the [`App::radio`] object. - pub fn setup(&mut self) -> Result<()> { + pub fn setup(&mut self, radio_number: u8) -> Result<()> { // initialize the radio hardware self.radio.init().map_err(|e| anyhow!("{e:?}"))?; @@ -62,10 +65,10 @@ impl App { let address = [b"1Node", b"2Node"]; self.radio - .open_rx_pipe(1, address[0]) + .open_rx_pipe(1, address[radio_number as usize]) .map_err(|e| anyhow!("{e:?}"))?; self.radio - .open_tx_pipe(address[1]) + .open_tx_pipe(address[1 - radio_number as usize]) .map_err(|e| anyhow!("{e:?}"))?; Ok(()) } @@ -79,14 +82,23 @@ impl App { let mut remaining = count; while remaining > 0 { let buf = self.payload.to_le_bytes(); + let start = std::time::Instant::now(); let result = self.radio.send(&buf, false).map_err(|e| anyhow!("{e:?}"))?; + let end = std::time::Instant::now(); if result { // succeeded + println!( + "Transmission successful! Time to Transmit: {} us. Sent: {}", + end.saturating_duration_since(start).as_micros(), + self.payload + ); self.payload += 0.01; } else { // failed + println!("Transmission failed or timed out"); } remaining -= 1; + DelayImpl.delay_ms(1000); } Ok(()) } @@ -98,7 +110,9 @@ impl App { let _end = Duration::from_secs(timeout as u64); // put radio into active RX mode self.radio.as_rx().map_err(|e| anyhow!("{e:?}"))?; - while false { + let mut end_time = + std::time::Instant::now() + std::time::Duration::from_secs(timeout as u64); + while std::time::Instant::now() < end_time { let mut pipe = 15u8; if self .radio @@ -106,13 +120,16 @@ impl App { .map_err(|e| anyhow!("{e:?}"))? { let mut buf = [0u8; 4]; - let _len = self + let len = self .radio .read(&mut buf, None) .map_err(|e| anyhow!("{e:?}"))?; - // print pipe number and payload length - // print buf self.payload = f32::from_le_bytes(buf); + // print pipe number and payload length and payload + print!("Received {len} bytes on pipe {pipe}: {}", self.payload); + // reset timeout + end_time = + std::time::Instant::now() + std::time::Duration::from_secs(timeout as u64); } } @@ -120,15 +137,57 @@ impl App { self.radio.as_tx().map_err(|e| anyhow!("{e:?}"))?; Ok(()) } + + pub fn set_role(&mut self) -> Result { + let prompt = "*** Enter 'R' for receiver role.\n\ + *** Enter 'T' for transmitter role.\n\ + *** Enter 'Q' to quit example."; + println!("{prompt}"); + let mut input = std::string::String::new(); + std::io::stdin().read_line(&mut input)?; + let mut inputs = input.trim().split(' '); + let role = inputs + .next() + .map(|v| v.to_uppercase()) + .unwrap_or("?".to_string()); + if role.starts_with('T') { + let count = inputs + .next() + .map(|v| v.parse::().ok()) + .flatten() + .unwrap_or(5); + self.tx(count)?; + return Ok(true); + } else if role.starts_with('R') { + let timeout = inputs + .next() + .map(|v| v.parse::().ok()) + .flatten() + .unwrap_or(6); + self.rx(timeout)?; + return Ok(true); + } else if role.starts_with('Q') { + self.radio.power_down().map_err(|e| anyhow!("{e:?}"))?; + return Ok(false); + } + println!("{role} is an unrecognized input. Please try again."); + return Ok(true); + } } fn main() -> Result<()> { let mut app = App::new()?; - app.setup()?; - if option_env!("ROLE").unwrap_or_default() == "master" { - app.tx(5)?; - } else { - app.rx(6)?; - } + let mut input = std::string::String::new(); + print!("Which radio is this? Enter '0' or '1'. Defaults to '0' "); + std::io::stdout().flush()?; + std::io::stdin().read_line(&mut input)?; + let radio_number = input + .trim() + .chars() + .next() + .map(|c| if c == '1' { 1 } else { 0 }) + .unwrap_or_default(); + app.setup(radio_number)?; + while app.set_role()? {} Ok(()) } diff --git a/examples/rust/src/rp2040.rs b/examples/rust/src/rp2040.rs deleted file mode 100644 index 336ce51..0000000 --- a/examples/rust/src/rp2040.rs +++ /dev/null @@ -1,42 +0,0 @@ -use core::cell::RefCell; -use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice; -use embassy_rp::gpio::{Level, Output}; -use embassy_rp::peripherals::{PIN_10, PIN_25, SPI1}; -use embassy_rp::spi::{Blocking, Config, Spi}; -use embassy_rp::Peripherals; -use embassy_sync::blocking_mutex::raw::NoopRawMutex; -use embassy_sync::blocking_mutex::Mutex; - -pub struct BoardHardware<'b> { - peri: Peripherals, - spi_bus_mutex: Mutex>>, - pub spi_device: SpiDevice<'b, NoopRawMutex, Spi<'b, SPI1, Blocking>, Output<'b, PIN_10>>, - pub ce_pin: Output<'b, PIN_25>, -} - -impl BoardHardware<'_> { - pub fn new() -> Self { - let peri = embassy_rp::init(Default::default()); - - let ce = peri.PIN_9; - let ce_pin = Output::new(ce, Level::Low); - - let clk = peri.PIN_10; - let mosi = peri.PIN_11; - let miso = peri.PIN_12; - let mut spi_config = Config::default(); - spi_config.frequency = 10_000_000; - let spi = Spi::new_blocking(peri.SPI1, clk, mosi, miso, spi_config); - let spi_bus_mutex: Mutex> = Mutex::new(RefCell::new(spi)); - let cs = peri.PIN_25; - let cs_pin = Output::new(cs, Level::High); - let spi_device = SpiDevice::new(&spi_bus_mutex, cs_pin); - - BoardHardware { - peri, - spi_bus_mutex, - spi_device, - ce_pin, - } - } -}