diff options
| -rw-r--r-- | Cargo.lock | 86 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/fl2k.rs | 45 | ||||
| -rw-r--r-- | src/main.rs | 42 | 
4 files changed, 143 insertions, 31 deletions
@@ -63,6 +63,16 @@ dependencies = [  ]  [[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"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -74,6 +84,7 @@ version = "0.1.0"  dependencies = [   "bindgen",   "cc", + "ctrlc",   "getopts",  ] @@ -142,6 +153,18 @@ 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"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -209,6 +232,12 @@ 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"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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" @@ -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 <http://www.gnu.org/licenses/>.   */ +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<i16>, @@ -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::<Vec<f32>>(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);  | 
