embedded_hal_can/
lib.rs

1//! Controller Area Network
2#![no_std]
3
4use nb;
5
6/// A type that can either be `BaseId` or `ExtendedId`
7pub trait Id {
8    /// The (11-bit) BaseId variant.
9    type BaseId;
10
11    /// The (29-bit) ExtendedId variant.
12    type ExtendedId;
13
14    /// Returns `Some(base_id)` if this Can-ID is 11-bit.
15    /// Returns `None` if this Can-ID is 29-bit.
16    fn base_id(&self) -> Option<Self::BaseId>;
17
18    /// Returns `Some(extended_id)` if this Can-ID is 29-bit.
19    /// Returns `None` if this Can-ID is 11-bit.
20    fn extended_id(&self) -> Option<Self::ExtendedId>;
21}
22
23/// A type that will either accept or filter a `Frame`.
24/// The filtering is done solely on the `ID` of the `Frame`.
25pub trait Filter {
26    /// The Id type this filter works on
27    type Id: Id;
28
29    /// Constructs a filter that only accepts `Frame`s with the provided identifier.
30    fn from_id(id: Self::Id) -> Self;
31
32    /// Constructs a filter that will accept any `Frame`.
33    fn accept_all() -> Self;
34
35    /// Create a `Filter` from a filter/mask combination.
36    ///
37    /// - Bit 0..11 is used when matching against base id
38    /// - Bit 0..29 is used when matching against extended_id
39    /// - Bit 29 matches the extended frame flag (can be used for only matching against base/extended ids)
40    /// - Bit 30..32 *must* be `0`
41    ///
42    /// *Note: When filtering base id any rule put on `bit_pos >= 11` will (for implementers: must) be ignored*
43    ///
44    /// ### Panic
45    /// (for implementers: must) panic if mask have bits equal to `1` for bit_position `>= 30`.
46    fn from_mask(mask: u32, filter: u32) -> Self;
47}
48
49
50/// A Can Frame
51pub trait Frame {
52    /// The Id type of this Frame
53    type Id: Id;
54
55    /// Returns true if this `Frame` is a remote frame
56    fn is_remote_frame(&self) -> bool;
57
58    /// Returns true if this `Frame` is a data frame
59    fn is_data_frame(&self) -> bool;
60
61    /// Returns true if this `Frame` is a extended id frame
62    fn is_base_id_frame(&self) -> bool {
63        self.id().base_id().is_some()
64    }
65
66    /// Returns true if this `Frame` is a extended id frame
67    fn is_extended_id_frame(&self) -> bool {
68        self.id().extended_id().is_some()
69    }
70
71    /// Returns the Can-ID
72    fn id(&self) -> Self::Id;
73
74    /// Returns `Some(Data)` if data frame.
75    /// Returns `None` if remote frame.
76    fn data(&self) -> Option<&[u8]>;
77}
78
79/// A Can-FD Frame
80///
81/// A "ordinary" Can-Frame must also be representable by this type.
82#[cfg(feature = "unproven")]
83pub trait FdFrame {
84    /// The Id type of this Frame
85    type Id: Id;
86
87    /// Returns true if this frame would/has be(en) transmitted as a Can-Fd frame.
88    /// Returns false if this frame would/has be(en) transmitted as a "ordinary" Can frame.
89    fn is_fd_frame(&self) -> bool;
90
91    /// Returns true if this `Frame` is a remote frame
92    fn is_remote_frame(&self) -> bool;
93
94    /// Returns true if this `Frame` is a data frame
95    fn is_data_frame(&self) -> bool;
96
97    /// Returns true if this `Frame` is a extended id frame
98    fn is_base_id_frame(&self) -> bool {
99        self.id().base_id().is_some()
100    }
101
102    /// Returns true if this `Frame` is a extended id frame
103    fn is_extended_id_frame(&self) -> bool {
104        self.id().extended_id().is_some()
105    }
106
107    /// Returns the Can-ID
108    fn id(&self) -> Self::Id;
109
110    /// Returns `Some(Data)` if data frame.
111    /// Returns `None` if remote frame.
112    fn data(&self) -> Option<&[u8]>;
113}
114
115
116/// A CAN interface
117///
118/// May be a `Transmitter`, `Receiver` or both.
119pub trait Interface {
120    /// The Id type that works with this `Interface`
121    type Id: Id;
122
123    /// The Can Frame this Interface operates on
124    type Frame: Frame<Id = Self::Id>;
125
126    /// The Interface Error type
127    type Error;
128
129    /// The Filter type used in this `Interface`
130    type Filter: Filter<Id = Self::Id>;
131}
132
133/// A CAN interface that is able to transmit frames.
134pub trait Transmitter: Interface {
135    /// Put a `Frame` in the transmit buffer (or a free mailbox).
136    ///
137    /// If the buffer is full, this function will try to replace a lower priority `Frame`
138    /// and return it. This is to avoid the priority inversion problem.
139    fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error>;
140}
141
142/// A CAN interface that is able to receive frames.
143pub trait Receiver: Interface {
144    /// Return the available `Frame` with the highest priority (lowest ID).
145    ///
146    /// NOTE: Can-FD Frames will not be received using this function.
147    fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error>;
148
149    /// Set the can controller in a mode where it only accept frames matching the given filter.
150    ///
151    /// If there exists several receive buffers, this filter will be applied for all of them.
152    ///
153    /// *Note: Even after this method has been called, there may still be `Frame`s in the receive buffer with
154    /// identifiers that would not been received with this `Filter`.*
155    fn set_filter(&mut self, filter: Self::Filter);
156
157    /// Set the can controller in a mode where it will accept all frames.
158    fn clear_filter(&mut self);
159}
160
161///// A CAN interface also supporting Can-FD
162/////
163///// May be a `FdTransmitter`, `FdReceiver` or both.
164//pub trait FdInterface: Interface {
165//    /// The Can Frame this Interface operates on
166//    type FdFrame: FdFrame;
167//}
168//
169///// A CAN-FD interface that is able to transmit frames.
170//pub trait FdTransmitter: FdInterface + Receiver {
171//    /// Put a `FdFrame` in the transmit buffer (or a free mailbox).
172//    ///
173//    /// If the buffer is full, this function will try to replace a lower priority `FdFrame`
174//    /// and return it. This is to avoid the priority inversion problem.
175//    fn transmit(&mut self, frame: &Self::FdFrame) -> nb::Result<Option<Self::FdFrame>, Self::Error>;
176//}
177//
178///// A CAN-FD interface that is able to receive frames.
179//pub trait FdReceiver: FdInterface + Transmitter {
180//    /// Read the available `FdFrame` with the highest priority (lowest ID).
181//    fn receive(&mut self) -> nb::Result<Self::FdFrame, Self::Error>;
182//}