@@ -473,7 +473,10 @@ impl Can<CAN1> {
473
473
/// Filters are required for the receiver to accept any messages at all.
474
474
#[ cfg( not( feature = "connectivity" ) ) ]
475
475
pub fn split_filters ( & mut self ) -> Option < Filters < CAN1 > > {
476
- self . split_filters_internal ( NUM_FILTER_BANKS ) ?;
476
+ // Set all filter banks to 32bit scale and mask mode.
477
+ // Filters are alternating between between the FIFO0 and FIFO1 to share the
478
+ // load equally.
479
+ self . split_filters_internal ( 0x0000_0000 , 0xFFFF_FFFF , 0xAAAA_AAAA , NUM_FILTER_BANKS ) ?;
477
480
Some ( Filters :: new ( 0 , NUM_FILTER_BANKS ) )
478
481
}
479
482
@@ -486,33 +489,80 @@ impl Can<CAN1> {
486
489
/// for CAN2.
487
490
#[ cfg( feature = "connectivity" ) ]
488
491
pub fn split_filters ( & mut self , split_idx : usize ) -> Option < ( Filters < CAN1 > , Filters < CAN2 > ) > {
489
- self . split_filters_internal ( split_idx) ?;
492
+ // Set all filter banks to 32bit scale and mask mode.
493
+ // Filters are alternating between between the FIFO0 and FIFO1 to share the
494
+ // load equally.
495
+ self . split_filters_internal ( 0x0000_0000 , 0xFFFF_FFFF , 0xAAAA_AAAA , split_idx) ?;
490
496
Some ( (
491
497
Filters :: new ( 0 , split_idx) ,
492
498
Filters :: new ( split_idx, NUM_FILTER_BANKS ) ,
493
499
) )
494
500
}
495
501
496
- fn split_filters_internal ( & mut self , split_idx : usize ) -> Option < ( ) > {
502
+ /// Advanced version of `Can::split_filters()`.
503
+ ///
504
+ /// The additional parameters are bitmasks configure the filter banks.
505
+ /// Bit 0 for filter bank 0, bit 1 for filter bank 1 and so on.
506
+ /// `fm1r` in combination with `fs1r` sets the filter bank layout. The correct
507
+ /// `Filters::add_*()` function must be used.
508
+ /// `ffa1r` selects the FIFO the filter uses to store accepted messages.
509
+ /// More details can be found in the reference manual of the device.
510
+ #[ cfg( not( feature = "connectivity" ) ) ]
511
+ pub fn split_filters_advanced (
512
+ & mut self ,
513
+ fm1r : u32 ,
514
+ fs1r : u32 ,
515
+ ffa1r : u32 ,
516
+ ) -> Option < Filters < CAN1 > > {
517
+ self . split_filters_internal ( fm1r, fs1r, ffa1r, NUM_FILTER_BANKS ) ?;
518
+ Some ( Filters :: new ( 0 , NUM_FILTER_BANKS ) )
519
+ }
520
+
521
+ /// Advanced version of `Can::split_filters()`.
522
+ ///
523
+ /// The additional parameters are bitmasks to configure the filter banks.
524
+ /// Bit 0 for filter bank 0, bit 1 for filter bank 1 and so on.
525
+ /// `fm1r` in combination with `fs1r` sets the filter bank layout. The correct
526
+ /// `Filters::add_*()` function must be used.
527
+ /// `ffa1r` selects the FIFO the filter uses to store accepted messages.
528
+ /// More details can be found in the reference manual of the device.
529
+ #[ cfg( feature = "connectivity" ) ]
530
+ pub fn split_filters_advanced (
531
+ & mut self ,
532
+ fm1r : u32 ,
533
+ fs1r : u32 ,
534
+ ffa1r : u32 ,
535
+ split_idx : usize ,
536
+ ) -> Option < ( Filters < CAN1 > , Filters < CAN2 > ) > {
537
+ self . split_filters_internal ( fm1r, fs1r, ffa1r, split_idx) ?;
538
+ Some ( (
539
+ Filters :: new ( 0 , split_idx) ,
540
+ Filters :: new ( split_idx, NUM_FILTER_BANKS ) ,
541
+ ) )
542
+ }
543
+
544
+ fn split_filters_internal (
545
+ & mut self ,
546
+ fm1r : u32 ,
547
+ fs1r : u32 ,
548
+ ffa1r : u32 ,
549
+ _split_idx : usize ,
550
+ ) -> Option < ( ) > {
497
551
let can = unsafe { & * CAN1 :: ptr ( ) } ;
498
552
499
553
if can. fmr . read ( ) . finit ( ) . bit_is_clear ( ) {
500
554
return None ;
501
555
}
502
556
503
- // Same configuration for all filters banks.
504
- can. fm1r . write ( |w| unsafe { w. bits ( 0x0000_0000 ) } ) ; // Mask mode
505
- can. fs1r . write ( |w| unsafe { w. bits ( 0xFFFF_FFFF ) } ) ; // 32bit scale
506
-
507
- // Filters are alternating between between the FIFO0 and FIFO1 to share the
508
- // load equally.
509
- can. ffa1r . write ( |w| unsafe { w. bits ( 0xAAAA_AAAA ) } ) ;
557
+ can. fm1r . write ( |w| unsafe { w. bits ( fm1r) } ) ;
558
+ can. fs1r . write ( |w| unsafe { w. bits ( fs1r) } ) ;
559
+ can. ffa1r . write ( |w| unsafe { w. bits ( ffa1r) } ) ;
510
560
511
561
// Init filter banks. Each used filter must still be enabled individually.
512
562
#[ allow( unused_unsafe) ]
513
563
can. fmr . modify ( |_, w| unsafe {
514
564
#[ cfg( feature = "connectivity" ) ]
515
- w. can2sb ( ) . bits ( split_idx as u8 ) ;
565
+ w. can2sb ( ) . bits ( _split_idx as u8 ) ;
516
566
w. finit ( ) . clear_bit ( )
517
567
} ) ;
518
568
@@ -578,6 +628,16 @@ impl Filter {
578
628
}
579
629
580
630
fn matches_single_id ( & self ) -> bool {
631
+ ( ( self . mask & ( Id :: IDE_MASK | Id :: RTR_MASK ) ) == ( Id :: IDE_MASK | Id :: RTR_MASK ) )
632
+ && if self . is_extended ( ) {
633
+ ( self . mask & Id :: EXTENDED_MASK ) == Id :: EXTENDED_MASK
634
+ } else {
635
+ ( self . mask & Id :: STANDARD_MASK ) == Id :: STANDARD_MASK
636
+ }
637
+ }
638
+
639
+ fn as_16bit_filter ( reg : u32 ) -> u32 {
640
+ ( reg & Id :: STANDARD_MASK ) >> 16 | ( reg & Id :: IDE_MASK ) << 1 | ( reg & Id :: RTR_MASK ) << 3
581
641
}
582
642
}
583
643
@@ -602,33 +662,116 @@ where
602
662
}
603
663
}
604
664
605
- pub fn num_filters ( & self ) -> usize {
606
- self . stop_idx - self . start_idx
665
+ /// Returns the number of available filters.
666
+ pub fn num_available ( & self ) -> usize {
667
+ let can = unsafe { & * CAN1 :: ptr ( ) } ;
668
+
669
+ let mut filter_count = self . stop_idx - self . start_idx ;
670
+
671
+ let owned_bits = ( ( 1 << filter_count) - 1 ) << self . start_idx ;
672
+ let mode_list = can. fm1r . read ( ) . bits ( ) & owned_bits;
673
+ let scale_16bit = !can. fs1r . read ( ) . bits ( ) & owned_bits;
674
+
675
+ filter_count += mode_list. count_ones ( ) as usize ;
676
+ filter_count += scale_16bit. count_ones ( ) as usize ;
677
+ filter_count += ( mode_list & scale_16bit) . count_ones ( ) as usize ;
678
+ filter_count
607
679
}
608
680
609
681
/// Adds a filter. Returns `Err` if the maximum number of filters was reached.
610
682
pub fn add ( & mut self , filter : & Filter ) -> Result < ( ) , ( ) > {
611
- let can = unsafe { & * CAN1 :: ptr ( ) } ;
683
+ let idx = self . next_idx ( ) ?;
684
+ self . check_config ( idx, false , true ) ?;
685
+ self . write_filter_bank ( idx, filter. id , filter. mask ) ;
686
+ Ok ( ( ) )
687
+ }
612
688
613
- let idx = self . start_idx + self . count ;
614
- if idx >= self . stop_idx {
689
+ /// Adds two filters, each filtering for a single ID.
690
+ ///
691
+ /// The filter bank must to be configured to `fm1r.fbm = 1` and `fs1r.fsc = 1` by
692
+ /// `Can::split_filters_advanced()`.
693
+ pub fn add_list ( & mut self , filters : [ & Filter ; 2 ] ) -> Result < ( ) , ( ) > {
694
+ if !filters[ 0 ] . matches_single_id ( ) || !filters[ 1 ] . matches_single_id ( ) {
695
+ return Err ( ( ) ) ;
696
+ }
697
+
698
+ let idx = self . next_idx ( ) ?;
699
+ self . check_config ( idx, true , true ) ?;
700
+ self . write_filter_bank ( idx, filters[ 0 ] . id , filters[ 1 ] . id ) ;
701
+ Ok ( ( ) )
702
+ }
703
+
704
+ /// Adds two standard ID filters with mask support.
705
+ ///
706
+ /// The filter bank must to be configured to `fm1r.fbm = 0` and `fs1r.fsc = 0` by
707
+ /// `Can::split_filters_advanced()`.
708
+ pub fn add_standard ( & mut self , filters : [ & Filter ; 2 ] ) -> Result < ( ) , ( ) > {
709
+ if filters[ 0 ] . is_extended ( ) || filters[ 1 ] . is_extended ( ) {
615
710
return Err ( ( ) ) ;
616
711
}
617
712
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 {
621
- let filter_bank = & can. fb [ idx] ;
622
- filter_bank. fr1 . write ( |w| unsafe { w. bits ( filter. id ) } ) ;
623
- filter_bank. fr2 . write ( |w| unsafe { w. bits ( filter. mask ) } ) ;
624
- bb:: set ( & can. fa1r , idx as u8 ) ; // Enable filter
625
- self . count += 1 ;
713
+ let idx = self . next_idx ( ) ?;
714
+ self . check_config ( idx, false , false ) ?;
715
+ self . write_filter_bank (
716
+ idx,
717
+ Filter :: as_16bit_filter ( filters[ 0 ] . mask ) << 16 | Filter :: as_16bit_filter ( filters[ 0 ] . id ) ,
718
+ Filter :: as_16bit_filter ( filters[ 1 ] . mask ) << 16 | Filter :: as_16bit_filter ( filters[ 1 ] . id ) ,
719
+ ) ;
720
+ Ok ( ( ) )
721
+ }
722
+
723
+ /// Adds four filters, each filtering for a single standard ID.
724
+ ///
725
+ /// The filter bank must to be configured to `fm1r.fbm = 1` and `fs1r.fsc = 0` by
726
+ /// `Can::split_filters_advanced()`.
727
+ pub fn add_standard_list ( & mut self , filters : [ & Filter ; 4 ] ) -> Result < ( ) , ( ) > {
728
+ for filter in & filters {
729
+ if !filter. matches_single_id ( ) {
730
+ return Err ( ( ) ) ;
731
+ }
732
+ }
733
+
734
+ let idx = self . next_idx ( ) ?;
735
+ self . check_config ( idx, true , false ) ?;
736
+ self . write_filter_bank (
737
+ idx,
738
+ Filter :: as_16bit_filter ( filters[ 1 ] . id ) << 16 | Filter :: as_16bit_filter ( filters[ 0 ] . id ) ,
739
+ Filter :: as_16bit_filter ( filters[ 3 ] . id ) << 16 | Filter :: as_16bit_filter ( filters[ 2 ] . id ) ,
740
+ ) ;
741
+ Ok ( ( ) )
742
+ }
743
+
744
+ fn next_idx ( & self ) -> Result < usize , ( ) > {
745
+ let idx = self . start_idx + self . count ;
746
+ if idx < self . stop_idx {
747
+ Ok ( idx)
748
+ } else {
749
+ Err ( ( ) )
750
+ }
751
+ }
752
+
753
+ fn check_config ( & self , idx : usize , mode_list : bool , scale_32bit : bool ) -> Result < ( ) , ( ) > {
754
+ let can = unsafe { & * CAN1 :: ptr ( ) } ;
755
+
756
+ if mode_list == ( ( can. fm1r . read ( ) . bits ( ) & ( 1 << idx) ) != 0 )
757
+ && scale_32bit == ( ( can. fs1r . read ( ) . bits ( ) & ( 1 << idx) ) != 0 )
758
+ {
626
759
Ok ( ( ) )
627
760
} else {
628
761
Err ( ( ) )
629
762
}
630
763
}
631
764
765
+ fn write_filter_bank ( & mut self , idx : usize , fr1 : u32 , fr2 : u32 ) {
766
+ let can = unsafe { & * CAN1 :: ptr ( ) } ;
767
+
768
+ let filter_bank = & can. fb [ idx] ;
769
+ filter_bank. fr1 . write ( |w| unsafe { w. bits ( fr1) } ) ;
770
+ filter_bank. fr2 . write ( |w| unsafe { w. bits ( fr2) } ) ;
771
+ bb:: set ( & can. fa1r , idx as u8 ) ; // Enable filter
772
+ self . count += 1 ;
773
+ }
774
+
632
775
/// Disables all enabled filters.
633
776
pub fn clear ( & mut self ) {
634
777
let can = unsafe { & * CAN1 :: ptr ( ) } ;
0 commit comments