Skip to content

Commit a168666

Browse files
committed
can: Fix and improve filter configuration
1 parent 28ea852 commit a168666

File tree

4 files changed

+40
-31
lines changed

4 files changed

+40
-31
lines changed

examples/can-echo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn main() -> ! {
4949
// Split the filters at index 0: No filters for CAN1 (unused), 28 filters
5050
// for CAN2.
5151
let (_filters1, mut filters2) = can1.split_filters(0).unwrap();
52-
filters2.add(Filter::accept_all()).unwrap(); // Receive all messages.
52+
filters2.add(&Filter::accept_all()).unwrap(); // Receive all messages.
5353
let mut rx = can2.take_rx(filters2).unwrap();
5454

5555
// Sync to the bus and start normal operation.

examples/can-loopback.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn main() -> ! {
4545
let mut filters = can.split_filters().unwrap();
4646
#[cfg(feature = "connectivity")]
4747
let (mut filters, _) = can.split_filters(NUM_FILTER_BANKS / 2).unwrap();
48-
filters.add(Filter::accept_all()).unwrap();
48+
filters.add(&Filter::accept_all()).unwrap();
4949
let mut rx = can.take_rx(filters).unwrap();
5050

5151
// Sync to the bus and start normal operation.

examples/can-rtfm.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ const APP: () = {
8888
let (_, mut filters) = can1.split_filters(0).unwrap();
8989

9090
// To share load between FIFOs use one filter for standard messages and another
91-
// for extended messages. Accept all IDs by setting the mask to 0. Only accept
92-
// data frames (no remote frames).
91+
// for extended messages. Accept all IDs by setting the mask to 0. Explicitly
92+
// allow to receive remote frames.
9393
filters
94-
.add(Filter::new_standard(0).with_mask(0).with_rtr(false))
94+
.add(&Filter::new_standard(0).with_mask(0).allow_remote())
9595
.unwrap();
9696
filters
97-
.add(Filter::new_extended(0).with_mask(0).with_rtr(false))
97+
.add(&Filter::new_extended(0).with_mask(0).allow_remote())
9898
.unwrap();
9999

100100
let mut can_rx = can2.take_rx(filters).unwrap();

src/can.rs

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl Id {
6161
const EXTENDED_SHIFT: u32 = 3;
6262
const EXTENDED_MASK: u32 = 0x1FFF_FFFF << Self::EXTENDED_SHIFT;
6363

64-
const EID_MASK: u32 = 0x0000_0004;
64+
const IDE_MASK: u32 = 0x0000_0004;
6565

6666
const RTR_MASK: u32 = 0x0000_0002;
6767

@@ -78,7 +78,7 @@ impl Id {
7878
/// Ids outside the allowed range are silently truncated.
7979
pub fn new_extended(id: u32) -> Id {
8080
assert!(id < 0x1FFF_FFFF);
81-
Self(id << Self::EXTENDED_SHIFT | Self::EID_MASK)
81+
Self(id << Self::EXTENDED_SHIFT | Self::IDE_MASK)
8282
}
8383

8484
fn from_register(reg: u32) -> Id {
@@ -108,7 +108,7 @@ impl Id {
108108

109109
/// Returns `true` if the identifier is an extended identifier.
110110
pub fn is_extended(self) -> bool {
111-
self.0 & Self::EID_MASK != 0
111+
self.0 & Self::IDE_MASK != 0
112112
}
113113

114114
/// Returns `true` if the identifier is a standard identifier.
@@ -526,56 +526,59 @@ pub struct Filter {
526526
mask: u32,
527527
}
528528

529-
/// bxCAN filters have some quirks:
530-
/// https://github.com/UAVCAN/libcanard/blob/8ee343c4edae0e0e4e1c040852aa3d8430f7bf76/drivers/stm32/canard_stm32.c#L471-L513
531529
impl Filter {
532530
/// Creates a filter that accepts all messages.
533531
pub fn accept_all() -> Self {
534-
Self {
535-
id: Id::EID_MASK | Id::RTR_MASK,
536-
mask: 0,
537-
}
532+
Self { id: 0, mask: 0 }
538533
}
539534

540535
/// Creates a filter that accepts frames with the specified standard identifier.
541536
pub fn new_standard(id: u32) -> Self {
542537
Self {
543-
id: id << Id::STANDARD_SHIFT | Id::RTR_MASK,
544-
mask: Id::STANDARD_MASK | Id::EID_MASK,
538+
id: id << Id::STANDARD_SHIFT,
539+
mask: Id::STANDARD_MASK | Id::IDE_MASK | Id::RTR_MASK,
545540
}
546541
}
547542

548543
/// Creates a filter that accepts frames with the extended standard identifier.
549544
pub fn new_extended(id: u32) -> Self {
550545
Self {
551-
id: id << Id::EXTENDED_SHIFT | Id::RTR_MASK | Id::EID_MASK,
552-
mask: Id::EXTENDED_MASK | Id::EID_MASK,
546+
id: id << Id::EXTENDED_SHIFT | Id::IDE_MASK,
547+
mask: Id::EXTENDED_MASK | Id::IDE_MASK | Id::RTR_MASK,
553548
}
554549
}
555550

556551
/// Only look at the bits of the indentifier which are set to 1 in the mask.
557552
///
558553
/// A mask of 0 accepts all identifiers.
559-
pub fn with_mask(mut self, mask: u32) -> Self {
560-
if self.id & Id::EID_MASK != 0 {
554+
pub fn with_mask(&mut self, mask: u32) -> &mut Self {
555+
if self.is_extended() {
561556
self.mask = (self.mask & !Id::EXTENDED_MASK) | (mask << Id::EXTENDED_SHIFT);
562557
} else {
563558
self.mask = (self.mask & !Id::STANDARD_MASK) | (mask << Id::STANDARD_SHIFT);
564559
}
565560
self
566561
}
567562

568-
/// Select if only remote (`rtr = true`) frames or only data (`rtr = false`)
569-
/// shall be received.
570-
pub fn with_rtr(mut self, rtr: bool) -> Self {
571-
if rtr {
572-
self.id |= Id::RTR_MASK;
573-
} else {
574-
self.id &= !Id::RTR_MASK;
575-
}
563+
/// Makes this filter accept both data and remote frames.
564+
pub fn allow_remote(&mut self) -> &mut Self {
565+
self.mask &= !Id::RTR_MASK;
566+
self
567+
}
568+
569+
/// Makes this filter accept only remote frames.
570+
pub fn only_remote(&mut self) -> &mut Self {
571+
self.id |= Id::RTR_MASK;
576572
self.mask |= Id::RTR_MASK;
577573
self
578574
}
575+
576+
fn is_extended(&self) -> bool {
577+
self.id & Id::IDE_MASK != 0
578+
}
579+
580+
fn matches_single_id(&self) -> bool {
581+
}
579582
}
580583

581584
/// Interface to the filter banks of a CAN peripheral.
@@ -604,11 +607,17 @@ where
604607
}
605608

606609
/// Adds a filter. Returns `Err` if the maximum number of filters was reached.
607-
pub fn add(&mut self, filter: Filter) -> Result<(), ()> {
610+
pub fn add(&mut self, filter: &Filter) -> Result<(), ()> {
608611
let can = unsafe { &*CAN1::ptr() };
609612

610613
let idx = self.start_idx + self.count;
611-
if idx < self.stop_idx {
614+
if idx >= self.stop_idx {
615+
return Err(());
616+
}
617+
618+
let list_mode = (can.fm1r.read().bits() & (1 << idx)) != 0;
619+
let scale_32bit = (can.fs1r.read().bits() & (1 << idx)) != 0;
620+
if !list_mode && scale_32bit {
612621
let filter_bank = &can.fb[idx];
613622
filter_bank.fr1.write(|w| unsafe { w.bits(filter.id) });
614623
filter_bank.fr2.write(|w| unsafe { w.bits(filter.mask) });

0 commit comments

Comments
 (0)