1use core::marker::PhantomData;
4
5use crate::pac::can::RegisterBlock;
6use crate::{ExtendedId, Fifo, FilterOwner, Id, Instance, MasterInstance, StandardId};
7
8const F32_RTR: u32 = 0b010; const F32_IDE: u32 = 0b100; const F16_RTR: u16 = 0b10000;
11const F16_IDE: u16 = 0b01000;
12
13#[derive(Debug, Copy, Clone, Eq, PartialEq)]
17#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
18pub struct ListEntry16(u16);
19
20#[derive(Debug, Copy, Clone, Eq, PartialEq)]
24#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
25pub struct ListEntry32(u32);
26
27#[derive(Debug, Copy, Clone)]
29#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
30pub struct Mask16 {
31 id: u16,
32 mask: u16,
33}
34
35#[derive(Debug, Copy, Clone)]
37#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
38pub struct Mask32 {
39 id: u32,
40 mask: u32,
41}
42
43impl ListEntry16 {
44 pub fn data_frames_with_id(id: StandardId) -> Self {
48 Self(id.as_raw() << 5)
49 }
50
51 pub fn remote_frames_with_id(id: StandardId) -> Self {
53 Self(id.as_raw() << 5 | F16_RTR)
54 }
55}
56
57impl ListEntry32 {
58 pub fn data_frames_with_id(id: impl Into<Id>) -> Self {
64 match id.into() {
65 Id::Standard(id) => Self(u32::from(id.as_raw()) << 21),
66 Id::Extended(id) => Self(id.as_raw() << 3 | F32_IDE),
67 }
68 }
69
70 pub fn remote_frames_with_id(id: impl Into<Id>) -> Self {
72 match id.into() {
73 Id::Standard(id) => Self(u32::from(id.as_raw()) << 21 | F32_RTR),
74 Id::Extended(id) => Self(id.as_raw() << 3 | F32_IDE | F32_RTR),
75 }
76 }
77}
78
79impl Mask16 {
80 pub fn accept_all() -> Self {
84 Self { id: 0, mask: 0 }
85 }
86
87 pub fn frames_with_std_id(id: StandardId, mask: StandardId) -> Self {
97 Self {
98 id: id.as_raw() << 5,
99 mask: mask.as_raw() << 5 | F16_IDE, }
101 }
102
103 pub fn data_frames_only(&mut self) -> &mut Self {
105 self.id &= !F16_RTR; self.mask |= F16_RTR;
107 self
108 }
109
110 pub fn remote_frames_only(&mut self) -> &mut Self {
112 self.id |= F16_RTR; self.mask |= F16_RTR;
114 self
115 }
116}
117
118impl Mask32 {
119 pub fn accept_all() -> Self {
123 Self { id: 0, mask: 0 }
124 }
125
126 pub fn frames_with_ext_id(id: ExtendedId, mask: ExtendedId) -> Self {
135 Self {
136 id: id.as_raw() << 3 | F32_IDE,
137 mask: mask.as_raw() << 3 | F32_IDE, }
139 }
140
141 pub fn frames_with_std_id(id: StandardId, mask: StandardId) -> Self {
150 Self {
151 id: u32::from(id.as_raw()) << 21,
152 mask: u32::from(mask.as_raw()) << 21 | F32_IDE, }
154 }
155
156 pub fn data_frames_only(&mut self) -> &mut Self {
158 self.id &= !F32_RTR; self.mask |= F32_RTR;
160 self
161 }
162
163 pub fn remote_frames_only(&mut self) -> &mut Self {
165 self.id |= F32_RTR; self.mask |= F32_RTR;
167 self
168 }
169}
170
171#[derive(Debug, Copy, Clone)]
173#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
174pub enum BankConfig {
175 List16([ListEntry16; 4]),
176 List32([ListEntry32; 2]),
177 Mask16([Mask16; 2]),
178 Mask32(Mask32),
179}
180
181impl From<[ListEntry16; 4]> for BankConfig {
182 #[inline]
183 fn from(entries: [ListEntry16; 4]) -> Self {
184 Self::List16(entries)
185 }
186}
187
188impl From<[ListEntry32; 2]> for BankConfig {
189 #[inline]
190 fn from(entries: [ListEntry32; 2]) -> Self {
191 Self::List32(entries)
192 }
193}
194
195impl From<[Mask16; 2]> for BankConfig {
196 #[inline]
197 fn from(entries: [Mask16; 2]) -> Self {
198 Self::Mask16(entries)
199 }
200}
201
202impl From<Mask32> for BankConfig {
203 #[inline]
204 fn from(filter: Mask32) -> Self {
205 Self::Mask32(filter)
206 }
207}
208
209pub struct MasterFilters<'a, I: FilterOwner> {
211 bank_count: u8,
215 _can: PhantomData<&'a mut I>,
216}
217
218impl<I: FilterOwner> MasterFilters<'_, I> {
221 pub(crate) unsafe fn new() -> Self {
222 let can = &*I::REGISTERS;
223
224 can.fmr.modify(|_, w| w.finit().set_bit());
226
227 let bank_count = can.fmr.read().can2sb().bits();
229
230 Self {
235 bank_count,
236 _can: PhantomData,
237 }
238 }
239
240 fn registers(&self) -> &RegisterBlock {
241 unsafe { &*I::REGISTERS }
242 }
243
244 fn banks_imm(&self) -> FilterBanks<'_> {
245 FilterBanks {
246 start_idx: 0,
247 bank_count: self.bank_count,
248 can: self.registers(),
249 }
250 }
251
252 pub fn num_banks(&self) -> u8 {
257 self.bank_count
258 }
259
260 pub fn clear(&mut self) -> &mut Self {
264 self.banks_imm().clear();
265 self
266 }
267
268 pub fn disable_bank(&mut self, index: u8) -> &mut Self {
272 self.banks_imm().disable(index);
273 self
274 }
275
276 pub fn enable_bank(
290 &mut self,
291 index: u8,
292 fifo: Fifo,
293 config: impl Into<BankConfig>,
294 ) -> &mut Self {
295 self.banks_imm().enable(index, fifo, config.into());
296 self
297 }
298}
299
300impl<I: MasterInstance> MasterFilters<'_, I> {
301 pub fn set_split(&mut self, split_index: u8) -> &mut Self {
303 assert!(split_index <= I::NUM_FILTER_BANKS);
304 self.registers()
305 .fmr
306 .modify(|_, w| unsafe { w.can2sb().bits(split_index) });
307 self.bank_count = split_index;
308 self
309 }
310
311 pub fn slave_filters(&mut self) -> SlaveFilters<'_, I> {
313 SlaveFilters {
315 start_idx: self.bank_count,
316 bank_count: I::NUM_FILTER_BANKS - self.bank_count,
317 _can: PhantomData,
318 }
319 }
320}
321
322impl<I: FilterOwner> Drop for MasterFilters<'_, I> {
323 #[inline]
324 fn drop(&mut self) {
325 let can = self.registers();
326
327 can.fmr.modify(|_, w| w.finit().clear_bit());
329 }
330}
331
332pub struct SlaveFilters<'a, I: Instance> {
334 start_idx: u8,
335 bank_count: u8,
336 _can: PhantomData<&'a mut I>,
337}
338
339impl<I: Instance> SlaveFilters<'_, I> {
340 fn registers(&self) -> &RegisterBlock {
341 unsafe { &*I::REGISTERS }
342 }
343
344 fn banks_imm(&self) -> FilterBanks<'_> {
345 FilterBanks {
346 start_idx: self.start_idx,
347 bank_count: self.bank_count,
348 can: self.registers(),
349 }
350 }
351
352 pub fn num_banks(&self) -> u8 {
357 self.bank_count
358 }
359
360 pub fn clear(&mut self) -> &mut Self {
364 self.banks_imm().clear();
365 self
366 }
367
368 pub fn disable_bank(&mut self, index: u8) -> &mut Self {
372 self.banks_imm().disable(index);
373 self
374 }
375
376 pub fn enable_bank(
384 &mut self,
385 index: u8,
386 fifo: Fifo,
387 config: impl Into<BankConfig>,
388 ) -> &mut Self {
389 self.banks_imm().enable(index, fifo, config.into());
390 self
391 }
392}
393
394struct FilterBanks<'a> {
395 start_idx: u8,
396 bank_count: u8,
397 can: &'a RegisterBlock,
398}
399
400impl FilterBanks<'_> {
401 fn clear(&mut self) {
402 let mask = filter_bitmask(self.start_idx, self.bank_count);
403
404 self.can.fa1r.modify(|r, w| {
405 let bits = r.bits();
406 unsafe { w.bits(bits & !mask) }
408 });
409 }
410
411 fn assert_bank_index(&self, index: u8) {
412 assert!((self.start_idx..self.start_idx + self.bank_count).contains(&index));
413 }
414
415 fn disable(&mut self, index: u8) {
416 self.assert_bank_index(index);
417
418 self.can
419 .fa1r
420 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << index)) })
421 }
422
423 fn enable(&mut self, index: u8, fifo: Fifo, config: BankConfig) {
424 self.assert_bank_index(index);
425
426 let mode = matches!(config, BankConfig::List16(_) | BankConfig::List32(_));
428 self.can.fm1r.modify(|r, w| {
429 let mut bits = r.bits();
430 if mode {
431 bits |= 1 << index;
432 } else {
433 bits &= !(1 << index);
434 }
435 unsafe { w.bits(bits) }
436 });
437
438 let scale = matches!(config, BankConfig::List32(_) | BankConfig::Mask32(_));
440 self.can.fs1r.modify(|r, w| {
441 let mut bits = r.bits();
442 if scale {
443 bits |= 1 << index;
444 } else {
445 bits &= !(1 << index);
446 }
447 unsafe { w.bits(bits) }
448 });
449
450 let (fxr1, fxr2);
452 match config {
453 BankConfig::List16([a, b, c, d]) => {
454 fxr1 = (u32::from(b.0) << 16) | u32::from(a.0);
455 fxr2 = (u32::from(d.0) << 16) | u32::from(c.0);
456 }
457 BankConfig::List32([a, b]) => {
458 fxr1 = a.0;
459 fxr2 = b.0;
460 }
461 BankConfig::Mask16([a, b]) => {
462 fxr1 = (u32::from(a.mask) << 16) | u32::from(a.id);
463 fxr2 = (u32::from(b.mask) << 16) | u32::from(b.id);
464 }
465 BankConfig::Mask32(a) => {
466 fxr1 = a.id;
467 fxr2 = a.mask;
468 }
469 };
470 let bank = &self.can.fb[usize::from(index)];
471 bank.fr1.write(|w| unsafe { w.bits(fxr1) });
472 bank.fr2.write(|w| unsafe { w.bits(fxr2) });
473
474 self.can.ffa1r.modify(|r, w| unsafe {
476 let mut bits = r.bits();
477 match fifo {
478 Fifo::Fifo0 => bits &= !(1 << index),
479 Fifo::Fifo1 => bits |= 1 << index,
480 }
481 w.bits(bits)
482 });
483
484 self.can
486 .fa1r
487 .modify(|r, w| unsafe { w.bits(r.bits() | (1 << index)) })
488 }
489}
490
491fn filter_bitmask(start_idx: u8, bank_count: u8) -> u32 {
493 let count_mask = (1 << bank_count) - 1; count_mask << start_idx
495}
496
497#[cfg(test)]
498mod tests {
499 use super::*;
500
501 #[test]
502 fn test_filter_bitmask() {
503 assert_eq!(filter_bitmask(0, 1), 0x1);
504 assert_eq!(filter_bitmask(1, 1), 0b10);
505 assert_eq!(filter_bitmask(0, 4), 0xf);
506 assert_eq!(filter_bitmask(1, 3), 0xe);
507 assert_eq!(filter_bitmask(8, 1), 0x100);
508 assert_eq!(filter_bitmask(8, 4), 0xf00);
509 }
510}