diff --git a/red/.gitignore b/red/.gitignore new file mode 100644 index 0000000..f2f9e58 --- /dev/null +++ b/red/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock \ No newline at end of file diff --git a/red/Cargo.toml b/red/Cargo.toml new file mode 100644 index 0000000..ead1142 --- /dev/null +++ b/red/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "red" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bytes = "1.2.1" +euclid = "0.22.7" +futures = "0.3.24" +tokio = { version = "1.21.0", features = ["full"] } +tokio-serial = "5.4.3" +tokio-util = { version = "0.7.4", features = ["codec"] } diff --git a/red/build.rs b/red/build.rs new file mode 100644 index 0000000..03d1980 --- /dev/null +++ b/red/build.rs @@ -0,0 +1,13 @@ +fn main() { + let async_main = format!("{}/main.rs", std::env::var("OUT_DIR").unwrap()); + std::fs::write( + async_main, + r#" + #[cfg_attr(feature = "pasts/web", wasm_bindgen(start))] + pub fn main() { + let executor = Executor::default(); + executor.spawn(App::main(executor.clone())); + }"#, + ) + .unwrap(); +} diff --git a/red/justfile b/red/justfile new file mode 100644 index 0000000..10271af --- /dev/null +++ b/red/justfile @@ -0,0 +1,7 @@ +build: + cargo build --target=armv7-unknown-linux-gnueabihf + +rrun: + #scp -r ./src olimex@muele.local:red/ + rsync -rvu --filter=':- .gitignore' ../red olimex@muele.local: + ssh olimex@muele.local "cd red; /home/olimex/.cargo/bin/cargo run" \ No newline at end of file diff --git a/red/src/main.rs b/red/src/main.rs new file mode 100644 index 0000000..8c7b8c0 --- /dev/null +++ b/red/src/main.rs @@ -0,0 +1,61 @@ +#![warn(rust_2018_idioms)] + +use futures::stream::StreamExt; +use std::{env, io, str}; +use tokio_util::codec::{Decoder, Encoder}; + +use bytes::BytesMut; +use tokio_serial::SerialPortBuilderExt; + +#[cfg(unix)] +const DEFAULT_TTY: &str = "/dev/ttyUSB0"; +#[cfg(windows)] +const DEFAULT_TTY: &str = "COM1"; + +struct LineCodec; + +impl Decoder for LineCodec { + type Item = String; + type Error = io::Error; + + fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { + let newline = src.as_ref().iter().position(|b| *b == b'\n'); + if let Some(n) = newline { + let line = src.split_to(n + 1); + return match str::from_utf8(line.as_ref()) { + Ok(s) => Ok(Some(s.to_string())), + Err(_) => Err(io::Error::new(io::ErrorKind::Other, "Invalid String")), + }; + } + Ok(None) + } +} + +impl Encoder for LineCodec { + type Error = io::Error; + + fn encode(&mut self, _item: String, _dst: &mut BytesMut) -> Result<(), Self::Error> { + Ok(()) + } +} + +#[tokio::main] +async fn main() -> tokio_serial::Result<()> { + let mut args = env::args(); + let tty_path = args.nth(1).unwrap_or_else(|| DEFAULT_TTY.into()); + + let mut port = tokio_serial::new(tty_path, 115200).open_native_async() + .expect("Unable to open serial port"); + + #[cfg(unix)] + port.set_exclusive(false) + .expect("Unable to set serial port exclusive to false"); + + let mut reader = LineCodec.framed(port); + println!("Starting read."); + while let Some(line_result) = reader.next().await { + let line = line_result.expect("Failed to read line"); + println!("{}", line); + } + Ok(()) +} \ No newline at end of file