use embedded_can::{ExtendedId, StandardId};
use crate::can::fd::message_ram;
pub use crate::can::fd::message_ram::{EXTENDED_FILTER_MAX, STANDARD_FILTER_MAX};
pub type StandardFilter = Filter<StandardId, u16>;
pub type ExtendedFilter = Filter<ExtendedId, u32>;
impl Default for StandardFilter {
fn default() -> Self {
StandardFilter::disable()
}
}
impl Default for ExtendedFilter {
fn default() -> Self {
ExtendedFilter::disable()
}
}
impl StandardFilter {
pub fn accept_all_into_fifo0() -> StandardFilter {
StandardFilter {
filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
action: Action::StoreInFifo0,
}
}
pub fn accept_all_into_fifo1() -> StandardFilter {
StandardFilter {
filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
action: Action::StoreInFifo1,
}
}
pub fn reject_all() -> StandardFilter {
StandardFilter {
filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
action: Action::Reject,
}
}
pub fn disable() -> StandardFilter {
StandardFilter {
filter: FilterType::Disabled,
action: Action::Disable,
}
}
}
impl ExtendedFilter {
pub fn accept_all_into_fifo0() -> ExtendedFilter {
ExtendedFilter {
filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
action: Action::StoreInFifo0,
}
}
pub fn accept_all_into_fifo1() -> ExtendedFilter {
ExtendedFilter {
filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
action: Action::StoreInFifo1,
}
}
pub fn reject_all() -> ExtendedFilter {
ExtendedFilter {
filter: FilterType::BitMask { filter: 0x0, mask: 0x0 },
action: Action::Reject,
}
}
pub fn disable() -> ExtendedFilter {
ExtendedFilter {
filter: FilterType::Disabled,
action: Action::Disable,
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum FilterType<ID, UNIT>
where
ID: Copy + Clone + core::fmt::Debug,
UNIT: Copy + Clone + core::fmt::Debug,
{
Range {
from: ID,
to: ID,
},
BitMask {
filter: UNIT,
mask: UNIT,
},
DedicatedSingle(ID),
DedicatedDual(ID, ID),
Disabled,
}
impl<ID, UNIT> From<FilterType<ID, UNIT>> for message_ram::enums::FilterType
where
ID: Copy + Clone + core::fmt::Debug,
UNIT: Copy + Clone + core::fmt::Debug,
{
fn from(f: FilterType<ID, UNIT>) -> Self {
match f {
FilterType::Range { to: _, from: _ } => Self::RangeFilter,
FilterType::BitMask { filter: _, mask: _ } => Self::ClassicFilter,
FilterType::DedicatedSingle(_) => Self::DualIdFilter,
FilterType::DedicatedDual(_, _) => Self::DualIdFilter,
FilterType::Disabled => Self::FilterDisabled,
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum Action {
Disable = 0b000,
StoreInFifo0 = 0b001,
StoreInFifo1 = 0b010,
Reject = 0b011,
FlagHighPrio = 0b100,
FlagHighPrioAndStoreInFifo0 = 0b101,
FlagHighPrioAndStoreInFifo1 = 0b110,
}
impl From<Action> for message_ram::enums::FilterElementConfig {
fn from(a: Action) -> Self {
match a {
Action::Disable => Self::DisableFilterElement,
Action::StoreInFifo0 => Self::StoreInFifo0,
Action::StoreInFifo1 => Self::StoreInFifo1,
Action::Reject => Self::Reject,
Action::FlagHighPrio => Self::SetPriority,
Action::FlagHighPrioAndStoreInFifo0 => Self::SetPriorityAndStoreInFifo0,
Action::FlagHighPrioAndStoreInFifo1 => Self::SetPriorityAndStoreInFifo1,
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct Filter<ID, UNIT>
where
ID: Copy + Clone + core::fmt::Debug,
UNIT: Copy + Clone + core::fmt::Debug,
{
pub filter: FilterType<ID, UNIT>,
pub action: Action,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum StandardFilterSlot {
_0 = 0,
_1 = 1,
_2 = 2,
_3 = 3,
_4 = 4,
_5 = 5,
_6 = 6,
_7 = 7,
_8 = 8,
_9 = 9,
_10 = 10,
_11 = 11,
_12 = 12,
_13 = 13,
_14 = 14,
_15 = 15,
_16 = 16,
_17 = 17,
_18 = 18,
_19 = 19,
_20 = 20,
_21 = 21,
_22 = 22,
_23 = 23,
_24 = 24,
_25 = 25,
_26 = 26,
_27 = 27,
}
impl From<u8> for StandardFilterSlot {
fn from(u: u8) -> Self {
match u {
0 => StandardFilterSlot::_0,
1 => StandardFilterSlot::_1,
2 => StandardFilterSlot::_2,
3 => StandardFilterSlot::_3,
4 => StandardFilterSlot::_4,
5 => StandardFilterSlot::_5,
6 => StandardFilterSlot::_6,
7 => StandardFilterSlot::_7,
8 => StandardFilterSlot::_8,
9 => StandardFilterSlot::_9,
10 => StandardFilterSlot::_10,
11 => StandardFilterSlot::_11,
12 => StandardFilterSlot::_12,
13 => StandardFilterSlot::_13,
14 => StandardFilterSlot::_14,
15 => StandardFilterSlot::_15,
16 => StandardFilterSlot::_16,
17 => StandardFilterSlot::_17,
18 => StandardFilterSlot::_18,
19 => StandardFilterSlot::_19,
20 => StandardFilterSlot::_20,
21 => StandardFilterSlot::_21,
22 => StandardFilterSlot::_22,
23 => StandardFilterSlot::_23,
24 => StandardFilterSlot::_24,
25 => StandardFilterSlot::_25,
26 => StandardFilterSlot::_26,
27 => StandardFilterSlot::_27,
_ => panic!("Standard Filter Slot Too High!"),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ExtendedFilterSlot {
_0 = 0,
_1 = 1,
_2 = 2,
_3 = 3,
_4 = 4,
_5 = 5,
_6 = 6,
_7 = 7,
}
impl From<u8> for ExtendedFilterSlot {
fn from(u: u8) -> Self {
match u {
0 => ExtendedFilterSlot::_0,
1 => ExtendedFilterSlot::_1,
2 => ExtendedFilterSlot::_2,
3 => ExtendedFilterSlot::_3,
4 => ExtendedFilterSlot::_4,
5 => ExtendedFilterSlot::_5,
6 => ExtendedFilterSlot::_6,
7 => ExtendedFilterSlot::_7,
_ => panic!("Extended Filter Slot Too High!"), }
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum FilterId {
Standard(StandardFilterSlot),
Extended(ExtendedFilterSlot),
}
pub(crate) trait ActivateFilter<ID, UNIT>
where
ID: Copy + Clone + core::fmt::Debug,
UNIT: Copy + Clone + core::fmt::Debug,
{
fn activate(&mut self, f: Filter<ID, UNIT>);
}
impl ActivateFilter<StandardId, u16> for message_ram::StandardFilter {
fn activate(&mut self, f: Filter<StandardId, u16>) {
let sft = f.filter.into();
let (sfid1, sfid2) = match f.filter {
FilterType::Range { to, from } => (to.as_raw(), from.as_raw()),
FilterType::DedicatedSingle(id) => (id.as_raw(), id.as_raw()),
FilterType::DedicatedDual(id1, id2) => (id1.as_raw(), id2.as_raw()),
FilterType::BitMask { filter, mask } => (filter, mask),
FilterType::Disabled => (0x0, 0x0),
};
let sfec = f.action.into();
self.write(|w| {
unsafe { w.sfid1().bits(sfid1).sfid2().bits(sfid2) }
.sft()
.set_filter_type(sft)
.sfec()
.set_filter_element_config(sfec)
});
}
}
impl ActivateFilter<ExtendedId, u32> for message_ram::ExtendedFilter {
fn activate(&mut self, f: Filter<ExtendedId, u32>) {
let eft = f.filter.into();
let (efid1, efid2) = match f.filter {
FilterType::Range { to, from } => (to.as_raw(), from.as_raw()),
FilterType::DedicatedSingle(id) => (id.as_raw(), id.as_raw()),
FilterType::DedicatedDual(id1, id2) => (id1.as_raw(), id2.as_raw()),
FilterType::BitMask { filter, mask } => (filter, mask),
FilterType::Disabled => (0x0, 0x0),
};
let efec = f.action.into();
self.write(|w| {
unsafe { w.efid1().bits(efid1).efid2().bits(efid2) }
.eft()
.set_filter_type(eft)
.efec()
.set_filter_element_config(efec)
});
}
}