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