diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fl2k.rs | 45 | ||||
-rw-r--r-- | src/main.rs | 42 |
2 files changed, 56 insertions, 31 deletions
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); |