1 | //! Controller Area Network |
2 | |
3 | pub mod nb; |
4 | |
5 | mod id; |
6 | |
7 | pub use self::id::*; |
8 | pub use self::nb::*; |
9 | |
10 | /// A CAN2.0 Frame |
11 | pub trait Frame: Sized { |
12 | /// Creates a new frame. |
13 | /// |
14 | /// This will return `None` if the data slice is too long. |
15 | fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self>; |
16 | |
17 | /// Creates a new remote frame (RTR bit set). |
18 | /// |
19 | /// This will return `None` if the data length code (DLC) is not valid. |
20 | fn new_remote(id: impl Into<Id>, dlc: usize) -> Option<Self>; |
21 | |
22 | /// Returns true if this frame is a extended frame. |
23 | fn is_extended(&self) -> bool; |
24 | |
25 | /// Returns true if this frame is a standard frame. |
26 | fn is_standard(&self) -> bool { |
27 | !self.is_extended() |
28 | } |
29 | |
30 | /// Returns true if this frame is a remote frame. |
31 | fn is_remote_frame(&self) -> bool; |
32 | |
33 | /// Returns true if this frame is a data frame. |
34 | fn is_data_frame(&self) -> bool { |
35 | !self.is_remote_frame() |
36 | } |
37 | |
38 | /// Returns the frame identifier. |
39 | fn id(&self) -> Id; |
40 | |
41 | /// Returns the data length code (DLC) which is in the range 0..8. |
42 | /// |
43 | /// For data frames the DLC value always matches the length of the data. |
44 | /// Remote frames do not carry any data, yet the DLC can be greater than 0. |
45 | fn dlc(&self) -> usize; |
46 | |
47 | /// Returns the frame data (0..8 bytes in length). |
48 | fn data(&self) -> &[u8]; |
49 | } |
50 | |
51 | /// CAN error |
52 | pub trait Error: core::fmt::Debug { |
53 | /// Convert error to a generic CAN error kind |
54 | /// |
55 | /// By using this method, CAN errors freely defined by HAL implementations |
56 | /// can be converted to a set of generic serial errors upon which generic |
57 | /// code can act. |
58 | fn kind(&self) -> ErrorKind; |
59 | } |
60 | |
61 | /// CAN error kind |
62 | /// |
63 | /// This represents a common set of CAN operation errors. HAL implementations are |
64 | /// free to define more specific or additional error types. However, by providing |
65 | /// a mapping to these common CAN errors, generic code can still react to them. |
66 | #[derive (Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
67 | pub enum ErrorKind { |
68 | /// The peripheral receive buffer was overrun. |
69 | Overrun, |
70 | |
71 | // MAC sublayer errors |
72 | /// A bit error is detected at that bit time when the bit value that is |
73 | /// monitored differs from the bit value sent. |
74 | Bit, |
75 | |
76 | /// A stuff error is detected at the bit time of the sixth consecutive |
77 | /// equal bit level in a frame field that shall be coded by the method |
78 | /// of bit stuffing. |
79 | Stuff, |
80 | |
81 | /// Calculated CRC sequence does not equal the received one. |
82 | Crc, |
83 | |
84 | /// A form error shall be detected when a fixed-form bit field contains |
85 | /// one or more illegal bits. |
86 | Form, |
87 | |
88 | /// An ACK error shall be detected by a transmitter whenever it does not |
89 | /// monitor a dominant bit during the ACK slot. |
90 | Acknowledge, |
91 | |
92 | /// A different error occurred. The original error may contain more information. |
93 | Other, |
94 | } |
95 | |
96 | impl Error for ErrorKind { |
97 | fn kind(&self) -> ErrorKind { |
98 | *self |
99 | } |
100 | } |
101 | |
102 | impl core::fmt::Display for ErrorKind { |
103 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
104 | match self { |
105 | ErrorKind::Overrun => write!(f, "The peripheral receive buffer was overrun" ), |
106 | ErrorKind::Bit => write!( |
107 | f, |
108 | "Bit value that is monitored differs from the bit value sent" |
109 | ), |
110 | ErrorKind::Stuff => write!(f, "Sixth consecutive equal bits detected" ), |
111 | ErrorKind::Crc => write!(f, "Calculated CRC sequence does not equal the received one" ), |
112 | ErrorKind::Form => write!( |
113 | f, |
114 | "A fixed-form bit field contains one or more illegal bits" |
115 | ), |
116 | ErrorKind::Acknowledge => write!(f, "Transmitted frame was not acknowledged" ), |
117 | ErrorKind::Other => write!( |
118 | f, |
119 | "A different error occurred. The original error may contain more information" |
120 | ), |
121 | } |
122 | } |
123 | } |
124 | |