embassy_stm32/can/fd/
filter.rs

1//! Definition of Filter structs for FDCAN Module
2// Note: This file is copied and modified from fdcan crate by Richard Meadows
3
4use embedded_can::{ExtendedId, StandardId};
5
6use crate::can::fd::message_ram;
7pub use crate::can::fd::message_ram::{EXTENDED_FILTER_MAX, STANDARD_FILTER_MAX};
8
9/// A Standard Filter
10pub type StandardFilter = Filter<StandardId, u16>;
11/// An Extended Filter
12pub type ExtendedFilter = Filter<ExtendedId, u32>;
13
14impl Default for StandardFilter {
15    fn default() -> Self {
16        StandardFilter::disable()
17    }
18}
19impl Default for ExtendedFilter {
20    fn default() -> Self {
21        ExtendedFilter::disable()
22    }
23}
24
25impl StandardFilter {
26    /// Accept all messages in FIFO 0
27    pub fn accept_all_into_fifo0() -> StandardFilter {
28        StandardFilter {
29            filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
30            action: Action::StoreInFifo0,
31        }
32    }
33
34    /// Accept all messages in FIFO 1
35    pub fn accept_all_into_fifo1() -> StandardFilter {
36        StandardFilter {
37            filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
38            action: Action::StoreInFifo1,
39        }
40    }
41
42    /// Reject all messages
43    pub fn reject_all() -> StandardFilter {
44        StandardFilter {
45            filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
46            action: Action::Reject,
47        }
48    }
49
50    /// Disable the filter
51    pub fn disable() -> StandardFilter {
52        StandardFilter {
53            filter: FilterType::Disabled,
54            action: Action::Disable,
55        }
56    }
57}
58
59impl ExtendedFilter {
60    /// Accept all messages in FIFO 0
61    pub fn accept_all_into_fifo0() -> ExtendedFilter {
62        ExtendedFilter {
63            filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
64            action: Action::StoreInFifo0,
65        }
66    }
67
68    /// Accept all messages in FIFO 1
69    pub fn accept_all_into_fifo1() -> ExtendedFilter {
70        ExtendedFilter {
71            filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
72            action: Action::StoreInFifo1,
73        }
74    }
75
76    /// Reject all messages
77    pub fn reject_all() -> ExtendedFilter {
78        ExtendedFilter {
79            filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
80            action: Action::Reject,
81        }
82    }
83
84    /// Disable the filter
85    pub fn disable() -> ExtendedFilter {
86        ExtendedFilter {
87            filter: FilterType::Disabled,
88            action: Action::Disable,
89        }
90    }
91}
92
93/// Filter Type
94#[derive(Clone, Copy, Debug)]
95pub enum FilterType<ID, UNIT>
96where
97    ID: Copy + Clone + core::fmt::Debug,
98    UNIT: Copy + Clone + core::fmt::Debug,
99{
100    /// Match with a range between two messages
101    Range {
102        /// First Id of the range
103        from: ID,
104        /// Last Id of the range
105        to: ID,
106    },
107    /// Match with a bitmask
108    BitMask {
109        /// Filter of the bitmask
110        filter: UNIT,
111        /// Mask of the bitmask
112        mask: UNIT,
113    },
114    /// Match with a single ID
115    DedicatedSingle(ID),
116    /// Match with one of two ID's
117    DedicatedDual(ID, ID),
118    /// Filter is disabled
119    Disabled,
120}
121impl<ID, UNIT> From<FilterType<ID, UNIT>> for message_ram::enums::FilterType
122where
123    ID: Copy + Clone + core::fmt::Debug,
124    UNIT: Copy + Clone + core::fmt::Debug,
125{
126    fn from(f: FilterType<ID, UNIT>) -> Self {
127        match f {
128            FilterType::Range { to: _, from: _ } => Self::RangeFilter,
129            FilterType::BitMask { filter: _, mask: _ } => Self::ClassicFilter,
130            FilterType::DedicatedSingle(_) => Self::DualIdFilter,
131            FilterType::DedicatedDual(_, _) => Self::DualIdFilter,
132            FilterType::Disabled => Self::FilterDisabled,
133        }
134    }
135}
136
137/// Filter Action
138#[derive(Clone, Copy, Debug)]
139pub enum Action {
140    /// No Action
141    Disable = 0b000,
142    /// Store an matching message in FIFO 0
143    StoreInFifo0 = 0b001,
144    /// Store an matching message in FIFO 1
145    StoreInFifo1 = 0b010,
146    /// Reject an matching message
147    Reject = 0b011,
148    /// Flag a matching message (But not store?!?)
149    FlagHighPrio = 0b100,
150    /// Flag a matching message as a High Priority message and store it in FIFO 0
151    FlagHighPrioAndStoreInFifo0 = 0b101,
152    /// Flag a matching message as a High Priority message and store it in FIFO 1
153    FlagHighPrioAndStoreInFifo1 = 0b110,
154}
155impl From<Action> for message_ram::enums::FilterElementConfig {
156    fn from(a: Action) -> Self {
157        match a {
158            Action::Disable => Self::DisableFilterElement,
159            Action::StoreInFifo0 => Self::StoreInFifo0,
160            Action::StoreInFifo1 => Self::StoreInFifo1,
161            Action::Reject => Self::Reject,
162            Action::FlagHighPrio => Self::SetPriority,
163            Action::FlagHighPrioAndStoreInFifo0 => Self::SetPriorityAndStoreInFifo0,
164            Action::FlagHighPrioAndStoreInFifo1 => Self::SetPriorityAndStoreInFifo1,
165        }
166    }
167}
168
169/// Filter
170#[derive(Clone, Copy, Debug)]
171pub struct Filter<ID, UNIT>
172where
173    ID: Copy + Clone + core::fmt::Debug,
174    UNIT: Copy + Clone + core::fmt::Debug,
175{
176    /// How to match an incoming message
177    pub filter: FilterType<ID, UNIT>,
178    /// What to do with a matching message
179    pub action: Action,
180}
181
182/// Standard Filter Slot
183#[derive(Debug, Copy, Clone, Eq, PartialEq)]
184pub enum StandardFilterSlot {
185    /// 0
186    _0 = 0,
187    /// 1
188    _1 = 1,
189    /// 2
190    _2 = 2,
191    /// 3
192    _3 = 3,
193    /// 4
194    _4 = 4,
195    /// 5
196    _5 = 5,
197    /// 6
198    _6 = 6,
199    /// 7
200    _7 = 7,
201    /// 8
202    _8 = 8,
203    /// 9
204    _9 = 9,
205    /// 10
206    _10 = 10,
207    /// 11
208    _11 = 11,
209    /// 12
210    _12 = 12,
211    /// 13
212    _13 = 13,
213    /// 14
214    _14 = 14,
215    /// 15
216    _15 = 15,
217    /// 16
218    _16 = 16,
219    /// 17
220    _17 = 17,
221    /// 18
222    _18 = 18,
223    /// 19
224    _19 = 19,
225    /// 20
226    _20 = 20,
227    /// 21
228    _21 = 21,
229    /// 22
230    _22 = 22,
231    /// 23
232    _23 = 23,
233    /// 24
234    _24 = 24,
235    /// 25
236    _25 = 25,
237    /// 26
238    _26 = 26,
239    /// 27
240    _27 = 27,
241}
242impl From<u8> for StandardFilterSlot {
243    fn from(u: u8) -> Self {
244        match u {
245            0 => StandardFilterSlot::_0,
246            1 => StandardFilterSlot::_1,
247            2 => StandardFilterSlot::_2,
248            3 => StandardFilterSlot::_3,
249            4 => StandardFilterSlot::_4,
250            5 => StandardFilterSlot::_5,
251            6 => StandardFilterSlot::_6,
252            7 => StandardFilterSlot::_7,
253            8 => StandardFilterSlot::_8,
254            9 => StandardFilterSlot::_9,
255            10 => StandardFilterSlot::_10,
256            11 => StandardFilterSlot::_11,
257            12 => StandardFilterSlot::_12,
258            13 => StandardFilterSlot::_13,
259            14 => StandardFilterSlot::_14,
260            15 => StandardFilterSlot::_15,
261            16 => StandardFilterSlot::_16,
262            17 => StandardFilterSlot::_17,
263            18 => StandardFilterSlot::_18,
264            19 => StandardFilterSlot::_19,
265            20 => StandardFilterSlot::_20,
266            21 => StandardFilterSlot::_21,
267            22 => StandardFilterSlot::_22,
268            23 => StandardFilterSlot::_23,
269            24 => StandardFilterSlot::_24,
270            25 => StandardFilterSlot::_25,
271            26 => StandardFilterSlot::_26,
272            27 => StandardFilterSlot::_27,
273            _ => panic!("Standard Filter Slot Too High!"),
274        }
275    }
276}
277
278/// Extended Filter Slot
279#[derive(Debug, Copy, Clone, Eq, PartialEq)]
280pub enum ExtendedFilterSlot {
281    /// 0
282    _0 = 0,
283    /// 1
284    _1 = 1,
285    /// 2
286    _2 = 2,
287    /// 3
288    _3 = 3,
289    /// 4
290    _4 = 4,
291    /// 5
292    _5 = 5,
293    /// 6
294    _6 = 6,
295    /// 7
296    _7 = 7,
297}
298impl From<u8> for ExtendedFilterSlot {
299    fn from(u: u8) -> Self {
300        match u {
301            0 => ExtendedFilterSlot::_0,
302            1 => ExtendedFilterSlot::_1,
303            2 => ExtendedFilterSlot::_2,
304            3 => ExtendedFilterSlot::_3,
305            4 => ExtendedFilterSlot::_4,
306            5 => ExtendedFilterSlot::_5,
307            6 => ExtendedFilterSlot::_6,
308            7 => ExtendedFilterSlot::_7,
309            _ => panic!("Extended Filter Slot Too High!"), // Should be unreachable
310        }
311    }
312}
313
314/// Enum over both Standard and Extended Filter ID's
315#[derive(Debug, Copy, Clone, Eq, PartialEq)]
316pub enum FilterId {
317    /// Standard Filter Slots
318    Standard(StandardFilterSlot),
319    /// Extended Filter Slots
320    Extended(ExtendedFilterSlot),
321}
322
323pub(crate) trait ActivateFilter<ID, UNIT>
324where
325    ID: Copy + Clone + core::fmt::Debug,
326    UNIT: Copy + Clone + core::fmt::Debug,
327{
328    fn activate(&mut self, f: Filter<ID, UNIT>);
329    // fn read(&self) -> Filter<ID, UNIT>;
330}
331
332impl ActivateFilter<StandardId, u16> for message_ram::StandardFilter {
333    fn activate(&mut self, f: Filter<StandardId, u16>) {
334        let sft = f.filter.into();
335
336        let (sfid1, sfid2) = match f.filter {
337            FilterType::Range { to, from } => (to.as_raw(), from.as_raw()),
338            FilterType::DedicatedSingle(id) => (id.as_raw(), id.as_raw()),
339            FilterType::DedicatedDual(id1, id2) => (id1.as_raw(), id2.as_raw()),
340            FilterType::BitMask { filter, mask } => (filter, mask),
341            FilterType::Disabled => (0x0, 0x0),
342        };
343        let sfec = f.action.into();
344        self.write(|w| {
345            unsafe { w.sfid1().bits(sfid1).sfid2().bits(sfid2) }
346                .sft()
347                .set_filter_type(sft)
348                .sfec()
349                .set_filter_element_config(sfec)
350        });
351    }
352    // fn read(&self) -> Filter<StandardId, u16> {
353    //     todo!()
354    // }
355}
356impl ActivateFilter<ExtendedId, u32> for message_ram::ExtendedFilter {
357    fn activate(&mut self, f: Filter<ExtendedId, u32>) {
358        let eft = f.filter.into();
359
360        let (efid1, efid2) = match f.filter {
361            FilterType::Range { to, from } => (to.as_raw(), from.as_raw()),
362            FilterType::DedicatedSingle(id) => (id.as_raw(), id.as_raw()),
363            FilterType::DedicatedDual(id1, id2) => (id1.as_raw(), id2.as_raw()),
364            FilterType::BitMask { filter, mask } => (filter, mask),
365            FilterType::Disabled => (0x0, 0x0),
366        };
367        let efec = f.action.into();
368        self.write(|w| {
369            unsafe { w.efid1().bits(efid1).efid2().bits(efid2) }
370                .eft()
371                .set_filter_type(eft)
372                .efec()
373                .set_filter_element_config(efec)
374        });
375    }
376    // fn read(&self) -> Filter<ExtendedId, u32> {
377    //     todo!()
378    // }
379}