aboutsummaryrefslogtreecommitdiffstats
path: root/src/fl2k.rs
blob: 8bfc0ec525be886ad0d2b6f67ee2c90c320260de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::ffi::c_int;
use fl2k_ampliphase::{fl2k_dev_t, fl2k_get_device_count, fl2k_open, fl2k_close, fl2k_stop_tx, fl2k_set_sample_rate, fl2k_get_sample_rate, fl2k_tx_cb_t, fl2k_start_tx};

#[derive(Debug)]
pub enum FL2KError {
    InvalidParam,
    NoDevice,
    NotFound,
    Busy,
    Timeout,
    NoMem,
    Unknown(c_int)
}

fn handle_return_value(val : c_int) -> Result<(), FL2KError> {
    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() }
}

pub struct FL2K {
    device : *mut fl2k_dev_t,
}

impl FL2K {
    pub fn open(device_index : u32) -> Result<Self, FL2KError> {
        unsafe {
            let mut fl2k = FL2K { device: std::mem::zeroed() };
            handle_return_value(fl2k_open(&mut fl2k.device, device_index))?;
            Ok(fl2k)
        }
    }


    pub fn set_sample_rate(&mut self, sample_rate : u32) -> Result<(), FL2KError> {
        handle_return_value( unsafe { fl2k_set_sample_rate(self.device, sample_rate) })
    }

    pub fn get_sample_rate(&mut self) -> Result<u32, FL2KError> {
        let sr = unsafe { fl2k_get_sample_rate(self.device) };
        if sr == 0 { Err(FL2KError::Unknown(0)) } else { Ok(sr) }
    }

    pub fn start_tx(&mut self, callback : fl2k_tx_cb_t, buf_num: u32) -> Result<(), FL2KError> {
        let r = unsafe { fl2k_start_tx(self.device, callback, std::ptr::null_mut(), 0) };
        handle_return_value(r)
    }

    pub fn stop_tx(&self) -> Result<(), FL2KError> {
        handle_return_value( unsafe { fl2k_stop_tx(self.device) } )
    }
}


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),
        }
    }
}