-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add register definition for can filter
- Loading branch information
1 parent
2db1958
commit 191efb4
Showing
9 changed files
with
278 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
use embedded_can::StandardId; | ||
|
||
use super::{Bit16Mode, CanFilter, FilterOptions, ListMode, MaskMode}; | ||
|
||
pub struct Bit16IdReg<'a>(&'a mut u16); | ||
|
||
pub struct Bit16MaskReg<'a> { | ||
mask: &'a mut u16, | ||
id: &'a mut u16, | ||
} | ||
|
||
impl Bit16IdReg<'_> { | ||
pub fn set(&mut self, id: StandardId, opts: FilterOptions) { | ||
let bits = (id.as_raw() << 3) | ((opts.rtr_enabled as u16) << 2); | ||
*self.0 &= 0x0000; | ||
*self.0 |= bits; | ||
} | ||
} | ||
|
||
impl Bit16MaskReg<'_> { | ||
pub fn set(&mut self, id: u16, mask: u16, opts: FilterOptions) { | ||
*self.mask &= 0xFFFF; | ||
*self.id &= 0xFFFF; | ||
|
||
*self.mask |= (id << 3) | ((opts.rtr_enabled as u16) << 2); | ||
*self.id |= (mask << 3) | ((opts.rtr_enabled as u16) << 2); | ||
} | ||
} | ||
|
||
impl CanFilter<Bit16Mode, ListMode> { | ||
pub fn get(&mut self, index: usize) -> Option<Bit16IdReg> { | ||
use core::mem; | ||
|
||
match index { | ||
0 => { | ||
let bytes = unsafe { &mut *mem::transmute::<*mut u32, *mut [u16; 2]>(&mut self.id_value) }; | ||
Some(Bit16IdReg(&mut bytes[0])) | ||
} | ||
|
||
1 => { | ||
let bytes = unsafe { &mut *mem::transmute::<*mut u32, *mut [u16; 2]>(&mut self.id_value) }; | ||
Some(Bit16IdReg(&mut bytes[1])) | ||
} | ||
|
||
2 => { | ||
let bytes = unsafe { &mut *mem::transmute::<*mut u32, *mut [u16; 2]>(&mut self.id_mask) }; | ||
Some(Bit16IdReg(&mut bytes[0])) | ||
} | ||
|
||
3 => { | ||
let bytes = unsafe { &mut *mem::transmute::<*mut u32, *mut [u16; 2]>(&mut self.id_mask) }; | ||
Some(Bit16IdReg(&mut bytes[0])) | ||
} | ||
|
||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
impl From<[(StandardId, FilterOptions); 4]> for CanFilter<Bit16Mode, ListMode> { | ||
fn from(value: [(StandardId, FilterOptions); 4]) -> Self { | ||
let mut filter = CanFilter::new_id_list().use_16bit(); | ||
|
||
for (index, (id, opts)) in value.into_iter().enumerate() { | ||
filter.get(index).expect("index less 4").set(id, opts); | ||
} | ||
|
||
filter | ||
} | ||
} | ||
|
||
impl CanFilter<Bit16Mode, MaskMode> { | ||
pub fn get(&mut self, index: usize) -> Option<Bit16MaskReg> { | ||
use core::mem; | ||
|
||
match index { | ||
0 => { | ||
let [id, mask] = unsafe { &mut *mem::transmute::<*mut u32, *mut [u16; 2]>(&mut self.id_value) }; | ||
|
||
Some(Bit16MaskReg { id, mask }) | ||
} | ||
1 => { | ||
let [id, mask] = unsafe { &mut *mem::transmute::<*mut u32, *mut [u16; 2]>(&mut self.id_mask) }; | ||
|
||
Some(Bit16MaskReg { id, mask }) | ||
} | ||
_ => None, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
use core::marker::PhantomData; | ||
|
||
use embedded_can::Id; | ||
|
||
use super::{Bit16Mode, Bit32Mode, CanFilter, FilterMode, FilterOptions, ListMode, MaskMode}; | ||
|
||
impl<MODE: FilterMode> CanFilter<Bit32Mode, MODE> { | ||
pub fn use_16bit(self) -> CanFilter<Bit16Mode, MODE> { | ||
CanFilter { | ||
id_mask: self.id_mask, | ||
id_value: self.id_value, | ||
mode: self.mode, | ||
bank: self.bank, | ||
bit_mode: PhantomData, | ||
} | ||
} | ||
} | ||
|
||
impl CanFilter<Bit32Mode, ListMode> { | ||
/// Creates a filter that accepts all frames | ||
pub fn accept_all() -> Self { | ||
CanFilter { | ||
bank: 0, | ||
mode: ListMode, | ||
id_value: 0, | ||
id_mask: 0, | ||
bit_mode: PhantomData, | ||
} | ||
} | ||
|
||
pub fn new_id_list() -> Self { | ||
Self { | ||
bank: 0, | ||
bit_mode: PhantomData, | ||
mode: ListMode, | ||
|
||
id_mask: 0, | ||
id_value: 0, | ||
} | ||
} | ||
} | ||
|
||
impl CanFilter<Bit32Mode, MaskMode> { | ||
pub fn new_id_mask() -> Self { | ||
Self { | ||
bank: 0, | ||
bit_mode: PhantomData, | ||
mode: MaskMode, | ||
|
||
id_mask: 0, | ||
id_value: 0, | ||
} | ||
} | ||
} | ||
|
||
pub struct Bit32IdReg<'a>(&'a mut u32); | ||
|
||
impl Bit32IdReg<'_> { | ||
pub fn set(&mut self, id: Id, opts: FilterOptions) { | ||
*self.0 = 0; | ||
*self.0 |= (opts.rtr_enabled as u32) << 1; | ||
|
||
match id { | ||
Id::Standard(id) => { | ||
let id_bits = id.as_raw() as u32; | ||
|
||
*self.0 |= ((id_bits << 3) << 24) | ((id_bits & 0x7) << 20); | ||
} | ||
|
||
Id::Extended(id) => { | ||
let std_id = (id.as_raw() as u16) as u32; | ||
let ext_id = id.as_raw() >> 11; | ||
|
||
*self.0 |= ((std_id << 3) << 24) | ((std_id & 0x7) << 20) | (ext_id << 3); | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl CanFilter<Bit32Mode, ListMode> { | ||
pub fn get(&mut self, index: usize) -> Option<Bit32IdReg> { | ||
match index { | ||
0 => Some(Bit32IdReg(&mut self.id_value)), | ||
1 => Some(Bit32IdReg(&mut self.id_mask)), | ||
_ => None, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
mod bit16; | ||
mod bit32; | ||
|
||
use core::marker::PhantomData; | ||
|
||
/// Filter mode, either identifier mask or identifier list | ||
pub trait FilterMode { | ||
fn val_bool(&self) -> bool; | ||
} | ||
|
||
/// Matches the incoming ID to a predefined value after applying a predefined bit mask. | ||
pub struct MaskMode; | ||
pub struct ListMode; | ||
|
||
impl FilterMode for MaskMode { | ||
fn val_bool(&self) -> bool { | ||
false | ||
} | ||
} | ||
|
||
impl FilterMode for ListMode { | ||
fn val_bool(&self) -> bool { | ||
true | ||
} | ||
} | ||
|
||
pub trait BitMode {} | ||
|
||
pub struct Bit16Mode; | ||
pub struct Bit32Mode; | ||
|
||
impl BitMode for Bit16Mode {} | ||
impl BitMode for Bit32Mode {} | ||
|
||
/// See table 24-1 of the reference manual for more details on filtering and modes. | ||
/// Each filter is applied for only one bank and for one register on it bank | ||
pub struct CanFilter<BIT: BitMode, MODE: FilterMode> { | ||
/// Filter bank number, 0-27 | ||
pub bank: usize, | ||
/// Values for `STID:EXID:IDE:RTR:0` from msb to lsb to be matched with an incoming message's values. | ||
/// In IdList mode, value should be a 32-bit id or two 16-bit ids. | ||
pub id_value: u32, | ||
/// Bit mask to be applied to incoming message before comparing it to a predefined value. | ||
/// In IdList mode, this is used in the same way as `id_value` is. | ||
pub id_mask: u32, | ||
pub bit_mode: PhantomData<BIT>, | ||
pub mode: MODE, | ||
} | ||
|
||
impl<BIT: BitMode, MODE: FilterMode> CanFilter<BIT, MODE> { | ||
pub fn set_bank(&mut self, bank: usize) -> &mut Self { | ||
self.bank = bank; | ||
|
||
self | ||
} | ||
|
||
/// Offset in `usize` for bank `n` filter register 1 | ||
pub(crate) fn fr_id_value_reg(&self) -> usize { | ||
self.bank * 2 + 0 | ||
} | ||
|
||
/// Offset in `usize` for bank `n` filter register 2 | ||
pub(crate) fn fr_id_mask_reg(&self) -> usize { | ||
self.bank * 2 + 1 | ||
} | ||
} | ||
|
||
/// By default rtr is disabled | ||
#[derive(Default)] | ||
pub struct FilterOptions { | ||
pub rtr_enabled: bool, | ||
//todo: add ide? | ||
} |
Oops, something went wrong.