digilent_waveforms/
lib.rs

1#![allow(dead_code, non_upper_case_globals)]
2
3extern crate time;
4#[macro_use] extern crate failure_derive;
5
6use std::ffi::CStr;
7use std::mem;
8use std::os::raw::c_char;
9use std::os::raw::c_int;
10
11use time::Duration;
12
13use crate::dwf::*;
14use std::fmt;
15use std::fmt::Formatter;
16use std::fmt::Display;
17
18mod dwf;
19
20pub type Result<T> = std::result::Result<T, Error>;
21
22pub fn get_version() -> String {
23    unsafe {
24        let mut version = [0i8; 32];
25        FDwfGetVersion(version.as_mut_ptr());
26
27        CStr::from_ptr(mem::transmute(version.as_mut_ptr())).to_str().unwrap().to_owned()
28    }
29}
30
31#[derive(PartialEq, Debug)]
32pub enum ErrorKind {
33    NoError = dwfercNoErc as isize,
34    Unknown = dwfercUnknownError as isize,
35    ApiLockTimeout = dwfercApiLockTimeout as isize,
36    AlreadyOpened = dwfercAlreadyOpened as isize,
37    NotSupported = dwfercNotSupported as isize,
38    InvalidParameter0 = dwfercInvalidParameter0 as isize,
39    InvalidParameter1 = dwfercInvalidParameter1 as isize,
40    InvalidParameter2 = dwfercInvalidParameter2 as isize,
41    InvalidParameter3 = dwfercInvalidParameter3 as isize,
42    InvalidParameter4 = dwfercInvalidParameter4 as isize,
43}
44
45impl Display for ErrorKind {
46    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
47        f.write_str(match self {
48            ErrorKind::NoError => "No error",
49            ErrorKind::Unknown => "Unknown error",
50            ErrorKind::ApiLockTimeout => "API lock timeout",
51            ErrorKind::AlreadyOpened => "Device is already in use",
52            ErrorKind::NotSupported => "Operation is not supported",
53            ErrorKind::InvalidParameter0 => "Parameter #0 is invalid",
54            ErrorKind::InvalidParameter1 => "Parameter #1 is invalid",
55            ErrorKind::InvalidParameter2 => "Parameter #2 is invalid",
56            ErrorKind::InvalidParameter3 => "Parameter #3 is invalid",
57            ErrorKind::InvalidParameter4 => "Parameter #4 is invalid",
58        })
59    }
60}
61
62#[derive(Fail, Debug)]
63pub struct Error {
64    kind: ErrorKind,
65    message: String,
66}
67
68impl Display for Error {
69    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
70        self.kind.fmt(f)?;
71        if self.message.len() > 0 {
72            f.write_str(": ")?;
73            f.write_str(&self.message)?;
74        }
75        Ok(())
76    }
77}
78
79fn get_last_error_code() -> ErrorKind {
80    unsafe {
81        let mut error_code: DWFERC = mem::uninitialized();
82        if FDwfGetLastError((&mut error_code) as *mut DWFERC) == 0 {
83            return ErrorKind::Unknown;
84        }
85        match error_code {
86            dwfercNoErc => ErrorKind::NoError,
87            dwfercUnknownError => ErrorKind::Unknown,
88            dwfercApiLockTimeout => ErrorKind::ApiLockTimeout,
89            dwfercAlreadyOpened => ErrorKind::AlreadyOpened,
90            dwfercNotSupported => ErrorKind::NotSupported,
91            dwfercInvalidParameter0 => ErrorKind::InvalidParameter0,
92            dwfercInvalidParameter1 => ErrorKind::InvalidParameter1,
93            dwfercInvalidParameter2 => ErrorKind::InvalidParameter2,
94            dwfercInvalidParameter3 => ErrorKind::InvalidParameter3,
95            dwfercInvalidParameter4 => ErrorKind::InvalidParameter4,
96            _ => ErrorKind::Unknown,
97        }
98    }
99}
100
101fn get_last_error_message() -> String {
102    unsafe {
103        let mut error_message = [0i8; 512];
104        FDwfGetLastErrorMsg(error_message.as_mut_ptr());
105
106        CStr::from_ptr(mem::transmute(error_message.as_mut_ptr())).to_str().unwrap().to_owned()
107    }
108}
109
110fn get_last_error() -> Error {
111    Error {
112        kind: get_last_error_code(),
113        message: get_last_error_message(),
114    }
115}
116
117#[derive(Copy, Clone, PartialEq, Debug)]
118#[repr(isize)]
119pub enum TriggerSource {
120    NoTrigger = trigsrcNone as isize,
121    PC = trigsrcPC as isize,
122    DetectorAnalogIn = trigsrcDetectorAnalogIn as isize,
123    DetectorDigitalIn = trigsrcDetectorDigitalIn as isize,
124    AnalogIn = trigsrcAnalogIn as isize,
125    DigitalIn = trigsrcDigitalIn as isize,
126    DigitalOut = trigsrcDigitalOut as isize,
127    AnalogOut1 = trigsrcAnalogOut1 as isize,
128    AnalogOut2 = trigsrcAnalogOut2 as isize,
129    AnalogOut3 = trigsrcAnalogOut3 as isize,
130    AnalogOut4 = trigsrcAnalogOut4 as isize,
131    External1 = trigsrcExternal1 as isize,
132    External2 = trigsrcExternal2 as isize,
133    External3 = trigsrcExternal3 as isize,
134    External4 = trigsrcExternal4 as isize,
135    High = trigsrcHigh as isize,
136    Low = trigsrcLow as isize,
137}
138
139impl TriggerSource {
140    fn code(self) -> TRIGSRC {
141        self as TRIGSRC
142    }
143
144    fn from_code(code: TRIGSRC) -> TriggerSource {
145        unsafe { mem::transmute(code as isize) }
146    }
147}
148
149#[derive(PartialEq, Debug)]
150pub struct DeviceConfigInfo {
151    device_ix: c_int,
152    config_ix: c_int,
153    pub analog_inputs: i32,
154    pub analog_outputs: i32,
155    pub analog_ios: i32,
156    pub digital_inputs: i32,
157    pub digital_outputs: i32,
158    pub digital_ios: i32,
159    pub analog_in_buf_size: i32,
160    pub analog_out_buf_size: i32,
161    pub digital_in_buf_size: i32,
162    pub digital_out_buf_size: i32,
163}
164
165fn handle_dwf_errors(res: BOOL) -> Result<()> {
166    if res as BOOL == false_ as BOOL {
167        Err(get_last_error())
168    } else {
169        Ok(())
170    }
171}
172
173impl DeviceConfigInfo {
174    pub fn open(&self) -> Result<Device> {
175        unsafe {
176            let mut dev = Device {
177                handle: mem::uninitialized(),
178            };
179            handle_dwf_errors(FDwfDeviceConfigOpen(self.device_ix, self.config_ix, (&mut dev.handle) as *mut HDWF))?;
180            Ok(dev)
181        }
182    }
183}
184
185#[derive(PartialEq, Debug)]
186pub struct DeviceInfo {
187    device_ix: c_int,
188    pub id: i32,
189    pub revision: i32,
190    pub user_name: String,
191    pub name: String,
192    pub serial: String,
193    pub in_use: bool,
194    pub configs: Vec<DeviceConfigInfo>,
195}
196
197#[derive(PartialEq, Debug)]
198pub struct DeviceInfoList {
199    pub devices: Vec<DeviceInfo>,
200}
201
202pub fn devices() -> Result<DeviceInfoList> {
203    unsafe {
204        let mut devices_cnt: c_int = 0;
205        handle_dwf_errors(FDwfEnum(enumfilterAll, &mut devices_cnt as *mut c_int))?;
206        let mut devices = Vec::with_capacity(devices_cnt as usize);
207
208        for device_ix in 0..devices_cnt {
209            let mut id: DEVID = mem::uninitialized();
210            let mut ver: DEVVER = mem::uninitialized();
211
212            handle_dwf_errors(FDwfEnumDeviceType(device_ix, &mut id as *mut DEVID, &mut ver as *mut DEVVER))?;
213
214            let mut in_use: BOOL = mem::uninitialized();
215            handle_dwf_errors(FDwfEnumDeviceIsOpened(device_ix, &mut in_use as *mut BOOL))?;
216
217            let mut user_name = [0 as c_char; 32];
218            handle_dwf_errors(FDwfEnumUserName(device_ix, user_name.as_mut_ptr()))?;
219
220            let mut name = [0 as c_char; 32];
221            handle_dwf_errors(FDwfEnumDeviceName(device_ix, name.as_mut_ptr()))?;
222
223            let mut serial = [0 as c_char; 32];
224            handle_dwf_errors(FDwfEnumSN(device_ix, serial.as_mut_ptr()))?;
225
226            let mut configs_cnt: c_int = 0;
227            handle_dwf_errors(FDwfEnumConfig(device_ix, &mut configs_cnt as *mut c_int))?;
228
229            let mut configs = Vec::with_capacity(configs_cnt as usize);
230
231            for config_ix in 0..configs_cnt {
232                let mut analog_inputs: c_int = 0;
233                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIAnalogInChannelCount, &mut analog_inputs as *mut c_int))?;
234
235                let mut analog_outputs: c_int = 0;
236                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIAnalogInChannelCount, &mut analog_outputs as *mut c_int))?;
237
238                let mut analog_ios: c_int = 0;
239                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIAnalogInChannelCount, &mut analog_ios as *mut c_int))?;
240
241                let mut digital_inputs: c_int = 0;
242                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIDigitalInChannelCount, &mut digital_inputs as *mut c_int))?;
243
244                let mut digital_outputs: c_int = 0;
245                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIDigitalInChannelCount, &mut digital_outputs as *mut c_int))?;
246
247                let mut digital_ios: c_int = 0;
248                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIDigitalInChannelCount, &mut digital_ios as *mut c_int))?;
249
250                let mut analog_in_buf_size: c_int = 0;
251                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIAnalogInBufferSize, &mut analog_in_buf_size as *mut c_int))?;
252
253                let mut analog_out_buf_size: c_int = 0;
254                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIAnalogOutBufferSize, &mut analog_out_buf_size as *mut c_int))?;
255
256                let mut digital_in_buf_size: c_int = 0;
257                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIDigitalInBufferSize, &mut digital_in_buf_size as *mut c_int))?;
258
259                let mut digital_out_buf_size: c_int = 0;
260                handle_dwf_errors(FDwfEnumConfigInfo(config_ix, DECIDigitalOutBufferSize, &mut digital_out_buf_size as *mut c_int))?;
261
262                configs.insert(config_ix as usize, DeviceConfigInfo {
263                    device_ix,
264                    config_ix,
265                    analog_inputs,
266                    analog_outputs,
267                    analog_ios,
268                    digital_inputs,
269                    digital_outputs,
270                    digital_ios,
271                    analog_in_buf_size,
272                    analog_out_buf_size,
273                    digital_in_buf_size,
274                    digital_out_buf_size,
275                })
276            }
277
278            devices.insert(device_ix as usize, DeviceInfo {
279                device_ix,
280                id,
281                revision: ver,
282                user_name: CStr::from_ptr(mem::transmute(user_name.as_mut_ptr())).to_str().unwrap().to_owned(),
283                name: CStr::from_ptr(mem::transmute(name.as_mut_ptr())).to_str().unwrap().to_owned(),
284                serial: CStr::from_ptr(mem::transmute(serial.as_mut_ptr())).to_str().unwrap().to_owned(),
285                in_use: in_use != 0,
286                configs,
287            })
288        }
289
290        Ok(DeviceInfoList { devices })
291    }
292}
293
294pub struct AnalogOutNode<'a> {
295    out: &'a AnalogOut<'a>,
296    ix: c_int,
297}
298
299impl<'a> AnalogOutNode<'a> {
300    pub fn set_function(&self, func: AnalogOutFunction) -> Result<()> {
301        unsafe {
302            match func {
303                AnalogOutFunction::Const { offset } => {
304                    handle_dwf_errors(FDwfAnalogOutNodeFunctionSet(self.out.device.handle, self.out.ix, self.ix, funcDC))?;
305                    handle_dwf_errors(FDwfAnalogOutNodeOffsetSet(self.out.device.handle, self.out.ix, self.ix, offset))?;
306                },
307                AnalogOutFunction::RampUp { frequency, amplitude, offset, symmetry, phase_deg } => {
308                    handle_dwf_errors(FDwfAnalogOutNodeFunctionSet(self.out.device.handle, self.out.ix, self.ix, funcRampUp))?;
309                    handle_dwf_errors(FDwfAnalogOutNodeFrequencySet(self.out.device.handle, self.out.ix, self.ix, frequency))?;
310                    handle_dwf_errors(FDwfAnalogOutNodeAmplitudeSet(self.out.device.handle, self.out.ix, self.ix, amplitude))?;
311                    handle_dwf_errors(FDwfAnalogOutNodeOffsetSet(self.out.device.handle, self.out.ix, self.ix, offset))?;
312                    handle_dwf_errors(FDwfAnalogOutNodeSymmetrySet(self.out.device.handle, self.out.ix, self.ix, symmetry))?;
313                    handle_dwf_errors(FDwfAnalogOutNodePhaseSet(self.out.device.handle, self.out.ix, self.ix, phase_deg))?;
314                },
315                AnalogOutFunction::RampDown { frequency, amplitude, offset, symmetry, phase_deg } => {
316                    handle_dwf_errors(FDwfAnalogOutNodeFunctionSet(self.out.device.handle, self.out.ix, self.ix, funcRampDown))?;
317                    handle_dwf_errors(FDwfAnalogOutNodeFrequencySet(self.out.device.handle, self.out.ix, self.ix, frequency))?;
318                    handle_dwf_errors(FDwfAnalogOutNodeAmplitudeSet(self.out.device.handle, self.out.ix, self.ix, amplitude))?;
319                    handle_dwf_errors(FDwfAnalogOutNodeOffsetSet(self.out.device.handle, self.out.ix, self.ix, offset))?;
320                    handle_dwf_errors(FDwfAnalogOutNodeSymmetrySet(self.out.device.handle, self.out.ix, self.ix, symmetry))?;
321                    handle_dwf_errors(FDwfAnalogOutNodePhaseSet(self.out.device.handle, self.out.ix, self.ix, phase_deg))?;
322                },
323                AnalogOutFunction::Sine { frequency, amplitude, offset, symmetry, phase_deg } => {
324                    handle_dwf_errors(FDwfAnalogOutNodeFunctionSet(self.out.device.handle, self.out.ix, self.ix, funcSine))?;
325                    handle_dwf_errors(FDwfAnalogOutNodeFrequencySet(self.out.device.handle, self.out.ix, self.ix, frequency))?;
326                    handle_dwf_errors(FDwfAnalogOutNodeAmplitudeSet(self.out.device.handle, self.out.ix, self.ix, amplitude))?;
327                    handle_dwf_errors(FDwfAnalogOutNodeOffsetSet(self.out.device.handle, self.out.ix, self.ix, offset))?;
328                    handle_dwf_errors(FDwfAnalogOutNodeSymmetrySet(self.out.device.handle, self.out.ix, self.ix, symmetry))?;
329                    handle_dwf_errors(FDwfAnalogOutNodePhaseSet(self.out.device.handle, self.out.ix, self.ix, phase_deg))?;
330                },
331                AnalogOutFunction::Square { frequency, amplitude, offset, symmetry, phase_deg } => {
332                    handle_dwf_errors(FDwfAnalogOutNodeFunctionSet(self.out.device.handle, self.out.ix, self.ix, funcSquare))?;
333                    handle_dwf_errors(FDwfAnalogOutNodeFrequencySet(self.out.device.handle, self.out.ix, self.ix, frequency))?;
334                    handle_dwf_errors(FDwfAnalogOutNodeAmplitudeSet(self.out.device.handle, self.out.ix, self.ix, amplitude))?;
335                    handle_dwf_errors(FDwfAnalogOutNodeOffsetSet(self.out.device.handle, self.out.ix, self.ix, offset))?;
336                    handle_dwf_errors(FDwfAnalogOutNodeSymmetrySet(self.out.device.handle, self.out.ix, self.ix, symmetry))?;
337                    handle_dwf_errors(FDwfAnalogOutNodePhaseSet(self.out.device.handle, self.out.ix, self.ix, phase_deg))?;
338                },
339                AnalogOutFunction::Triangle { frequency, amplitude, offset, symmetry, phase_deg } => {
340                    handle_dwf_errors(FDwfAnalogOutNodeFunctionSet(self.out.device.handle, self.out.ix, self.ix, funcTriangle))?;
341                    handle_dwf_errors(FDwfAnalogOutNodeFrequencySet(self.out.device.handle, self.out.ix, self.ix, frequency))?;
342                    handle_dwf_errors(FDwfAnalogOutNodeAmplitudeSet(self.out.device.handle, self.out.ix, self.ix, amplitude))?;
343                    handle_dwf_errors(FDwfAnalogOutNodeOffsetSet(self.out.device.handle, self.out.ix, self.ix, offset))?;
344                    handle_dwf_errors(FDwfAnalogOutNodeSymmetrySet(self.out.device.handle, self.out.ix, self.ix, symmetry))?;
345                    handle_dwf_errors(FDwfAnalogOutNodePhaseSet(self.out.device.handle, self.out.ix, self.ix, phase_deg))?;
346                },
347            }
348        }
349        Ok(())
350    }
351
352    pub fn set_enabled(&self, enabled: bool) -> Result<()> {
353        unsafe {
354            handle_dwf_errors(FDwfAnalogOutNodeEnableSet(self.out.device.handle, self.out.ix, self.ix, to_c_bool(enabled)))?;
355        }
356        Ok(())
357    }
358}
359
360pub enum AnalogOutFunction {
361    Const { offset: f64 },
362    RampUp { frequency: f64, amplitude: f64, offset: f64, symmetry: f64, phase_deg: f64 },
363    RampDown { frequency: f64, amplitude: f64, offset: f64, symmetry: f64, phase_deg: f64 },
364    Sine { frequency: f64, amplitude: f64, offset: f64, symmetry: f64, phase_deg: f64 },
365    Square { frequency: f64, amplitude: f64, offset: f64, symmetry: f64, phase_deg: f64 },
366    Triangle { frequency: f64, amplitude: f64, offset: f64, symmetry: f64, phase_deg: f64 },
367}
368
369#[derive(Copy, Clone, PartialEq, Debug)]
370#[repr(isize)]
371pub enum AnalogOutIdleMode {
372    Disable = DwfAnalogOutIdleDisable as isize,
373    Offset = DwfAnalogOutIdleOffset as isize,
374    Initial = DwfAnalogOutIdleInitial as isize,
375}
376
377impl AnalogOutIdleMode {
378    fn code(self) -> DwfAnalogOutIdle {
379        self as DwfAnalogOutIdle
380    }
381
382    fn from_code(code: DwfAnalogOutIdle) -> AnalogOutIdleMode {
383        unsafe { mem::transmute(code as isize) }
384    }
385}
386
387pub struct AnalogOut<'a> {
388    device: &'a Device,
389    ix: c_int,
390}
391
392impl<'a> AnalogOut<'a> {
393    pub fn node(&self, ix: u32) -> AnalogOutNode {
394        AnalogOutNode {
395            out: &self,
396            ix: ix as c_int,
397        }
398    }
399
400    pub fn set_duration(&self, duration: Duration) -> Result<()> {
401        unsafe {
402            handle_dwf_errors(FDwfAnalogOutRunSet(self.device.handle, self.ix, duration.num_nanoseconds().unwrap() as f64 / 1e9))?;
403        }
404        Ok(())
405    }
406
407    pub fn set_repeat_count(&self, repeat_cnt: i32) -> Result<()> {
408        unsafe {
409            handle_dwf_errors(FDwfAnalogOutRepeatSet(self.device.handle, self.ix, repeat_cnt))?;
410        }
411        Ok(())
412    }
413
414    pub fn set_trigger_source(&self, src: TriggerSource) -> Result<()> {
415        unsafe {
416            handle_dwf_errors(FDwfAnalogOutTriggerSourceSet(self.device.handle, self.ix, src.code()))?;
417        }
418        Ok(())
419    }
420
421    pub fn set_idle_mode(&self, mode: AnalogOutIdleMode) -> Result<()> {
422        unsafe {
423            handle_dwf_errors(FDwfAnalogOutIdleSet(self.device.handle, self.ix, mode.code()))?;
424        }
425        Ok(())
426    }
427
428    pub fn start(&self) -> Result<()> {
429        unsafe {
430            handle_dwf_errors(FDwfAnalogOutConfigure(self.device.handle, self.ix, to_c_bool(true)))?;
431        }
432        Ok(())
433    }
434
435    pub fn stop(&self) -> Result<()> {
436        unsafe {
437            handle_dwf_errors(FDwfAnalogOutConfigure(self.device.handle, self.ix, to_c_bool(false)))?;
438        }
439        Ok(())
440    }
441}
442
443pub struct AnalogIO<'a> {
444    device: &'a Device,
445}
446
447impl<'a> AnalogIO<'a> {
448    pub fn set_enabled(&self, enabled: bool) -> Result<()> {
449        unsafe {
450            handle_dwf_errors(FDwfAnalogIOEnableSet(self.device.handle, to_c_bool(enabled)))?;
451        }
452        Ok(())
453    }
454
455    pub fn channel(&self, ix: i32) -> AnalogIOChannel {
456        AnalogIOChannel {
457            io: self,
458            ix: ix as c_int,
459        }
460    }
461}
462
463pub struct AnalogIOChannel<'a> {
464    io: &'a AnalogIO<'a>,
465    ix: c_int,
466}
467
468impl<'a> AnalogIOChannel<'a> {
469    pub fn node(&self, ix: i32) -> AnalogIOChannelNode {
470        AnalogIOChannelNode {
471            channel: self,
472            ix: ix as c_int,
473        }
474    }
475}
476
477pub struct AnalogIOChannelNode<'a> {
478    channel: &'a AnalogIOChannel<'a>,
479    ix: c_int,
480}
481
482impl<'a> AnalogIOChannelNode<'a> {
483    pub fn set_value(&self, value: f64) -> Result<()> {
484        unsafe {
485            handle_dwf_errors(FDwfAnalogIOChannelNodeSet(self.channel.io.device.handle, self.channel.ix, self.ix, value))?;
486        }
487        Ok(())
488    }
489}
490
491
492pub struct AnalogIn<'a> {
493    device: &'a Device,
494}
495
496impl<'a> AnalogIn<'a> {
497    pub fn start(&self) -> Result<()> {
498        unsafe {
499            handle_dwf_errors(FDwfAnalogInConfigure(self.device.handle, to_c_bool(false), to_c_bool(true)))?;
500        }
501        Ok(())
502    }
503
504    pub fn set_frequency(&self, freq: f64) -> Result<()> {
505        unsafe {
506            handle_dwf_errors(FDwfAnalogInFrequencySet(self.device.handle, freq))?;
507        }
508        Ok(())
509    }
510
511    pub fn set_buffer_size(&self, buf_size: u32) -> Result<()> {
512        unsafe {
513            handle_dwf_errors(FDwfAnalogInBufferSizeSet(self.device.handle, buf_size as i32))?;
514        }
515        Ok(())
516    }
517
518    pub fn set_record_mode(&self, length: f64) -> Result<()> {
519        unsafe {
520            handle_dwf_errors(FDwfAnalogInRecordLengthSet(self.device.handle, length))?;
521            handle_dwf_errors(FDwfAnalogInAcquisitionModeSet(self.device.handle, acqmodeRecord as ACQMODE))?;
522        }
523        Ok(())
524    }
525
526    pub fn channel(&self, ix: i32) -> AnalogInChannel {
527        AnalogInChannel {
528            input: &self,
529            ix: ix as c_int,
530        }
531    }
532
533    pub fn get_status(&self) -> Result<AnalogAcquisitionStatus> {
534        unsafe {
535            let mut state: DwfState = mem::uninitialized();
536            handle_dwf_errors(FDwfAnalogInStatus(self.device.handle, to_c_bool(true), (&mut state) as *mut DwfState))?;
537            Ok(match state {
538                DwfStateReady => AnalogAcquisitionStatus::Ready,
539                DwfStateConfig => AnalogAcquisitionStatus::Config,
540                DwfStatePrefill => AnalogAcquisitionStatus::Prefill,
541                DwfStateArmed => AnalogAcquisitionStatus::Armed,
542                DwfStateWait => AnalogAcquisitionStatus::Waiting,
543                DwfStateRunning => AnalogAcquisitionStatus::Running,
544                DwfStateDone => AnalogAcquisitionStatus::Done,
545                _ => panic!(),
546            })
547        }
548    }
549
550    pub fn get_samples_left(&self) -> Result<i32> {
551        unsafe {
552            let mut ret = mem::uninitialized();
553            handle_dwf_errors(FDwfAnalogInStatusSamplesLeft(self.device.handle, &mut ret as *mut c_int))?;
554            Ok(ret)
555        }
556    }
557
558    pub fn get_record_status(&self) -> Result<(i32, i32, i32)> {
559        unsafe {
560            let (mut available, mut lost, mut corrupted) = mem::uninitialized();
561            handle_dwf_errors(FDwfAnalogInStatusRecord(self.device.handle,
562                                                       &mut available as *mut c_int,
563                                                       &mut lost as *mut c_int,
564                                                       &mut corrupted as *mut c_int
565            ))?;
566            Ok((available, lost, corrupted))
567        }
568    }
569}
570
571#[derive(Eq, PartialEq, Debug)]
572pub enum AnalogAcquisitionStatus {
573    Ready = DwfStateReady as isize,
574    Config = DwfStateConfig as isize,
575    Prefill = DwfStatePrefill as isize,
576    Armed = DwfStateArmed as isize,
577    Waiting = DwfStateWait as isize,
578    Running = DwfStateRunning as isize,
579    Done = DwfStateDone as isize,
580}
581
582pub struct AnalogInChannel<'a> {
583    input: &'a AnalogIn<'a>,
584    ix: c_int,
585}
586
587impl<'a> AnalogInChannel<'a> {
588    pub fn set_offset(&self, offset: f64) -> Result<()> {
589        unsafe {
590            handle_dwf_errors(FDwfAnalogInChannelOffsetSet(self.input.device.handle, self.ix, offset))?;
591        }
592        Ok(())
593    }
594
595    pub fn set_range(&self, range: f64) -> Result<()> {
596        unsafe {
597            handle_dwf_errors(FDwfAnalogInChannelRangeSet(self.input.device.handle, self.ix, range))?;
598        }
599        Ok(())
600    }
601
602    pub fn fetch_samples(&self, dest: &mut Vec<f64>, available: i32) -> Result<()> {
603        unsafe {
604            let original_len = dest.len();
605            dest.reserve(available as usize);
606            dest.set_len(original_len + available as usize);
607            handle_dwf_errors(FDwfAnalogInStatusData(self.input.device.handle, self.ix,
608                                                     dest.as_mut_ptr().offset(original_len as isize), available))?;
609        }
610        Ok(())
611    }
612}
613
614
615pub struct Device {
616    handle: HDWF,
617}
618
619impl Device {
620    pub fn set_auto_configure(&self, enabled: bool) -> Result<()> {
621        unsafe {
622            handle_dwf_errors(FDwfDeviceAutoConfigureSet(self.handle, to_c_bool(enabled)))?;
623        }
624        Ok(())
625    }
626
627    pub fn reset(&self) -> Result<()> {
628        unsafe {
629            handle_dwf_errors(FDwfDeviceReset(self.handle))?;
630        }
631        Ok(())
632    }
633
634    pub fn set_enabled(&self, enabled: bool) -> Result<()> {
635        unsafe {
636            handle_dwf_errors(FDwfDeviceEnableSet(self.handle, to_c_bool(enabled)))?;
637        }
638        Ok(())
639    }
640
641    pub fn analog_out(&self, ix: u32) -> AnalogOut {
642        AnalogOut {
643            device: &self,
644            ix: ix as c_int,
645        }
646    }
647
648    pub fn analog_io(&self) -> AnalogIO {
649        AnalogIO {
650            device: &self,
651        }
652    }
653
654    pub fn analog_input(&self) -> AnalogIn {
655        AnalogIn {
656            device: &self,
657        }
658    }
659}
660
661impl Drop for Device {
662    fn drop(&mut self) {
663        unsafe {
664            FDwfDeviceClose(self.handle);
665        }
666    }
667}