From ba3778a9d75a177ef51b99c3d641d399ffce4bd2 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 31 Dec 2022 14:59:18 +0100 Subject: Handle Ctrl-C, add some fl2k code --- Cargo.lock | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/fl2k.rs | 45 ++++++++++++++++++-------------- src/main.rs | 42 +++++++++++++++++++++--------- 4 files changed, 143 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13f116a..457d9d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,6 +62,16 @@ dependencies = [ "libloading", ] +[[package]] +name = "ctrlc" +version = "3.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1631ca6e3c59112501a9d87fd86f21591ff77acd31331e8a73f8d80a65bbdd71" +dependencies = [ + "nix", + "windows-sys", +] + [[package]] name = "either" version = "1.8.0" @@ -74,6 +84,7 @@ version = "0.1.0" dependencies = [ "bindgen", "cc", + "ctrlc", "getopts", ] @@ -141,6 +152,18 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "nix" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a58d1d356c6597d08cde02c2f09d785b09e28711837b1ed667dc652c08a694" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "static_assertions", +] + [[package]] name = "nom" version = "7.1.1" @@ -208,6 +231,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "syn" version = "1.0.107" @@ -263,3 +292,60 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" diff --git a/Cargo.toml b/Cargo.toml index 1da5201..01a7bac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] getopts = "0.2" +ctrlc = "3.2" [build-dependencies] bindgen = "0.63" diff --git a/src/fl2k.rs b/src/fl2k.rs index 7bade50..cfc2778 100644 --- a/src/fl2k.rs +++ b/src/fl2k.rs @@ -1,7 +1,8 @@ use std::ffi::c_int; -use fl2k_ampliphase::{fl2k_dev_t, fl2k_get_device_count, fl2k_open, fl2k_close}; +use fl2k_ampliphase::{fl2k_dev_t, fl2k_get_device_count, fl2k_open, fl2k_close, fl2k_stop_tx}; -enum FL2KError { +#[derive(Debug)] +pub enum FL2KError { InvalidParam, NoDevice, NotFound, @@ -12,25 +13,22 @@ enum FL2KError { } fn handle_return_value(val : c_int) -> Result<(), FL2KError> { - match val { - #![allow(non_snake_case)] - fl2k_error_FL2K_SUCCESS => Ok(()), - fl2k_error_FL2K_TRUE => Ok(()), - fl2k_error_FL2K_ERROR_INVALID_PARAM => Err(FL2KError::InvalidParam), - fl2k_error_FL2K_ERROR_NO_DEVICE => Err(FL2KError::NoDevice), - fl2k_error_FL2K_ERROR_NOT_FOUND => Err(FL2KError::NotFound), - fl2k_error_FL2K_ERROR_BUSY => Err(FL2KError::Busy), - fl2k_error_FL2K_ERROR_TIMEOUT => Err(FL2KError::Timeout), - fl2k_error_FL2K_ERROR_NO_MEM => Err(FL2KError::NoMem), - v => Err(FL2KError::Unknown(v)), - } + if val == fl2k_ampliphase::fl2k_error_FL2K_SUCCESS { Ok(()) } + else if val == fl2k_ampliphase::fl2k_error_FL2K_TRUE { Ok(()) } + else if val == fl2k_ampliphase::fl2k_error_FL2K_ERROR_INVALID_PARAM { Err(FL2KError::InvalidParam) } + else if val == fl2k_ampliphase::fl2k_error_FL2K_ERROR_NO_DEVICE { Err(FL2KError::NoDevice) } + else if val == fl2k_ampliphase::fl2k_error_FL2K_ERROR_NOT_FOUND { Err(FL2KError::NotFound) } + else if val == fl2k_ampliphase::fl2k_error_FL2K_ERROR_BUSY { Err(FL2KError::Busy) } + else if val == fl2k_ampliphase::fl2k_error_FL2K_ERROR_TIMEOUT { Err(FL2KError::Timeout) } + else if val == fl2k_ampliphase::fl2k_error_FL2K_ERROR_NO_MEM { Err(FL2KError::NoMem) } + else { Err(FL2KError::Unknown(val)) } } pub fn get_device_count() -> u32 { unsafe { fl2k_get_device_count() } } -struct FL2K { +pub struct FL2K { device : *mut fl2k_dev_t, } @@ -43,10 +41,19 @@ impl FL2K { } } - pub fn close(self) -> Result<(), FL2KError> { - unsafe { - handle_return_value(fl2k_close(self.device))?; - } + pub fn stop_tx(&self) -> Result<(), FL2KError> { + handle_return_value( unsafe { fl2k_stop_tx(self.device) } )?; Ok(()) } } + +impl Drop for FL2K { + fn drop(&mut self) { + match unsafe { + handle_return_value(fl2k_close(self.device)) + } { + Ok(_) => (), + Err(e) => eprintln!("Failed to close FL2K: {:?}", e), + } + } +} diff --git a/src/main.rs b/src/main.rs index 0492ed1..a415e9f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,13 +22,14 @@ * along with this program. If not, see . */ +use std::sync::atomic::{AtomicBool, Ordering}; use std::{env, thread}; use std::io::{prelude::*, BufReader, BufWriter}; use std::fs::File; -use std::sync::mpsc; +use std::sync::{mpsc, Arc}; use getopts::Options; -//mod fl2k; +mod fl2k; const TRIG_TABLE_ORDER : usize = 8; const TRIG_TABLE_SHIFT : usize = 32 - TRIG_TABLE_ORDER; @@ -40,7 +41,7 @@ const ANG_INCR : f32 = INT32_MAX_AS_FLOAT / (2.0 * PI); enum Waveform { Sine, Rect } -enum Output { Debug } +enum Output { Debug, FL2K } struct DDS { trig_table_quadrature : Vec, @@ -143,6 +144,7 @@ fn main() { opts.optopt("m", "mod-index", "Modulation index (default: 0.25)]", "FACTOR"); opts.optopt("i", "input-rate", "Input baseband sample rate (default: 48000 Hz)", "RATE"); opts.optopt("w", "waveform", "(sine|rect) default: rect", "WAVEFORM"); + opts.optflag("C", "device-count", "Return FL2K device count and quit"); opts.optflag("D", "debug", "Write to debug files instead of FL2K"); opts.optflag("h", "help", "print this help menu"); let cli_args = match opts.parse(&args[1..]) { @@ -154,16 +156,25 @@ fn main() { std::process::exit(1); } - let output = if cli_args.opt_str("D").is_none() { - eprintln!("Only debug supported for now"); - std::process::exit(1); + if cli_args.opt_str("D").is_some() { + eprintln!("FL2K device count {}", fl2k::get_device_count()); + return; } - else { + + let output = if cli_args.opt_str("D").is_some() { Output::Debug + } + else { + Output::FL2K + }; + + let device_index : u32 = match cli_args.opt_str("d") { + Some(s) => s.parse().expect("integer value"), + None => 0, }; let samp_rate : u32 = match cli_args.opt_str("s") { - Some(s) => s.parse().expect("floating point value"), + Some(s) => s.parse().expect("integer value"), None => 96_000_000, }; @@ -173,7 +184,7 @@ fn main() { }; let input_freq : u32 = match cli_args.opt_str("i") { - Some(s) => s.parse().expect("floating point value"), + Some(s) => s.parse().expect("integer value"), None => 48_000, }; @@ -193,8 +204,6 @@ fn main() { } }; - //eprintln!("Device count {}", fl2k::get_device_count()); - let source_file_name = match cli_args.opt_str("f") { Some(f) => f, None => { @@ -212,6 +221,12 @@ fn main() { eprintln!("Samplerate: {} MHz", (samp_rate as f32)/1000000.0); eprintln!("Center frequency: {} kHz", base_freq/1000.0); + let running = Arc::new(AtomicBool::new(true)); + + let r = running.clone(); + ctrlc::set_handler(move || { + r.store(false, Ordering::SeqCst); + }).expect("Error setting Ctrl-C handler"); let (input_samples_tx, input_samples_rx) = mpsc::sync_channel::>(2); let (pd_tx, pd_rx) = mpsc::sync_channel(2); @@ -224,7 +239,7 @@ fn main() { // Read file and convert samples thread::spawn(move || { - loop { + while running.load(Ordering::SeqCst) { let mut buf = Vec::with_capacity(BASEBAND_BUF_SAMPS); buf.resize(BASEBAND_BUF_SAMPS, 0i16); @@ -315,6 +330,9 @@ fn main() { // Main thread, output to file/device match output { + Output::FL2K => { + let fl2k = fl2k::FL2K::open(device_index); + } Output::Debug => { let out_file = File::create("debug-out.i8").expect("create file"); let mut out_file = BufWriter::new(out_file); -- cgit v1.2.3