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//}