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}