From 486c11f8d1d5b6b0b10838b50ea04a78f95b38eb Mon Sep 17 00:00:00 2001 From: Nathan Perry Date: Thu, 26 Sep 2024 06:47:23 -0400 Subject: host interface --- host/Cargo.toml | 22 ++++++++++ host/src/bin/debug_downlink.rs | 97 ++++++++++++++++++++++++++++++++++++++++++ host/src/lib.rs | 1 + 3 files changed, 120 insertions(+) create mode 100644 host/Cargo.toml create mode 100644 host/src/bin/debug_downlink.rs create mode 100644 host/src/lib.rs (limited to 'host') diff --git a/host/Cargo.toml b/host/Cargo.toml new file mode 100644 index 0000000..886962c --- /dev/null +++ b/host/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "ocularium_host" +version = "0.1.0" +edition = "2021" + +[dependencies] +clap = { version = "4.5.18", features = ["derive"] } +tokio = { version = "1.40.0", features = ["full"] } +chrono = "0.4.38" +tokio-serial = "5.4" +postcard = "1.0" +heapless = { version = "0.8", features = ["serde"] } +eyre = "0.6" +serde = "1.0" +ssmarshal = { version = "1.0", features = ["std"] } + +embassy-executor = { git = "https://github.com/embassy-rs/embassy", features = ["arch-std"] } +embassy-time = { git = "https://github.com/embassy-rs/embassy", features = ["std", "generic-queue"] } + +molybdos_lib = { git = "https://pub.npry.dev/molybdos", features = ["postcard", "serde", "std"], default-features = false } + +hound = "3.5" \ No newline at end of file diff --git a/host/src/bin/debug_downlink.rs b/host/src/bin/debug_downlink.rs new file mode 100644 index 0000000..a9744ac --- /dev/null +++ b/host/src/bin/debug_downlink.rs @@ -0,0 +1,97 @@ +use clap::Parser; +use tokio::{ + io::AsyncReadExt, + sync::Mutex, +}; +use tokio_serial::SerialPortBuilderExt; + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +pub enum Uplink { + Ping, +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +pub enum Downlink { + Pong, + PDM(heapless::Vec), +} + +#[derive(clap::Parser, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Args { + #[clap(short, long)] + #[cfg_attr(target_os = "linux", clap(default_value = "/dev/ttyACM0"))] + pub serial_port: String, +} + +#[tokio::main] +async fn main() -> eyre::Result<()> { + let args: Args = Args::parse(); + + let mut port = tokio_serial::new(args.serial_port, 115200).open_native_async()?; + let mut cobs_acc = postcard::accumulator::CobsAccumulator::<256>::new(); + + let spec = hound::WavSpec { + channels: 1, + sample_rate: 48000 * 8, + bits_per_sample: 16, + sample_format: hound::SampleFormat::Int, + }; + + let writer = + tokio::task::spawn_blocking(move || hound::WavWriter::create("data.wav", spec)).await??; + + let writer = std::sync::Arc::new(Mutex::new(Some(writer))); + + tokio::task::spawn({ + let writer = writer.clone(); + + async move { + tokio::signal::ctrl_c().await.unwrap(); + + let mut writer = writer.lock().await; + let writer = writer.take().unwrap(); + writer.finalize().unwrap(); + } + }); + + loop { + let mut bytes = [0u8; 1024]; + + let n = port.read(&mut bytes).await?; + if n == 0 { + eyre::bail!("serial port closed"); + } + + for msg in + molybdos_lib::util::cobs::do_deserialize::(&mut cobs_acc, &bytes[..n]) + { + match msg { + Downlink::PDM(data) => { + let writer = writer.clone(); + + tokio::task::spawn_blocking(move || { + let mut writer = writer.try_lock().unwrap(); + let writer = writer.as_mut().unwrap(); + + for b in data { + for bit in 0..8 { + let sample = (b >> bit) & 1; + writer + .write_sample(if sample == 1 { + i16::MAX + } else { + i16::MIN + }) + .unwrap(); + } + } + }) + .await?; + }, + _ => { + println!("{msg:?}"); + }, + } + } + } +} diff --git a/host/src/lib.rs b/host/src/lib.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/host/src/lib.rs @@ -0,0 +1 @@ + -- cgit v1.3.1