1pub mod dng;
6pub mod isa;
7pub mod lan;
8pub mod pcc;
9pub mod pci;
10pub mod usb;
11
12use crate::bus::Bus;
13use crate::error::{CanError, CanOkError};
14use crate::peak_lib;
15use crate::peak_can;
16
17use std::ops::Deref;
18
19pub const STANDARD_MASK: u32 = 0x07_FF;
20pub const EXTENDED_MASK: u32 = 0x1F_FF_FF_FF;
21
22#[derive(Debug, PartialEq)]
23pub enum MessageType {
24 Standard,
25 Extended,
26}
27
28#[derive(Debug, PartialEq)]
29pub enum FrameConstructionError {
30 TooMuchData,
31 CanIdMessageTypeMismatch,
32}
33
34#[derive(Debug, Copy, Clone)]
35pub struct CanFrame {
36 frame: peak_can::TPEAKMsg,
37}
38
39impl CanFrame {
40 const MAX_DLC: usize = 8;
41
42 pub fn new(
43 can_id: u32,
44 msg_type: MessageType,
45 data: &[u8],
46 ) -> Result<CanFrame, FrameConstructionError> {
47 if data.len() > Self::MAX_DLC {
48 Err(FrameConstructionError::TooMuchData)
49 } else {
50 let mut frame_data: [u8; 8] = [0; 8];
51 for (i, v) in data.into_iter().enumerate() {
52 frame_data[i] = *v;
53 }
54
55 match msg_type {
56 MessageType::Standard => Ok(CanFrame {
57 frame: peak_can::TPEAKMsg {
58 ID: can_id & STANDARD_MASK,
59 MSGTYPE: peak_can::PEAK_MESSAGE_STANDARD as u8,
60 LEN: data.len() as u8,
61 DATA: frame_data,
62 },
63 }),
64 MessageType::Extended => Ok(CanFrame {
65 frame: peak_can::TPEAKMsg {
66 ID: can_id & EXTENDED_MASK,
67 MSGTYPE: peak_can::PEAK_MESSAGE_EXTENDED as u8,
68 LEN: data.len() as u8,
69 DATA: frame_data,
70 },
71 }),
72 }
73 }
74 }
75
76 pub fn is_standard_frame(&self) -> bool {
77 !self.is_extended_frame()
79 }
80
81 pub fn is_extended_frame(&self) -> bool {
82 self.frame.MSGTYPE & peak_can::PEAK_MESSAGE_EXTENDED as u8 != 0
83 }
84
85 pub fn is_error_frame(&self) -> bool {
86 self.frame.MSGTYPE & peak_can::PEAK_MESSAGE_ERRFRAME as u8 != 0
87 }
88
89 pub fn is_echo_frame(&self) -> bool {
90 self.frame.MSGTYPE & peak_can::PEAK_MESSAGE_ECHO as u8 != 0
91 }
92
93 pub fn can_id(&self) -> u32 {
94 if self.is_standard_frame() {
95 self.frame.ID & STANDARD_MASK
96 } else {
97 self.frame.ID & EXTENDED_MASK
98 }
99 }
100
101 pub fn dlc(&self) -> u8 {
102 self.frame.LEN
103 }
104
105 pub fn data(&self) -> &[u8] {
106 &self.frame.DATA[0..self.dlc() as usize]
107 }
108
109 pub fn mut_data(&mut self) -> &mut [u8] {
110 let dlc = self.dlc();
111 &mut self.frame.DATA[0..dlc as usize]
112 }
113}
114
115impl Default for CanFrame {
116 fn default() -> Self {
117 CanFrame::new(0, MessageType::Standard, &[]).unwrap()
118 }
119}
120
121impl PartialEq for CanFrame {
122 fn eq(&self, other: &Self) -> bool {
123 if self.frame.ID != other.frame.ID {
124 return false;
125 }
126
127 if self.frame.LEN != other.frame.LEN {
128 return false;
129 }
130
131 if self.frame.MSGTYPE != other.frame.MSGTYPE {
132 return false;
133 }
134
135 if self.data() != other.data() {
136 return false;
137 }
138
139 true
140 }
141}
142
143#[derive(Debug, Copy, Clone)]
144pub struct CanFdFrame {
145 frame: peak_can::TPEAKMsgFD,
146}
147
148impl CanFdFrame {
149 const MAX_DATA_LENGTH: usize = 64;
150
151 pub fn new(
152 can_id: u32,
153 msg_type: MessageType,
154 data: &[u8],
155 fd: bool,
156 brs: bool,
157 ) -> Result<CanFdFrame, FrameConstructionError> {
158 if data.len() > Self::MAX_DATA_LENGTH {
159 Err(FrameConstructionError::TooMuchData)
160 } else {
161 let mut frame_data: [u8; Self::MAX_DATA_LENGTH] = [0; Self::MAX_DATA_LENGTH];
162 for (i, v) in data.into_iter().enumerate() {
163 frame_data[i] = *v;
164 }
165
166 match msg_type {
167 MessageType::Standard => Ok(CanFdFrame {
168 frame: peak_can::TPEAKMsgFD {
169 ID: can_id & STANDARD_MASK,
170 MSGTYPE: peak_can::PEAK_MESSAGE_STANDARD as u8 |
171 if fd { peak_can::PEAK_MESSAGE_FD as u8 } else { 0 } |
172 if brs { peak_can::PEAK_MESSAGE_BRS as u8 } else { 0 },
173 DLC: Self::calc_dlc(data.len()),
174 DATA: frame_data,
175 },
176 }),
177 MessageType::Extended => Ok(CanFdFrame {
178 frame: peak_can::TPEAKMsgFD {
179 ID: can_id & EXTENDED_MASK,
180 MSGTYPE: peak_can::PEAK_MESSAGE_EXTENDED as u8 |
181 if fd { peak_can::PEAK_MESSAGE_FD as u8 } else { 0 } |
182 if brs { peak_can::PEAK_MESSAGE_BRS as u8 } else { 0 },
183 DLC: Self::calc_dlc(data.len()),
184 DATA: frame_data,
185 },
186 }),
187 }
188 }
189 }
190
191 pub fn is_standard_frame(&self) -> bool {
192 self.frame.MSGTYPE & peak_can::PEAK_MESSAGE_STANDARD as u8 != 0
193 }
194
195 pub fn is_extended_frame(&self) -> bool {
196 if self.frame.MSGTYPE & peak_can::PEAK_MESSAGE_EXTENDED as u8 != 0 {
197 true
198 } else {
199 false
200 }
201 }
202
203 pub fn is_error_frame(&self) -> bool {
204 self.frame.MSGTYPE & peak_can::PEAK_MESSAGE_ERRFRAME as u8 != 0
205 }
206
207 pub fn is_echo_frame(&self) -> bool {
208 self.frame.MSGTYPE & peak_can::PEAK_MESSAGE_ECHO as u8 != 0
209 }
210
211 pub fn is_fd_frame(&self) -> bool {
212 self.frame.MSGTYPE & peak_can::PEAK_MESSAGE_FD as u8 != 0
213 }
214
215 pub fn can_id(&self) -> u32 {
216 if self.is_standard_frame() {
217 self.frame.ID & STANDARD_MASK
218 } else {
219 self.frame.ID & EXTENDED_MASK
220 }
221 }
222
223 pub fn dlc(&self) -> u8 {
224 self.frame.DLC
225 }
226
227 pub fn data(&self) -> &[u8] {
228 &self.frame.DATA[0..self.len() as usize]
229 }
230
231 pub fn mut_data(&mut self) -> &mut [u8] {
232 let len = self.len();
233 &mut self.frame.DATA[0..len as usize]
234 }
235
236 fn calc_dlc(len: usize) -> u8 {
237 match len {
238 0..=8 => len as u8,
239 9..=12 => 9,
240 13..=16 => 10,
241 17..=20 => 11,
242 21..=24 => 12,
243 25..=32 => 13,
244 33..=48 => 14,
245 49..=64 => 15,
246 _ => 15, }
248 }
249
250 pub fn len(&self) -> usize {
251 match self.dlc() {
252 0..=8 => self.dlc() as usize,
253 9 => 12,
254 10 => 16,
255 11 => 20,
256 12 => 24,
257 13 => 32,
258 14 => 48,
259 15 => 64,
260 _ => 64, }
262 }
263
264 pub fn is_empty(&self) -> bool {
265 self.len() == 0
266 }
267}
268
269impl Default for CanFdFrame {
270 fn default() -> Self {
271 CanFdFrame::new(0, MessageType::Standard, &[], false, false).unwrap()
272 }
273}
274
275impl PartialEq for CanFdFrame {
276 fn eq(&self, other: &Self) -> bool {
277 if self.frame.ID != other.frame.ID {
278 return false;
279 }
280
281 if self.frame.DLC != other.frame.DLC {
282 return false;
283 }
284
285 if self.frame.MSGTYPE != other.frame.MSGTYPE {
286 return false;
287 }
288
289 if self.data() != other.data() {
290 return false;
291 }
292
293 true
294 }
295}
296
297#[derive(Debug, Copy, Clone)]
298pub struct Timestamp {
299 timestamp: peak_can::TPEAKTimestamp,
300}
301
302impl Deref for Timestamp {
303 type Target = peak_can::TPEAKTimestamp;
304
305 fn deref(&self) -> &Self::Target {
306 &self.timestamp
307 }
308}
309
310impl Default for Timestamp {
311 fn default() -> Timestamp {
312 Timestamp {
313 timestamp: peak_can::TPEAKTimestamp {
314 micros: 0,
315 millis: 0,
316 millis_overflow: 0,
317 },
318 }
319 }
320}
321
322impl PartialEq for Timestamp {
323 fn eq(&self, other: &Self) -> bool {
324 if self.timestamp.micros != other.timestamp.micros {
325 return false;
326 }
327
328 if self.timestamp.millis != other.timestamp.millis {
329 return false;
330 }
331
332 if self.timestamp.millis_overflow != other.timestamp.millis_overflow {
333 return false;
334 }
335
336 true
337 }
338}
339
340#[derive(Debug, PartialEq)]
341pub struct CanSocket {
342 handle: u16,
343}
344
345impl CanSocket {
346 pub fn open<T: Bus>(bus: T, baud: Baudrate) -> Result<CanSocket, CanError> {
347 let handle = bus.channel();
348 let code = unsafe { peak_lib()?.CAN_Initialize(handle, baud.into(), 0, 0, 0) };
349
350 match CanOkError::try_from(code) {
351 Ok(CanOkError::Ok) => Ok(CanSocket { handle }),
352 Ok(CanOkError::Err(err)) => Err(err),
353 Err(_) => Err(CanError::Unknown),
354 }
355 }
356}
357
358trait HasRecvCan {}
359
360pub trait RecvCan {
361 fn recv(&self) -> Result<(CanFrame, Timestamp), CanError>;
362 fn recv_frame(&self) -> Result<CanFrame, CanError>;
363}
364
365trait HasRecvCanFd {}
366
367pub trait RecvCanFd {
368 fn recv_fd(&self) -> Result<(CanFdFrame, u64), CanError>;
369 fn recv_fd_frame(&self) -> Result<CanFdFrame, CanError>;
370}
371
372trait HasSendCan {}
373
374pub trait SendCan {
375 fn send(&self, frame: CanFrame) -> Result<(), CanError>;
376}
377
378trait HasSendCanFd {}
379
380pub trait SendCanFd {
381 fn send_fd(&self, frame: CanFdFrame) -> Result<(), CanError>;
382}
383
384trait Socket {
385 fn handle(&self) -> u16;
386}
387
388#[derive(Debug, PartialEq)]
391pub enum Baudrate {
392 Baud1M,
393 Baud800K,
394 Baud500K,
395 Baud250K,
396 Baud125K,
397 Baud100K,
398 Baud95K,
399 Baud83K,
400 Baud50K,
401 Baud47K,
402 Baud33K,
403 Baud20K,
404 Baud10K,
405 Baud5K,
406}
407
408impl From<Baudrate> for u16 {
409 fn from(value: Baudrate) -> Self {
410 let ret = match value {
411 Baudrate::Baud1M => peak_can::PEAK_BAUD_1M,
412 Baudrate::Baud800K => peak_can::PEAK_BAUD_800K,
413 Baudrate::Baud500K => peak_can::PEAK_BAUD_500K,
414 Baudrate::Baud250K => peak_can::PEAK_BAUD_250K,
415 Baudrate::Baud125K => peak_can::PEAK_BAUD_125K,
416 Baudrate::Baud100K => peak_can::PEAK_BAUD_100K,
417 Baudrate::Baud95K => peak_can::PEAK_BAUD_95K,
418 Baudrate::Baud83K => peak_can::PEAK_BAUD_83K,
419 Baudrate::Baud50K => peak_can::PEAK_BAUD_50K,
420 Baudrate::Baud47K => peak_can::PEAK_BAUD_47K,
421 Baudrate::Baud33K => peak_can::PEAK_BAUD_33K,
422 Baudrate::Baud20K => peak_can::PEAK_BAUD_20K,
423 Baudrate::Baud10K => peak_can::PEAK_BAUD_10K,
424 Baudrate::Baud5K => peak_can::PEAK_BAUD_5K,
425 } as u16;
426 ret
427 }
428}
429
430pub struct TimingBoundaries {
452 pub prescaler_min: u16,
453 pub prescaler_max: u16,
454 pub sjw_min: u8,
455 pub sjw_max: u8,
456 pub tseg1_min: u8,
457 pub tseg1_max: u8,
458 pub tseg2_min: u8,
459 pub tseg2_max: u8,
460}
461
462pub struct FdTimingBoundaries {
496 pub nom_prescaler_min: u16,
497 pub nom_prescaler_max: u16,
498 pub nom_sjw_min: u8,
499 pub nom_sjw_max: u8,
500 pub nom_tseg1_min: u16,
501 pub nom_tseg1_max: u16,
502 pub nom_tseg2_min: u8,
503 pub nom_tseg2_max: u8,
504 pub data_prescaler_min: u16,
505 pub data_prescaler_max: u16,
506 pub data_sjw_min: u8,
507 pub data_sjw_max: u8,
508 pub data_tseg1_min: u8,
509 pub data_tseg1_max: u8,
510 pub data_tseg2_min: u8,
511 pub data_tseg2_max: u8,
512}
513
514pub const CAN_TIMING_BOUNDARIES: TimingBoundaries = TimingBoundaries {
532 prescaler_min: 1,
533 prescaler_max: 64,
534 sjw_min: 1,
535 sjw_max: 4,
536 tseg1_min: 1,
537 tseg1_max: 16,
538 tseg2_min: 1,
539 tseg2_max: 8,
540};
541
542pub const CANFD_TIMING_BOUNDARIES: FdTimingBoundaries = FdTimingBoundaries {
567 nom_prescaler_min: 1,
568 nom_prescaler_max: 1024,
569 nom_sjw_min: 1,
570 nom_sjw_max: 128,
571 nom_tseg1_min: 1,
572 nom_tseg1_max: 256,
573 nom_tseg2_min: 1,
574 nom_tseg2_max: 128,
575 data_prescaler_min: 1,
576 data_prescaler_max: 1024,
577 data_sjw_min: 1,
578 data_sjw_max: 16,
579 data_tseg1_min: 1,
580 data_tseg1_max: 32,
581 data_tseg2_min: 1,
582 data_tseg2_max: 16,
583};
584
585pub struct CanBitTiming {
586 pub prescaler: u16,
587 pub sjw: u8,
588 pub tseg1: u8,
589 pub tseg2: u8,
590}
591
592impl CanBitTiming {
593 pub fn new(prescaler: u16, sjw: u8, tseg1: u8, tseg2: u8) -> Result<Self, Box<dyn std::error::Error>> {
594 let timing = CanBitTiming {
595 prescaler,
596 sjw,
597 tseg1,
598 tseg2,
599 };
600
601 if Self::validate(&timing) {
602 Ok(timing)
603 } else {
604 Err("Timing parameters are out of bounds".into())
605 }
606 }
607
608 fn validate(timing: &CanBitTiming) -> bool {
609 if timing.prescaler < CAN_TIMING_BOUNDARIES.prescaler_min
610 || timing.prescaler > CAN_TIMING_BOUNDARIES.prescaler_max
611 {
612 return false;
613 }
614 if timing.sjw < CAN_TIMING_BOUNDARIES.sjw_min
615 || timing.sjw > CAN_TIMING_BOUNDARIES.sjw_max
616 {
617 return false;
618 }
619 if timing.tseg1 < CAN_TIMING_BOUNDARIES.tseg1_min
620 || timing.tseg1 > CAN_TIMING_BOUNDARIES.tseg1_max
621 {
622 return false;
623 }
624 if timing.tseg2 < CAN_TIMING_BOUNDARIES.tseg2_min
625 || timing.tseg2 > CAN_TIMING_BOUNDARIES.tseg2_max
626 {
627 return false;
628 }
629 true
630 }
631}
632
633pub struct CanFdBitTiming {
634 pub nom_prescaler: u16,
635 pub nom_sjw: u8,
636 pub nom_tseg1: u16,
637 pub nom_tseg2: u8,
638 pub data_prescaler: u16,
639 pub data_sjw: u8,
640 pub data_tseg1: u8,
641 pub data_tseg2: u8,
642}
643
644impl CanFdBitTiming {
645 pub fn new(nom_prescaler: u16, nom_sjw: u8, nom_tseg1: u16, nom_tseg2: u8, data_prescaler: u16, data_sjw: u8, data_tseg1: u8, data_tseg2: u8) -> Result<Self, Box<dyn std::error::Error>> {
646 let timing = CanFdBitTiming {
647 nom_prescaler,
648 nom_sjw,
649 nom_tseg1,
650 nom_tseg2,
651 data_prescaler,
652 data_sjw,
653 data_tseg1,
654 data_tseg2,
655 };
656
657 if Self::validate(&timing) {
658 Ok(timing)
659 } else {
660 Err("Timing parameters are out of bounds".into())
661 }
662 }
663
664 fn validate(timing: &CanFdBitTiming) -> bool {
665 if timing.nom_prescaler < CANFD_TIMING_BOUNDARIES.nom_prescaler_min
666 || timing.nom_prescaler > CANFD_TIMING_BOUNDARIES.nom_prescaler_max
667 {
668 return false;
669 }
670 if timing.nom_sjw < CANFD_TIMING_BOUNDARIES.nom_sjw_min
671 || timing.nom_sjw > CANFD_TIMING_BOUNDARIES.nom_sjw_max
672 {
673 return false;
674 }
675 if timing.nom_tseg1 < CANFD_TIMING_BOUNDARIES.nom_tseg1_min
676 || timing.nom_tseg1 > CANFD_TIMING_BOUNDARIES.nom_tseg1_max
677 {
678 return false;
679 }
680 if timing.nom_tseg2 < CANFD_TIMING_BOUNDARIES.nom_tseg2_min
681 || timing.nom_tseg2 > CANFD_TIMING_BOUNDARIES.nom_tseg2_max
682 {
683 return false;
684 }
685 if timing.data_prescaler < CANFD_TIMING_BOUNDARIES.data_prescaler_min
686 || timing.data_prescaler > CANFD_TIMING_BOUNDARIES.data_prescaler_max
687 {
688 return false;
689 }
690 if timing.data_sjw < CANFD_TIMING_BOUNDARIES.data_sjw_min
691 || timing.data_sjw > CANFD_TIMING_BOUNDARIES.data_sjw_max
692 {
693 return false;
694 }
695 if timing.data_tseg1 < CANFD_TIMING_BOUNDARIES.data_tseg1_min
696 || timing.data_tseg1 > CANFD_TIMING_BOUNDARIES.data_tseg1_max
697 {
698 return false;
699 }
700 if timing.data_tseg2 < CANFD_TIMING_BOUNDARIES.data_tseg2_min
701 || timing.data_tseg2 > CANFD_TIMING_BOUNDARIES.data_tseg2_max
702 {
703 return false;
704 }
705 true
706 }
707}
708
709impl<T: HasRecvCan + Socket> RecvCan for T {
712 fn recv(&self) -> Result<(CanFrame, Timestamp), CanError> {
713 let mut frame = CanFrame::default();
714 let mut timestamp = Timestamp::default();
715
716 let error_code = unsafe {
717 peak_lib()?.CAN_Read(
718 self.handle(),
719 &mut frame.frame as *mut peak_can::TPEAKMsg,
720 &mut timestamp.timestamp as *mut peak_can::TPEAKTimestamp,
721 )
722 };
723
724 match CanOkError::try_from(error_code) {
725 Ok(CanOkError::Ok) => Ok((frame, timestamp)),
726 Ok(CanOkError::Err(err)) => Err(err),
727 Err(_) => Err(CanError::Unknown),
728 }
729 }
730
731 fn recv_frame(&self) -> Result<CanFrame, CanError> {
732 let mut frame = CanFrame::default();
733
734 let error_code = unsafe {
735 peak_lib()?.CAN_Read(
736 self.handle(),
737 &mut frame.frame as *mut peak_can::TPEAKMsg,
738 0 as *mut peak_can::TPEAKTimestamp,
739 )
740 };
741
742 match CanOkError::try_from(error_code) {
743 Ok(CanOkError::Ok) => Ok(frame),
744 Ok(CanOkError::Err(err)) => Err(err),
745 Err(_) => Err(CanError::Unknown),
746 }
747 }
748}
749
750impl<T: HasRecvCanFd + Socket> RecvCanFd for T {
753 fn recv_fd(&self) -> Result<(CanFdFrame, u64), CanError> {
754 let mut frame = CanFdFrame::default();
755 let mut timestamp = 0u64;
756
757 let error_code = unsafe {
758 peak_lib()?.CAN_ReadFD(
759 self.handle(),
760 &mut frame.frame as *mut peak_can::TPEAKMsgFD,
761 &mut timestamp as *mut u64,
762 )
763 };
764
765 match CanOkError::try_from(error_code) {
766 Ok(CanOkError::Ok) => Ok((frame, timestamp)),
767 Ok(CanOkError::Err(err)) => Err(err),
768 Err(_) => Err(CanError::Unknown),
769 }
770 }
771
772 fn recv_fd_frame(&self) -> Result<CanFdFrame, CanError> {
773 let mut frame = CanFdFrame::default();
774
775 let error_code = unsafe {
776 peak_lib()?.CAN_ReadFD(
777 self.handle(),
778 &mut frame.frame as *mut peak_can::TPEAKMsgFD,
779 0 as *mut u64,
780 )
781 };
782
783 match CanOkError::try_from(error_code) {
784 Ok(CanOkError::Ok) => Ok(frame),
785 Ok(CanOkError::Err(err)) => Err(err),
786 Err(_) => Err(CanError::Unknown),
787 }
788 }
789}
790
791impl<T: HasSendCan + Socket> SendCan for T {
794 fn send(&self, frame: CanFrame) -> Result<(), CanError> {
795 let mut frame = frame;
796 let error_code = unsafe {
797 peak_lib()?.CAN_Write(self.handle(), &mut frame.frame as *mut peak_can::TPEAKMsg)
798 };
799
800 match CanOkError::try_from(error_code) {
801 Ok(CanOkError::Ok) => Ok(()),
802 Ok(CanOkError::Err(err)) => Err(err),
803 Err(_) => Err(CanError::Unknown),
804 }
805 }
806}
807
808impl<T: HasSendCanFd + Socket> SendCanFd for T {
811 fn send_fd(&self, frame: CanFdFrame) -> Result<(), CanError> {
812 let mut frame = frame;
813 let error_code = unsafe {
814 peak_lib()?.CAN_WriteFD(self.handle(), &mut frame.frame as *mut peak_can::TPEAKMsgFD)
815 };
816
817 match CanOkError::try_from(error_code) {
818 Ok(CanOkError::Ok) => Ok(()),
819 Ok(CanOkError::Err(err)) => Err(err),
820 Err(_) => Err(CanError::Unknown),
821 }
822 }
823}
824
825#[cfg(test)]
826mod tests {
827 use super::*;
828
829 #[test]
830 fn can_frame_new_001() {
831 let can_frame_1 =
832 CanFrame::new(0x20, MessageType::Standard, &[0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
833
834 let can_frame_2 =
835 CanFrame::new(0x20, MessageType::Standard, &[0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
836
837 assert_eq!(can_frame_1, can_frame_2);
838 }
839
840 #[test]
841 fn can_frame_new_002() {
842 let can_frame_1 =
843 CanFrame::new(0x20, MessageType::Extended, &[0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
844
845 let can_frame_2 =
846 CanFrame::new(0x20, MessageType::Extended, &[0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
847
848 assert_eq!(can_frame_1, can_frame_2);
849 }
850
851 #[test]
852 #[should_panic]
853 fn can_frame_new_003() {
854 let _can_frame_1 =
855 CanFrame::new(0x20, MessageType::Standard, &[0, 1, 2, 3, 4, 5, 6, 7, 8]).unwrap();
856 }
857
858 #[test]
859 #[should_panic]
860 fn can_frame_new_004() {
861 let _can_frame_1 =
862 CanFrame::new(0x20, MessageType::Extended, &[0, 1, 2, 3, 4, 5, 6, 7, 8]).unwrap();
863 }
864
865 #[test]
866 fn can_frame_new_005() {
867 let extended_id = 0x1E_C5_7E_D0;
868 let standard_id = 0x06_D0;
870
871 let can_frame_1 = CanFrame::new(extended_id, MessageType::Standard, &[0, 1, 2]).unwrap();
872 assert_eq!(can_frame_1.can_id(), standard_id);
873
874 let can_frame_2 = CanFrame::new(extended_id, MessageType::Extended, &[0, 1, 2]).unwrap();
875 assert_eq!(can_frame_2.can_id(), extended_id);
876 }
877
878 #[test]
879 fn can_frame_new_006() {
880 let can_frame_1 = CanFrame::new(0x01_23, MessageType::Standard, &[0, 1, 2]).unwrap();
881 assert!(can_frame_1.is_standard_frame());
882
883 let can_frame_2 = CanFrame::new(0x1f_ff_00_ff, MessageType::Extended, &[0, 1, 2]).unwrap();
884 assert!(can_frame_2.is_extended_frame());
885 }
886
887 #[test]
890 fn can_fd_frame_new_001() {
891 let can_frame_1 =
892 CanFdFrame::new(0x20, MessageType::Standard, &(0..64u8).collect::<Vec<_>>(), false, false).unwrap();
893
894 let can_frame_2 =
895 CanFdFrame::new(0x20, MessageType::Standard, &(0..64u8).collect::<Vec<_>>(), false, false).unwrap();
896
897 assert_eq!(can_frame_1, can_frame_2);
898 }
899
900 #[test]
901 fn can_fd_frame_new_002() {
902 let can_frame_1 =
903 CanFdFrame::new(0x20, MessageType::Extended, &(0..64u8).collect::<Vec<_>>(), false, false).unwrap();
904
905 let can_frame_2 =
906 CanFdFrame::new(0x20, MessageType::Extended, &(0..64u8).collect::<Vec<_>>(), false, false).unwrap();
907
908 assert_eq!(can_frame_1, can_frame_2);
909 }
910
911 #[test]
912 #[should_panic]
913 fn can_fd_frame_new_003() {
914 let _can_frame_1 =
915 CanFdFrame::new(0x20, MessageType::Standard, &(0..65u8).collect::<Vec<_>>(), false, false).unwrap();
916 }
917
918 #[test]
919 #[should_panic]
920 fn can_fd_frame_new_004() {
921 let _can_frame_1 =
922 CanFdFrame::new(0x20, MessageType::Extended, &(0..65u8).collect::<Vec<_>>(), false, false).unwrap();
923 }
924
925 #[test]
926 fn can_fd_frame_new_005() {
927 let extended_id = 0x1E_C5_7E_D0;
928 let standard_id = 0x06_D0;
930
931 let can_frame_1 = CanFdFrame::new(
932 extended_id,
933 MessageType::Standard,
934 &(0..64u8).collect::<Vec<_>>(),
935 false,
936 false,
937 )
938 .unwrap();
939 assert_eq!(can_frame_1.can_id(), standard_id);
940
941 let can_frame_2 = CanFdFrame::new(
942 extended_id,
943 MessageType::Extended,
944 &(0..64u8).collect::<Vec<_>>(),
945 false,
946 false,
947 )
948 .unwrap();
949
950 assert_eq!(can_frame_2.can_id(), extended_id);
951 }
952
953 #[test]
956 fn calc_dlc_encoding() {
957 let test_cases = vec![
959 (0, 0), (1, 1), (8, 8), (9, 9), (12, 9), (13, 10), (16, 10), (17, 11), (20, 11), (21, 12), (24, 12), (25, 13), (32, 13), (33, 14), (48, 14), (49, 15), (64, 15), (65, 15), (100, 15), ];
969
970 for (len, expected_dlc) in test_cases {
971 assert_eq!(CanFdFrame::calc_dlc(len), expected_dlc, "Failed for length {}", len);
972 }
973 }
974
975 #[test]
978 fn len_decoding() {
979 let test_cases = vec![
981 (0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8),
982 (12, 12), (16, 16), (20, 20), (24, 24), (32, 32), (48, 48), (64, 64),
983 ];
984
985 for (data_len, expected_len) in test_cases {
986 let data = vec![0u8; data_len];
987 let frame = CanFdFrame::new(0x123, MessageType::Standard, &data, false, false).unwrap();
988 assert_eq!(frame.len(), expected_len, "Failed for data length {}", data_len);
989 }
990 }
991
992 #[test]
993 fn len_calc_dlc_inverse() {
994 let test_cases = vec![
996 (0, 0), (8, 8), (9, 12), (12, 12), (13, 16), (16, 16), (20, 20), (24, 24), (25, 32), (32, 32), (40, 48), (48, 48), (50, 64), (64, 64), ];
1004
1005 for (input_len, expected_frame_len) in test_cases {
1006 let data = vec![0u8; input_len];
1007 let frame = CanFdFrame::new(0x123, MessageType::Standard, &data, false, false).unwrap();
1008 assert_eq!(frame.len(), expected_frame_len, "Failed for input length {}", input_len);
1009 }
1010 }
1011
1012 #[test]
1015 fn can_bit_timing_valid_parameters() {
1016 let test_cases = vec![
1018 (1, 1, 1, 1), (64, 4, 16, 8), (8, 1, 13, 2), (32, 2, 8, 4), ];
1023
1024 for (prescaler, sjw, tseg1, tseg2) in test_cases {
1025 let result = CanBitTiming::new(prescaler, sjw, tseg1, tseg2);
1026 assert!(result.is_ok(), "Should accept valid parameters: prescaler={}, sjw={}, tseg1={}, tseg2={}",
1027 prescaler, sjw, tseg1, tseg2);
1028
1029 let timing = result.unwrap();
1030 assert_eq!(timing.prescaler, prescaler);
1031 assert_eq!(timing.sjw, sjw);
1032 assert_eq!(timing.tseg1, tseg1);
1033 assert_eq!(timing.tseg2, tseg2);
1034 }
1035 }
1036
1037 #[test]
1038 fn can_bit_timing_invalid_prescaler() {
1039 assert!(CanBitTiming::new(0, 1, 1, 1).is_err(), "Should reject prescaler=0");
1041 assert!(CanBitTiming::new(65, 1, 1, 1).is_err(), "Should reject prescaler=65");
1042 assert!(CanBitTiming::new(100, 1, 1, 1).is_err(), "Should reject prescaler=100");
1043 }
1044
1045 #[test]
1046 fn can_bit_timing_invalid_sjw() {
1047 assert!(CanBitTiming::new(8, 0, 1, 1).is_err(), "Should reject sjw=0");
1049 assert!(CanBitTiming::new(8, 5, 1, 1).is_err(), "Should reject sjw=5");
1050 assert!(CanBitTiming::new(8, 10, 1, 1).is_err(), "Should reject sjw=10");
1051 }
1052
1053 #[test]
1054 fn can_bit_timing_invalid_tseg1() {
1055 assert!(CanBitTiming::new(8, 1, 0, 1).is_err(), "Should reject tseg1=0");
1057 assert!(CanBitTiming::new(8, 1, 17, 1).is_err(), "Should reject tseg1=17");
1058 assert!(CanBitTiming::new(8, 1, 20, 1).is_err(), "Should reject tseg1=20");
1059 }
1060
1061 #[test]
1062 fn can_bit_timing_invalid_tseg2() {
1063 assert!(CanBitTiming::new(8, 1, 1, 0).is_err(), "Should reject tseg2=0");
1065 assert!(CanBitTiming::new(8, 1, 1, 9).is_err(), "Should reject tseg2=9");
1066 assert!(CanBitTiming::new(8, 1, 1, 15).is_err(), "Should reject tseg2=15");
1067 }
1068
1069 #[test]
1070 fn can_bit_timing_boundary_values() {
1071 assert!(CanBitTiming::new(1, 1, 1, 1).is_ok(), "Should accept all minimum boundaries");
1073 assert!(CanBitTiming::new(64, 4, 16, 8).is_ok(), "Should accept all maximum boundaries");
1074
1075 assert!(CanBitTiming::new(0, 1, 1, 1).is_err());
1077 assert!(CanBitTiming::new(65, 1, 1, 1).is_err());
1078 assert!(CanBitTiming::new(1, 0, 1, 1).is_err());
1079 assert!(CanBitTiming::new(1, 5, 1, 1).is_err());
1080 assert!(CanBitTiming::new(1, 1, 0, 1).is_err());
1081 assert!(CanBitTiming::new(1, 1, 17, 1).is_err());
1082 assert!(CanBitTiming::new(1, 1, 1, 0).is_err());
1083 assert!(CanBitTiming::new(1, 1, 1, 9).is_err());
1084 }
1085
1086 #[test]
1089 fn can_fd_bit_timing_valid_parameters() {
1090 let test_cases = vec![
1092 (1, 1, 1, 1, 1, 1, 1, 1), (1024, 128, 256, 128, 1024, 16, 32, 16), (2, 10, 127, 32, 2, 5, 25, 8), (500, 50, 100, 50, 100, 8, 16, 8), ];
1098
1099 for (np, ns, nt1, nt2, dp, ds, dt1, dt2) in test_cases {
1100 let result = CanFdBitTiming::new(np, ns, nt1, nt2, dp, ds, dt1, dt2);
1101 assert!(result.is_ok(), "Should accept valid parameters: nom({},{},{},{}), data({},{},{},{})",
1102 np, ns, nt1, nt2, dp, ds, dt1, dt2);
1103
1104 let timing = result.unwrap();
1105 assert_eq!(timing.nom_prescaler, np);
1106 assert_eq!(timing.nom_sjw, ns);
1107 assert_eq!(timing.nom_tseg1, nt1);
1108 assert_eq!(timing.nom_tseg2, nt2);
1109 assert_eq!(timing.data_prescaler, dp);
1110 assert_eq!(timing.data_sjw, ds);
1111 assert_eq!(timing.data_tseg1, dt1);
1112 assert_eq!(timing.data_tseg2, dt2);
1113 }
1114 }
1115
1116 #[test]
1117 fn can_fd_bit_timing_invalid_nom_prescaler() {
1118 assert!(CanFdBitTiming::new(0, 1, 1, 1, 1, 1, 1, 1).is_err(), "Should reject nom_prescaler=0");
1120 assert!(CanFdBitTiming::new(1025, 1, 1, 1, 1, 1, 1, 1).is_err(), "Should reject nom_prescaler=1025");
1121 assert!(CanFdBitTiming::new(2000, 1, 1, 1, 1, 1, 1, 1).is_err(), "Should reject nom_prescaler=2000");
1122 }
1123
1124 #[test]
1125 fn can_fd_bit_timing_invalid_nom_sjw() {
1126 assert!(CanFdBitTiming::new(1, 0, 1, 1, 1, 1, 1, 1).is_err(), "Should reject nom_sjw=0");
1128 assert!(CanFdBitTiming::new(1, 129, 1, 1, 1, 1, 1, 1).is_err(), "Should reject nom_sjw=129");
1129 assert!(CanFdBitTiming::new(1, 200, 1, 1, 1, 1, 1, 1).is_err(), "Should reject nom_sjw=200");
1130 }
1131
1132 #[test]
1133 fn can_fd_bit_timing_invalid_nom_tseg1() {
1134 assert!(CanFdBitTiming::new(1, 1, 0, 1, 1, 1, 1, 1).is_err(), "Should reject nom_tseg1=0");
1136 assert!(CanFdBitTiming::new(1, 1, 257, 1, 1, 1, 1, 1).is_err(), "Should reject nom_tseg1=257");
1137 assert!(CanFdBitTiming::new(1, 1, 300, 1, 1, 1, 1, 1).is_err(), "Should reject nom_tseg1=300");
1138 }
1139
1140 #[test]
1141 fn can_fd_bit_timing_invalid_nom_tseg2() {
1142 assert!(CanFdBitTiming::new(1, 1, 1, 0, 1, 1, 1, 1).is_err(), "Should reject nom_tseg2=0");
1144 assert!(CanFdBitTiming::new(1, 1, 1, 129, 1, 1, 1, 1).is_err(), "Should reject nom_tseg2=129");
1145 assert!(CanFdBitTiming::new(1, 1, 1, 200, 1, 1, 1, 1).is_err(), "Should reject nom_tseg2=200");
1146 }
1147
1148 #[test]
1149 fn can_fd_bit_timing_invalid_data_prescaler() {
1150 assert!(CanFdBitTiming::new(1, 1, 1, 1, 0, 1, 1, 1).is_err(), "Should reject data_prescaler=0");
1152 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1025, 1, 1, 1).is_err(), "Should reject data_prescaler=1025");
1153 assert!(CanFdBitTiming::new(1, 1, 1, 1, 2000, 1, 1, 1).is_err(), "Should reject data_prescaler=2000");
1154 }
1155
1156 #[test]
1157 fn can_fd_bit_timing_invalid_data_sjw() {
1158 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 0, 1, 1).is_err(), "Should reject data_sjw=0");
1160 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 17, 1, 1).is_err(), "Should reject data_sjw=17");
1161 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 50, 1, 1).is_err(), "Should reject data_sjw=50");
1162 }
1163
1164 #[test]
1165 fn can_fd_bit_timing_invalid_data_tseg1() {
1166 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 0, 1).is_err(), "Should reject data_tseg1=0");
1168 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 33, 1).is_err(), "Should reject data_tseg1=33");
1169 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 50, 1).is_err(), "Should reject data_tseg1=50");
1170 }
1171
1172 #[test]
1173 fn can_fd_bit_timing_invalid_data_tseg2() {
1174 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 1, 0).is_err(), "Should reject data_tseg2=0");
1176 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 1, 17).is_err(), "Should reject data_tseg2=17");
1177 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 1, 50).is_err(), "Should reject data_tseg2=50");
1178 }
1179
1180 #[test]
1181 fn can_fd_bit_timing_boundary_values() {
1182 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 1, 1).is_ok(),
1184 "Should accept all minimum boundaries");
1185 assert!(CanFdBitTiming::new(1024, 128, 256, 128, 1024, 16, 32, 16).is_ok(),
1186 "Should accept all maximum boundaries");
1187
1188 assert!(CanFdBitTiming::new(0, 1, 1, 1, 1, 1, 1, 1).is_err());
1190 assert!(CanFdBitTiming::new(1025, 1, 1, 1, 1, 1, 1, 1).is_err());
1191 assert!(CanFdBitTiming::new(1, 0, 1, 1, 1, 1, 1, 1).is_err());
1192 assert!(CanFdBitTiming::new(1, 129, 1, 1, 1, 1, 1, 1).is_err());
1193 assert!(CanFdBitTiming::new(1, 1, 0, 1, 1, 1, 1, 1).is_err());
1194 assert!(CanFdBitTiming::new(1, 1, 257, 1, 1, 1, 1, 1).is_err());
1195 assert!(CanFdBitTiming::new(1, 1, 1, 0, 1, 1, 1, 1).is_err());
1196 assert!(CanFdBitTiming::new(1, 1, 1, 129, 1, 1, 1, 1).is_err());
1197
1198 assert!(CanFdBitTiming::new(1, 1, 1, 1, 0, 1, 1, 1).is_err());
1200 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1025, 1, 1, 1).is_err());
1201 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 0, 1, 1).is_err());
1202 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 17, 1, 1).is_err());
1203 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 0, 1).is_err());
1204 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 33, 1).is_err());
1205 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 1, 0).is_err());
1206 assert!(CanFdBitTiming::new(1, 1, 1, 1, 1, 1, 1, 17).is_err());
1207 }
1208}