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