embedded_can/lib.rs
1//! Controller Area Network (CAN) traits
2
3#![warn(missing_docs)]
4#![no_std]
5
6pub mod blocking;
7pub mod nb;
8
9mod id;
10
11pub use id::*;
12
13/// A CAN2.0 Frame
14pub 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
55pub 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
64impl 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]
77pub 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
106impl Error for ErrorKind {
107 fn kind(&self) -> ErrorKind {
108 *self
109 }
110}
111
112impl 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}