1#![warn(missing_docs)]
9
10use std::fmt;
11use std::sync::{Arc, RwLock};
12use std::thread;
13use std::time;
14
15use crossbeam_channel::RecvError;
16
17use serde::{Deserialize, Serialize};
18
19mod device;
20use device::gsusb::*;
21use device::*;
22
23pub mod c;
24#[cfg(feature = "python")]
26pub mod python;
27
28#[derive(Debug)]
30pub enum Error {
31 DeviceError(device::Error),
33 DeviceNotFound,
35 Timeout,
37 Running,
39 NotRunning,
41 InvalidChannel,
43 InvalidBitrate(u32),
45 UnsupportedFeature(&'static str),
47}
48impl From<device::Error> for Error {
49 fn from(e: device::Error) -> Error {
50 Error::DeviceError(e)
53 }
54}
55
56#[derive(Debug, Clone)]
58pub struct Frame {
59 pub can_id: u32,
61
62 pub can_dlc: u8,
64
65 pub channel: u8,
67
68 pub data: Vec<u8>,
70
71 pub ext: bool,
74
75 pub fd: bool,
77
78 pub brs: bool,
80
81 pub esi: bool,
83
84 pub loopback: bool,
87
88 pub err: bool,
90
91 pub rtr: bool,
93
94 pub timestamp: Option<time::Duration>,
96}
97impl Frame {
98 fn data_as_array(&self) -> [u8; 64] {
99 let mut data = [0u8; 64];
100 data[..64].clone_from_slice(&self.data[..64]);
101 data
102 }
103 fn to_host_frame(&self) -> HostFrame {
105 let mut can_id = if self.ext {
107 self.can_id | GSUSB_EXT_FLAG
108 } else {
109 self.can_id
110 };
111 can_id = if self.rtr {
113 can_id | GSUSB_RTR_FLAG
114 } else {
115 can_id
116 };
117 can_id = if self.err {
118 can_id | GSUSB_ERR_FLAG
119 } else {
120 can_id
121 };
122
123 HostFrame {
124 echo_id: 1,
125 flags: 0,
126 reserved: 0,
127 can_id,
128 can_dlc: self.can_dlc,
129 channel: self.channel,
130 data: self.data_as_array(),
131 }
132 }
133 pub fn default() -> Frame {
135 Frame {
136 can_id: 0,
137 can_dlc: 0,
138 data: vec![0; 64],
139 channel: 0,
140 ext: false,
141 fd: false,
142 loopback: false,
143 rtr: false,
144 brs: false,
145 esi: false,
146 err: false,
147 timestamp: None,
148 }
149 }
150 fn from_host_frame(hf: HostFrame) -> Frame {
151 let ext = (hf.can_id & GSUSB_EXT_FLAG) > 0;
154 let rtr = (hf.can_id & GSUSB_RTR_FLAG) > 0;
156 let err = (hf.can_id & GSUSB_ERR_FLAG) > 0;
157 let can_id = hf.can_id & 0x1FFF_FFFF;
159 let loopback = hf.echo_id != GSUSB_RX_ECHO_ID;
161 let fd = (hf.flags & GS_CAN_FLAG_FD) > 0;
163 let brs = (hf.flags & GS_CAN_FLAG_BRS) > 0;
164 let esi = (hf.flags & GS_CAN_FLAG_ESI) > 0;
165
166 Frame {
167 can_id,
168 can_dlc: hf.can_dlc,
169 data: hf.data.to_vec(),
170 channel: hf.channel,
171 ext,
172 loopback,
173 rtr,
174 fd,
175 brs,
176 esi,
177 err,
178 timestamp: None,
179 }
180 }
181
182 pub fn data_len(&self) -> usize {
184 match self.can_dlc {
185 0..=8 => self.can_dlc as usize,
186 9 => 12,
187 10 => 16,
188 11 => 20,
189 12 => 24,
190 13 => 32,
191 14 => 48,
192 15 => 64,
193 16..=u8::MAX => panic!("invalid DLC value"),
194 }
195 }
196}
197
198#[derive(Debug, Serialize, Deserialize, Clone)]
200pub struct Channel {
201 pub bitrate: u32,
203 pub enabled: bool,
205 pub loopback: bool,
207 pub monitor: bool,
209 pub fd: bool,
211 pub data_bitrate: u32,
213}
214
215pub struct Interface {
217 dev: Device,
218 running: Arc<RwLock<bool>>,
219
220 can_clock: u32,
221 channel_count: usize,
223 sw_version: u32,
224 hw_version: u32,
225 features: u32,
226
227 channels: Vec<Channel>,
228}
229
230impl fmt::Debug for Interface {
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 f.debug_struct("Interface")
233 .field("running", &(*self.running.read().unwrap()))
234 .field("can_clock", &self.can_clock)
235 .field("channel_count", &self.channel_count)
236 .field("sw_version", &self.sw_version)
237 .field("hw_version", &self.hw_version)
238 .field("channels", &self.channels)
239 .finish()
240 }
241}
242
243impl Interface {
244 pub fn new() -> Result<Interface, Error> {
247 let mut dev = match Device::new(UsbContext::new()) {
248 Ok(d) => d,
249 Err(_) => return Err(Error::DeviceNotFound),
250 };
251
252 let dev_config = dev.get_device_config()?;
253 let bt_consts = dev.get_bit_timing_consts()?;
254
255 let channel_count = dev_config.icount as usize;
256
257 let mut channels = Vec::new();
258 for _ in 0..(channel_count + 1) {
260 channels.push(Channel {
261 bitrate: 0,
262 enabled: true,
263 loopback: false,
264 monitor: false,
265 fd: false,
266 data_bitrate: 0,
267 });
268 }
269
270 let i = Interface {
271 dev,
272 running: Arc::new(RwLock::from(false)),
273
274 channel_count,
275 can_clock: bt_consts.fclk_can,
276 sw_version: dev_config.sw_version,
277 hw_version: dev_config.hw_version,
278 features: bt_consts.feature,
279
280 channels,
281 };
282
283 Ok(i)
284 }
285
286 pub fn start(
291 &mut self,
292 mut rx_callback: impl FnMut(Frame) + Sync + Send + 'static,
293 ) -> Result<(), Error> {
294 for (i, ch) in self.channels.iter().enumerate() {
296 let mut flags = 0;
297 if ch.monitor {
300 if (self.features & GS_CAN_FEATURE_LISTEN_ONLY) == 0 {
301 return Err(Error::UnsupportedFeature("Monitor"));
302 }
303 flags |= GS_CAN_MODE_LISTEN_ONLY;
304 }
305 if ch.loopback {
306 if (self.features & GS_CAN_FEATURE_LOOP_BACK) == 0 {
307 return Err(Error::UnsupportedFeature("Loopback"));
308 }
309 flags |= GS_CAN_MODE_LOOP_BACK;
310 }
311 if ch.fd {
312 if !self.supports_fd() {
313 return Err(Error::UnsupportedFeature("FD"));
314 }
315 flags |= GS_CAN_MODE_FD;
316 }
317
318 let mode = Mode {
319 mode: CanMode::Start as u32,
320 flags,
321 };
322 if ch.enabled {
323 self.dev.set_mode(i as u16, mode).unwrap();
324 }
325 }
326
327 {
328 *self.running.write().unwrap() = true;
329 }
330
331 let can_rx = self.dev.can_rx_recv.clone();
333 let running = Arc::clone(&self.running);
334 let start_time = time::Instant::now();
335 thread::spawn(move || {
336 while *running.read().unwrap() {
337 match can_rx.recv() {
338 Ok(hf) => {
339 let mut f = Frame::from_host_frame(hf);
340 f.timestamp = Some(time::Instant::now().duration_since(start_time));
341 rx_callback(f)
342 }
343 Err(RecvError) => {
344 break;
346 }
347 }
348 }
349 });
350
351 self.dev.start_transfers().unwrap();
352 Ok(())
353 }
354
355 pub fn stop(&mut self) -> Result<(), Error> {
357 for (i, ch) in self.channels.iter().enumerate() {
359 let mode = Mode {
360 mode: CanMode::Reset as u32,
361 flags: 0,
362 };
363 if ch.enabled {
364 self.dev.set_mode(i as u16, mode).unwrap();
365 }
366 }
367
368 self.dev.stop_transfers().unwrap();
369 *self.running.write().unwrap() = false;
370 Ok(())
371 }
372
373 pub fn set_bitrate(&mut self, channel: usize, bitrate: u32) -> Result<(), Error> {
375 if channel > self.channel_count {
376 return Err(Error::InvalidChannel);
377 }
378
379 let bt = calculate_bit_timing(self.can_clock, bitrate)?;
380 self.dev
381 .set_bit_timing(channel as u16, bt)
382 .expect("failed to set bit timing");
383
384 self.channels[channel].bitrate = bitrate;
385 Ok(())
386 }
387
388 pub fn set_data_bitrate(&mut self, channel: usize, bitrate: u32) -> Result<(), Error> {
390 if !self.supports_fd() {
391 return Err(Error::UnsupportedFeature("FD"));
392 }
393
394 if channel > self.channel_count {
395 return Err(Error::InvalidChannel);
396 }
397
398 let bt = calculate_bit_timing(self.can_clock, bitrate)?;
399 self.dev
400 .set_data_bit_timing(channel as u16, bt)
401 .expect("failed to set bit timing");
402
403 self.channels[channel].data_bitrate = bitrate;
404 Ok(())
405 }
406
407 pub fn set_bit_timing(
409 &mut self,
410 channel: usize,
411 brp: u32,
412 phase_seg1: u32,
413 phase_seg2: u32,
414 sjw: u32,
415 ) -> Result<(), Error> {
416 let bt = BitTiming {
417 brp,
418 prop_seg: 0,
419 phase_seg1,
420 phase_seg2,
421 sjw,
422 };
423 self.dev
424 .set_bit_timing(channel as u16, bt)
425 .expect("failed to set bit timing");
426 Ok(())
427 }
428
429 pub fn set_monitor(&mut self, channel: usize, enabled: bool) -> Result<(), Error> {
432 if self.features & GS_CAN_FEATURE_LISTEN_ONLY == 0 {
433 return Err(Error::UnsupportedFeature("Monitor"));
434 }
435 if channel > self.channel_count {
436 return Err(Error::InvalidChannel);
437 }
438 if *self.running.read().unwrap() {
439 return Err(Error::Running);
440 }
441
442 self.channels[channel].monitor = enabled;
443 Ok(())
444 }
445
446 pub fn set_enabled(&mut self, channel: usize, enabled: bool) -> Result<(), Error> {
449 if channel > self.channel_count {
450 return Err(Error::InvalidChannel);
451 }
452 if *self.running.read().unwrap() {
453 return Err(Error::Running);
454 }
455
456 self.channels[channel].enabled = enabled;
457 Ok(())
458 }
459
460 pub fn set_loopback(&mut self, channel: usize, enabled: bool) -> Result<(), Error> {
466 if self.features & GS_CAN_FEATURE_LOOP_BACK == 0 {
467 return Err(Error::UnsupportedFeature("Loopback"));
468 }
469 if channel > self.channel_count {
470 return Err(Error::InvalidChannel);
471 }
472 if *self.running.read().unwrap() {
473 return Err(Error::Running);
474 }
475
476 self.channels[channel].loopback = enabled;
477 Ok(())
478 }
479
480 pub fn set_fd(&mut self, channel: usize, enabled: bool) -> Result<(), Error> {
482 if !self.supports_fd() {
483 return Err(Error::UnsupportedFeature("FD"));
484 }
485 if channel > self.channel_count {
486 return Err(Error::InvalidChannel);
487 }
488 if *self.running.read().unwrap() {
489 return Err(Error::Running);
490 }
491
492 self.channels[channel].fd = enabled;
493 Ok(())
494 }
495
496 pub fn supports_fd(&self) -> bool {
498 (self.features & GS_CAN_FEATURE_FD) > 0
499 }
500
501 pub fn send(&mut self, f: Frame) -> Result<(), Error> {
503 if !*self.running.read().unwrap() {
504 return Err(Error::NotRunning);
505 }
506
507 self.dev.send(f.to_host_frame()).unwrap();
508 Ok(())
509 }
510
511 pub fn channels(&self) -> usize {
513 self.channel_count + 1
514 }
515}
516
517fn calculate_bit_timing(clk: u32, bitrate: u32) -> Result<BitTiming, Error> {
518 let max_brp = 32;
519 let min_seg1 = 3;
520 let max_seg1 = 18;
521 let min_seg2 = 2;
522 let max_seg2 = 8;
523 let tolerances = vec![0.0, 0.1 / 100.0, 0.5 / 100.0];
524
525 for tolerance in tolerances {
526 let tmp = clk as f32 / bitrate as f32;
527 for brp in 1..(max_brp + 1) {
528 let btq = tmp / brp as f32;
529 let btq_rounded = btq.round() as u32;
530
531 if (4..=32).contains(&btq_rounded) {
532 let err = ((btq / (btq_rounded as f32) - 1.0) * 10000.0).round() / 10000.0;
533 if err.abs() > tolerance {
534 continue;
536 }
537 }
538
539 for seg1 in min_seg1..max_seg1 {
540 let seg2 = btq_rounded - seg1 - 1;
542 if seg2 < min_seg2 || seg2 > max_seg2 {
543 continue;
545 }
546 return Ok(BitTiming {
548 brp,
549 prop_seg: 0,
550 phase_seg1: seg1,
551 phase_seg2: seg2,
552 sjw: 1,
553 });
554 }
555 }
556 }
557 Err(Error::InvalidBitrate(bitrate))
558}
559
560#[allow(dead_code)]
561fn effective_bitrate(clk: u32, bt: BitTiming) -> u32 {
562 clk / bt.brp / (bt.prop_seg + bt.phase_seg1 + bt.phase_seg2 + 1)
563}
564
565#[cfg(test)]
566mod tests {
567 use super::*;
568 #[test]
569 fn test_bit_timing() {
570 let clk = 24000000;
571 let bitrates = vec![1000000, 500000, 250000, 125000, 33333];
572 for b in bitrates {
573 let bt = calculate_bit_timing(clk, b).unwrap();
574
575 println!("{:?}", &bt);
577 let err = 100.0 * (1.0 - (effective_bitrate(clk, bt) as f32 / b as f32).abs());
578 println!("{:?}", err);
579 assert!(err < 0.5);
580 }
581 }
582}