1use crate::channel::Channel;
9use crate::error::{CanError, CanOkError};
10use crate::peak_lib;
11use crate::peak_can;
12use std::ffi::c_void;
13
14#[derive(PartialEq, Debug)]
15pub enum IOConfig {
16 In,
17 InOut,
18}
19
20impl TryFrom<u32> for IOConfig {
21 type Error = ();
22
23 fn try_from(value: u32) -> Result<Self, Self::Error> {
24 match value {
25 0 => Ok(IOConfig::In),
26 1 => Ok(IOConfig::InOut),
27 _ => Err(()),
28 }
29 }
30}
31
32impl From<IOConfig> for u32 {
33 fn from(value: IOConfig) -> Self {
34 match value {
35 IOConfig::In => 0,
36 IOConfig::InOut => 1,
37 }
38 }
39}
40
41pub(crate) trait HasDigitalConfiguration {}
42
43pub trait DigitalConfiguration {
44 fn digital_mode(&self, pin: u8) -> Result<IOConfig, CanError>;
45 fn digital_mode_word(&self) -> Result<u32, CanError>;
46}
47
48impl<T: HasDigitalConfiguration + Channel> DigitalConfiguration for T {
49 fn digital_mode(&self, pin: u8) -> Result<IOConfig, CanError> {
50 let mut data = [0u8; 4];
51 let code = unsafe {
52 peak_lib()?.CAN_GetValue(
53 self.channel(),
54 peak_can::PEAK_IO_DIGITAL_CONFIGURATION as u8,
55 data.as_mut_ptr() as *mut c_void,
56 data.len() as u32,
57 )
58 };
59
60 match CanOkError::try_from(code) {
61 Ok(CanOkError::Ok) => {
62 let mode_word = u32::from_le_bytes(data);
63 let pin_enabled = mode_word & (1 << pin);
64
65 if pin_enabled == 0 {
66 Ok(IOConfig::In)
67 } else {
68 Ok(IOConfig::InOut)
69 }
70 }
71 Ok(CanOkError::Err(err)) => Err(err),
72 Err(_) => Err(CanError::Unknown),
73 }
74 }
75
76 fn digital_mode_word(&self) -> Result<u32, CanError> {
77 let mut data = [0u8; 4];
78 let code = unsafe {
79 peak_lib()?.CAN_GetValue(
80 self.channel(),
81 peak_can::PEAK_IO_DIGITAL_CONFIGURATION as u8,
82 data.as_mut_ptr() as *mut c_void,
83 data.len() as u32,
84 )
85 };
86
87 match CanOkError::try_from(code) {
88 Ok(CanOkError::Ok) => Ok(u32::from_le_bytes(data)),
89 Ok(CanOkError::Err(err)) => Err(err),
90 Err(_) => Err(CanError::Unknown),
91 }
92 }
93}
94
95pub(crate) trait HasSetDigitalConfiguration {}
96
97pub trait SetDigitalConfiguration {
98 fn set_digital_mode(&self, pin: u8, mode: IOConfig) -> Result<(), CanError>;
99 fn set_digital_mode_word(&self, mode_word: u32) -> Result<(), CanError>;
100}
101
102impl<T: HasSetDigitalConfiguration + Channel> SetDigitalConfiguration for T {
103 fn set_digital_mode(&self, pin: u8, mode: IOConfig) -> Result<(), CanError> {
104 let mut data = [0u8; 4];
105 let code = unsafe {
106 peak_lib()?.CAN_GetValue(
107 self.channel(),
108 peak_can::PEAK_IO_DIGITAL_CONFIGURATION as u8,
109 data.as_mut_ptr() as *mut c_void,
110 data.len() as u32,
111 )
112 };
113
114 let mode_word = match CanOkError::try_from(code) {
115 Ok(CanOkError::Ok) => u32::from_le_bytes(data),
116 Ok(CanOkError::Err(err)) => return Err(err),
117 Err(_) => return Err(CanError::Unknown),
118 };
119
120 let mode_word = match mode {
121 IOConfig::In => mode_word | !(1 << pin),
122 IOConfig::InOut => mode_word | (1 << pin),
123 };
124 let mut data = mode_word.to_le_bytes();
125
126 let code = unsafe {
127 peak_lib()?.CAN_SetValue(
128 self.channel(),
129 peak_can::PEAK_IO_DIGITAL_CONFIGURATION as u8,
130 data.as_mut_ptr() as *mut c_void,
131 data.len() as u32,
132 )
133 };
134
135 return match CanOkError::try_from(code) {
136 Ok(CanOkError::Ok) => Ok(()),
137 Ok(CanOkError::Err(err)) => Err(err),
138 Err(_) => Err(CanError::Unknown),
139 };
140 }
141
142 fn set_digital_mode_word(&self, mode_word: u32) -> Result<(), CanError> {
143 let mut data = mode_word.to_le_bytes();
144 let code = unsafe {
145 peak_lib()?.CAN_SetValue(
146 self.channel(),
147 peak_can::PEAK_IO_DIGITAL_CONFIGURATION as u8,
148 data.as_mut_ptr() as *mut c_void,
149 data.len() as u32,
150 )
151 };
152
153 match CanOkError::try_from(code) {
154 Ok(CanOkError::Ok) => Ok(()),
155 Ok(CanOkError::Err(err)) => Err(err),
156 Err(_) => Err(CanError::Unknown),
157 }
158 }
159}
160
161#[derive(PartialEq, Debug)]
164pub enum IOValue {
165 Low,
166 High,
167}
168
169impl TryFrom<u32> for IOValue {
170 type Error = ();
171
172 fn try_from(value: u32) -> Result<Self, Self::Error> {
173 match value {
174 0 => Ok(IOValue::Low),
175 1 => Ok(IOValue::High),
176 _ => Err(()),
177 }
178 }
179}
180
181impl From<IOValue> for u32 {
182 fn from(value: IOValue) -> Self {
183 match value {
184 IOValue::Low => 0,
185 IOValue::High => 1,
186 }
187 }
188}
189
190#[allow(unused)]
191pub(crate) trait HasDigitalValue {}
192
193pub trait DigitalValue {
194 fn digital_value(&self, pin: u8) -> Result<IOValue, CanError>;
195 fn digital_value_word(&self) -> Result<u32, CanError>;
196}
197
198impl<T: HasSetDigitalValue + Channel> DigitalValue for T {
199 fn digital_value(&self, pin: u8) -> Result<IOValue, CanError> {
200 let mut data = [0u8; 4];
201 let code = unsafe {
202 peak_lib()?.CAN_GetValue(
203 self.channel(),
204 peak_can::PEAK_IO_DIGITAL_VALUE as u8,
205 data.as_mut_ptr() as *mut c_void,
206 data.len() as u32,
207 )
208 };
209
210 match CanOkError::try_from(code) {
211 Ok(CanOkError::Ok) => {
212 let mode_word = u32::from_le_bytes(data);
213 let pin_enabled = mode_word & (1 << pin);
214
215 if pin_enabled == 0 {
216 Ok(IOValue::Low)
217 } else {
218 Ok(IOValue::High)
219 }
220 }
221 Ok(CanOkError::Err(err)) => Err(err),
222 Err(_) => Err(CanError::Unknown),
223 }
224 }
225
226 fn digital_value_word(&self) -> Result<u32, CanError> {
227 let mut data = [0u8; 4];
228 let code = unsafe {
229 peak_lib()?.CAN_GetValue(
230 self.channel(),
231 peak_can::PEAK_IO_DIGITAL_VALUE as u8,
232 data.as_mut_ptr() as *mut c_void,
233 data.len() as u32,
234 )
235 };
236
237 match CanOkError::try_from(code) {
238 Ok(CanOkError::Ok) => Ok(u32::from_le_bytes(data)),
239 Ok(CanOkError::Err(err)) => Err(err),
240 Err(_) => Err(CanError::Unknown),
241 }
242 }
243}
244
245pub(crate) trait HasSetDigitalValue {}
246
247pub trait SetDigitalValue {
248 fn set_digital_value(&self, pin: u8, value: IOValue) -> Result<(), CanError>;
249 fn set_digital_value_word(&self, value_word: u32) -> Result<(), CanError>;
250}
251
252impl<T: HasSetDigitalValue + Channel> SetDigitalValue for T {
253 fn set_digital_value(&self, pin: u8, value: IOValue) -> Result<(), CanError> {
254 let mut data = [0u8; 4];
255 let code = unsafe {
256 peak_lib()?.CAN_GetValue(
257 self.channel(),
258 peak_can::PEAK_IO_DIGITAL_CONFIGURATION as u8,
259 data.as_mut_ptr() as *mut c_void,
260 data.len() as u32,
261 )
262 };
263
264 let mode_word = match CanOkError::try_from(code) {
265 Ok(CanOkError::Ok) => u32::from_le_bytes(data),
266 Ok(CanOkError::Err(err)) => return Err(err),
267 Err(_) => return Err(CanError::Unknown),
268 };
269
270 let mode_word = match value {
271 IOValue::Low => mode_word | !(1 << pin),
272 IOValue::High => mode_word | (1 << pin),
273 };
274 let mut data = mode_word.to_le_bytes();
275
276 let code = unsafe {
277 peak_lib()?.CAN_SetValue(
278 self.channel(),
279 peak_can::PEAK_IO_DIGITAL_VALUE as u8,
280 data.as_mut_ptr() as *mut c_void,
281 data.len() as u32,
282 )
283 };
284
285 return match CanOkError::try_from(code) {
286 Ok(CanOkError::Ok) => Ok(()),
287 Ok(CanOkError::Err(err)) => Err(err),
288 Err(_) => Err(CanError::Unknown),
289 };
290 }
291
292 fn set_digital_value_word(&self, value_word: u32) -> Result<(), CanError> {
293 let mut data = value_word.to_le_bytes();
294 let code = unsafe {
295 peak_lib()?.CAN_SetValue(
296 self.channel(),
297 peak_can::PEAK_IO_DIGITAL_VALUE as u8,
298 data.as_mut_ptr() as *mut c_void,
299 data.len() as u32,
300 )
301 };
302
303 match CanOkError::try_from(code) {
304 Ok(CanOkError::Ok) => Ok(()),
305 Ok(CanOkError::Err(err)) => Err(err),
306 Err(_) => Err(CanError::Unknown),
307 }
308 }
309}
310
311pub(crate) trait HasSetDigitalSet {}
314
315pub trait SetDigitalSet {
316 fn digital_set(&self, mask: u32) -> Result<(), CanError>;
317}
318
319impl<T: HasSetDigitalSet + Channel> SetDigitalSet for T {
320 fn digital_set(&self, mask: u32) -> Result<(), CanError> {
321 let mut data = mask.to_le_bytes();
322 let code = unsafe {
323 peak_lib()?.CAN_SetValue(
324 self.channel(),
325 peak_can::PEAK_IO_DIGITAL_SET as u8,
326 data.as_mut_ptr() as *mut c_void,
327 data.len() as u32,
328 )
329 };
330
331 match CanOkError::try_from(code) {
332 Ok(CanOkError::Ok) => Ok(()),
333 Ok(CanOkError::Err(err)) => Err(err),
334 Err(_) => Err(CanError::Unknown),
335 }
336 }
337}
338
339pub(crate) trait HasSetDigitalClear {}
342
343pub trait SetDigitalClear {
344 fn digital_clear(&self, mask: u32) -> Result<(), CanError>;
345}
346
347impl<T: HasSetDigitalClear + Channel> SetDigitalClear for T {
348 fn digital_clear(&self, mask: u32) -> Result<(), CanError> {
349 let mut data = mask.to_le_bytes();
350 let code = unsafe {
351 peak_lib()?.CAN_SetValue(
352 self.channel(),
353 peak_can::PEAK_IO_DIGITAL_CLEAR as u8,
354 data.as_mut_ptr() as *mut c_void,
355 data.len() as u32,
356 )
357 };
358
359 match CanOkError::try_from(code) {
360 Ok(CanOkError::Ok) => Ok(()),
361 Ok(CanOkError::Err(err)) => Err(err),
362 Err(_) => Err(CanError::Unknown),
363 }
364 }
365}
366
367pub(crate) trait HasAnalogValue {}
370
371pub trait AnalogValue {
372 fn analog_value(&self) -> Result<u32, CanError>;
373}
374
375impl<T: HasAnalogValue + Channel> AnalogValue for T {
376 fn analog_value(&self) -> Result<u32, CanError> {
377 let mut data = [0u8; 4];
378 let code = unsafe {
379 peak_lib()?.CAN_GetValue(
380 self.channel(),
381 peak_can::PEAK_IO_ANALOG_VALUE as u8,
382 data.as_mut_ptr() as *mut c_void,
383 data.len() as u32,
384 )
385 };
386
387 match CanOkError::try_from(code) {
388 Ok(CanOkError::Ok) => Ok(u32::from_le_bytes(data)),
389 Ok(CanOkError::Err(err)) => Err(err),
390 Err(_) => Err(CanError::Unknown),
391 }
392 }
393}