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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
use helios_dac_sys::*;
use crate::frame::*;
use crate::DeviceStatus;
pub struct HeliosDacWrapper {
dac: HeliosDac,
}
impl HeliosDacWrapper {
pub fn new() -> Self {
let dac = unsafe { HeliosDac::new() };
HeliosDacWrapper { dac }
}
pub fn open_devices(&mut self) -> Result<u32, HeliosError> {
let device_count = unsafe { self.dac.OpenDevices() };
if device_count < 0 {
parse_error(device_count)?;
}
Ok(device_count as u32)
}
pub fn close_devices(&mut self) -> Result<(), HeliosError> {
let result = unsafe { self.dac.CloseDevices() };
parse_error(result)
}
pub fn write_frame(&mut self, device_number: u32, frame: Frame) -> Result<(), HeliosError> {
let mut points = frame.points.into_iter().map(HeliosPoint::from).collect::<Vec<_>>();
let point_count = points.len() as u32;
let point_ptr = points.as_mut_ptr();
let result = unsafe { self.dac.WriteFrame(device_number, frame.pps, 0, point_ptr, point_count) };
parse_error(result)
}
pub fn status(&mut self, device_number: u32) -> Result<DeviceStatus, HeliosError> {
let status = unsafe { self.dac.GetStatus(device_number) };
if status < 0 {
parse_error(status)?;
}
match status {
0 => Ok(DeviceStatus::NotReady),
1 => Ok(DeviceStatus::Ready),
_ => unreachable!("invalid status returned")
}
}
pub fn firmware_version(&mut self, device_number: u32) -> Result<u32, HeliosError> {
let result = unsafe { self.dac.GetFirmwareVersion(device_number) };
if result < 0 {
parse_error(result)?;
}
Ok(result as u32)
}
pub fn name(&mut self, device_number: u32) -> Result<String, HeliosError> {
let mut name = String::new();
let name_ptr = name.as_mut_ptr() as *mut i8;
let result = unsafe { self.dac.GetName(device_number, name_ptr) };
parse_error(result)?;
Ok(name)
}
pub fn set_name(&mut self, device_number: u32, mut name: String) -> Result<(), HeliosError> {
let name_ptr = name.as_mut_ptr() as *mut i8;
let result = unsafe { self.dac.SetName(device_number, name_ptr) };
parse_error(result)
}
pub fn stop(&mut self, device_number: u32) -> Result<(), HeliosError> {
let result = unsafe { self.dac.Stop(device_number) };
parse_error(result)
}
pub fn set_shutter(&mut self, device_number: u32, level: bool) -> Result<(), HeliosError> {
let result = unsafe { self.dac.SetShutter(device_number, level) };
parse_error(result)
}
pub fn erase_firmware(&mut self, device_number: u32) -> Result<(), HeliosError> {
let result = unsafe { self.dac.EraseFirmware(device_number) };
parse_error(result)
}
}
fn parse_error(code: i32) -> Result<(), HeliosError> {
if code == helios_dac_sys::HELIOS_SUCCESS as i32 {
Ok(())
}else {
unimplemented!("error parsing not done yet")
}
}
#[derive(Debug)]
pub enum HeliosError {
NotInitialized = HELIOS_ERROR_NOT_INITIALIZED as isize,
InvalidDevNum = HELIOS_ERROR_INVALID_DEVNUM as isize,
NullPoints = HELIOS_ERROR_NULL_POINTS as isize,
TooManyPoints = HELIOS_ERROR_TOO_MANY_POINTS as isize,
PPSTooHigh = HELIOS_ERROR_PPS_TOO_HIGH as isize,
PPSTooLow = HELIOS_ERROR_PPS_TOO_LOW as isize,
DeviceClosed = HELIOS_ERROR_DEVICE_CLOSED as isize,
DeviceFrameReady = HELIOS_ERROR_DEVICE_FRAME_READY as isize,
DeviceSendControl = HELIOS_ERROR_DEVICE_SEND_CONTROL as isize,
DeviceResult = HELIOS_ERROR_DEVICE_RESULT as isize,
DeviceNullBuffer = HELIOS_ERROR_DEVICE_NULL_BUFFER as isize,
DeviceSignalTooLong = HELIOS_ERROR_DEVICE_SIGNAL_TOO_LONG as isize,
Libusb = HELIOS_ERROR_LIBUSB_BASE as isize
}
impl Drop for HeliosDacWrapper {
fn drop(&mut self) {
unsafe {
self.dac.destruct();
}
}
}
impl From<Point> for HeliosPoint {
fn from(point: Point) -> Self {
HeliosPoint {
x: point.coordinate.x,
y: point.coordinate.y,
r: point.color.r,
g: point.color.g,
b: point.color.b,
i: point.intensity
}
}
}