1use embedded_can::{ExtendedId, Id, StandardId};
7
8use crate::pac::twai0::{
9 RegisterBlock,
10 mode_settings::{MODE_SETTINGS_SPEC, RTRTH_W},
11 tx_priority::{TX_PRIORITY_SPEC, TXT1P_W},
12};
13
14pub(super) const FRAME_WORDS: usize = 20;
16pub(super) const MAX_DLC: u8 = 15;
18pub(super) const MAX_DATA_LEN: usize = 64;
20pub(super) const CLASSIC_MAX_DATA_LEN: usize = 8;
22
23pub(super) const STD_ID_MASK: u32 = 0x0000_07FF;
25pub(super) const EXT_ID_MASK: u32 = 0x1FFF_FFFF;
27const IDENTIFIER_BASE_SHIFT: u32 = 18;
29
30const fn field_max(width: u8) -> u8 {
32 ((1u16 << width) - 1) as u8
33}
34
35pub const MAX_RETRANSMIT_LIMIT: u8 = field_max(<RTRTH_W<'static, MODE_SETTINGS_SPEC>>::WIDTH);
37
38pub const MAX_TX_PRIORITY: u8 = field_max(<TXT1P_W<'static, TX_PRIORITY_SPEC>>::WIDTH);
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
46#[cfg_attr(feature = "defmt", derive(defmt::Format))]
47pub struct TimingLimits {
48 pub min: Timing,
50 pub max: Timing,
52}
53
54pub const NOMINAL_TIMING_LIMITS: TimingLimits = TimingLimits {
56 min: Timing {
57 baud_rate_prescaler: 1,
58 propagation_segment: 1,
59 phase_segment_1: 0,
60 phase_segment_2: 1,
61 sync_jump_width: 1,
62 },
63 max: Timing {
64 baud_rate_prescaler: 255,
65 propagation_segment: 127,
66 phase_segment_1: 63,
67 phase_segment_2: 63,
68 sync_jump_width: 31,
69 },
70};
71
72pub const FD_TIMING_LIMITS: TimingLimits = TimingLimits {
74 min: Timing {
75 baud_rate_prescaler: 1,
76 propagation_segment: 1,
77 phase_segment_1: 0,
78 phase_segment_2: 1,
79 sync_jump_width: 1,
80 },
81 max: Timing {
82 baud_rate_prescaler: 255,
83 propagation_segment: 63,
84 phase_segment_1: 31,
85 phase_segment_2: 31,
86 sync_jump_width: 31,
87 },
88};
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
92#[cfg_attr(feature = "defmt", derive(defmt::Format))]
93pub struct Timing {
94 pub baud_rate_prescaler: u8,
96 pub propagation_segment: u8,
98 pub phase_segment_1: u8,
100 pub phase_segment_2: u8,
102 pub sync_jump_width: u8,
104}
105
106impl Timing {
107 pub const fn is_valid(&self, limits: &TimingLimits) -> bool {
112 if (self.baud_rate_prescaler as u32) * (self.phase_segment_2 as u32) < 2 {
114 return false;
115 }
116 if (self.baud_rate_prescaler as u32)
118 * (1 + self.propagation_segment as u32 + self.phase_segment_1 as u32)
119 <= 2
120 {
121 return false;
122 }
123
124 let (min, max) = (&limits.min, &limits.max);
125 self.baud_rate_prescaler >= min.baud_rate_prescaler
126 && self.baud_rate_prescaler <= max.baud_rate_prescaler
127 && self.propagation_segment >= min.propagation_segment
128 && self.propagation_segment <= max.propagation_segment
129 && self.phase_segment_1 >= min.phase_segment_1
130 && self.phase_segment_1 <= max.phase_segment_1
131 && self.phase_segment_2 >= min.phase_segment_2
132 && self.phase_segment_2 <= max.phase_segment_2
133 && self.sync_jump_width >= min.sync_jump_width
134 && self.sync_jump_width <= max.sync_jump_width
135 }
136
137 pub const fn total_quanta(&self) -> u32 {
139 1 + self.propagation_segment as u32
140 + self.phase_segment_1 as u32
141 + self.phase_segment_2 as u32
142 }
143
144 pub const fn bit_rate(&self, clock_hz: u32) -> u32 {
146 clock_hz / (self.baud_rate_prescaler as u32 * self.total_quanta())
147 }
148
149 pub const fn sample_point_permille(&self) -> u32 {
151 (1 + self.propagation_segment as u32 + self.phase_segment_1 as u32) * 1000
152 / self.total_quanta()
153 }
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
158#[cfg_attr(feature = "defmt", derive(defmt::Format))]
159#[repr(u8)]
160pub enum SspSource {
161 MeasuredPlusOffset = 0,
163 Disabled = 1,
165 #[allow(dead_code)]
167 OffsetOnly = 2,
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
172#[cfg_attr(feature = "defmt", derive(defmt::Format))]
173pub enum TxBufferState {
174 NotExist,
176 Ready,
178 InProgress,
180 AbortInProgress,
182 Ok,
184 Failed,
186 Aborted,
188 Empty,
190 Unknown(u8),
192}
193
194impl TxBufferState {
195 fn from_bits(bits: u8) -> Self {
196 match bits {
198 0x0 => Self::NotExist,
199 0x1 => Self::Ready,
200 0x2 => Self::InProgress,
201 0x3 => Self::AbortInProgress,
202 0x4 => Self::Ok,
203 0x6 => Self::Failed,
204 0x7 => Self::Aborted,
205 0x8 => Self::Empty,
206 other => Self::Unknown(other),
207 }
208 }
209
210 pub fn is_writable(self) -> bool {
212 matches!(self, Self::Empty | Self::Ok | Self::Failed | Self::Aborted)
213 }
214}
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
221#[cfg_attr(feature = "defmt", derive(defmt::Format))]
222pub enum ErrorState {
223 Active,
225 Passive,
227 BusOff,
229}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233#[cfg_attr(feature = "defmt", derive(defmt::Format))]
234#[repr(u8)]
235pub enum TimestampPoint {
236 EndOfFrame = 0,
238 StartOfFrame = 1,
240}
241
242#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
244pub(super) struct ModeSettings {
245 pub listen_only: bool,
246 pub self_test: bool,
247 pub loopback: bool,
248 pub fd_enabled: bool,
249 pub protocol_exception: bool,
250 pub rx_auto_increment: bool,
251 pub filters_enabled: bool,
252 pub bus_off_tx_fail: bool,
253 pub drop_request_frames: bool,
254 pub time_triggered_tx: bool,
255 pub retransmit_limit: Option<u8>,
257}
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
261#[cfg_attr(feature = "defmt", derive(defmt::Format))]
262pub enum MaskFilter {
263 A,
265 B,
267 C,
269}
270
271#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
273#[cfg_attr(feature = "defmt", derive(defmt::Format))]
274pub enum FrameFormats {
275 Classic,
277 Fd,
279 #[default]
281 Both,
282}
283
284#[derive(Debug, Clone, Copy, PartialEq, Eq)]
288pub(super) struct FrameKinds {
289 classic_standard: bool,
290 classic_extended: bool,
291 fd_standard: bool,
292 fd_extended: bool,
293}
294
295impl FrameKinds {
296 pub(super) const ALL: Self = Self {
298 classic_standard: true,
299 classic_extended: true,
300 fd_standard: true,
301 fd_extended: true,
302 };
303
304 pub(super) const NONE: Self = Self {
306 classic_standard: false,
307 classic_extended: false,
308 fd_standard: false,
309 fd_extended: false,
310 };
311
312 pub(super) fn new(extended: bool, formats: FrameFormats) -> Self {
318 let classic = formats != FrameFormats::Fd;
319 let fd = formats != FrameFormats::Classic;
320 Self {
321 classic_standard: classic && !extended,
322 classic_extended: classic && extended,
323 fd_standard: fd && !extended,
324 fd_extended: fd && extended,
325 }
326 }
327
328 fn bits(self) -> u32 {
329 (self.classic_standard as u32)
330 | ((self.classic_extended as u32) << 1)
331 | ((self.fd_standard as u32) << 2)
332 | ((self.fd_extended as u32) << 3)
333 }
334}
335
336#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
338#[cfg_attr(feature = "defmt", derive(defmt::Format))]
339pub enum BusErrorKind {
340 Bit,
342 Crc,
344 Form,
346 Ack,
348 Stuff,
350 Unknown(u8),
352}
353
354impl BusErrorKind {
355 fn from_bits(bits: u8) -> Self {
356 match bits {
357 0 => Self::Bit,
358 1 => Self::Crc,
359 2 => Self::Form,
360 3 => Self::Ack,
361 4 => Self::Stuff,
362 other => Self::Unknown(other),
363 }
364 }
365}
366
367#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
369#[cfg_attr(feature = "defmt", derive(defmt::Format))]
370pub enum ErrorPosition {
371 StartOfFrame,
373 Arbitration,
375 Control,
377 Data,
379 Crc,
381 Ack,
383 EndOfFrame,
385 ErrorFrame,
387 OverloadFrame,
389 Other,
391 Unknown(u8),
393}
394
395impl ErrorPosition {
396 fn from_bits(bits: u8) -> Self {
397 match bits {
398 0 => Self::StartOfFrame,
399 1 => Self::Arbitration,
400 2 => Self::Control,
401 3 => Self::Data,
402 4 => Self::Crc,
403 5 => Self::Ack,
404 6 => Self::EndOfFrame,
405 7 => Self::ErrorFrame,
406 8 => Self::OverloadFrame,
407 31 => Self::Other,
408 other => Self::Unknown(other),
409 }
410 }
411}
412
413#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
419#[cfg_attr(feature = "defmt", derive(defmt::Format))]
420pub struct ErrorCapture {
421 pub kind: BusErrorKind,
423 pub position: ErrorPosition,
425}
426
427#[derive(Debug, Clone, Copy)]
429pub(super) struct FrameHeader {
430 pub id: Id,
431 pub request: bool,
432 pub fd: bool,
433 pub bit_rate_switch: bool,
434 pub dlc: u8,
435}
436
437#[derive(Clone, Copy, PartialEq, Eq)]
442pub(super) struct FrameBuffer {
443 words: [u32; FRAME_WORDS],
444}
445
446const _: () = core::assert!(cfg!(target_endian = "little"));
449
450impl FrameBuffer {
451 const DATA_WORD_OFFSET: usize = 4;
452
453 pub(super) const fn new() -> Self {
454 Self {
455 words: [0; FRAME_WORDS],
456 }
457 }
458
459 pub(super) fn dlc(&self) -> u8 {
460 (self.words[0] & 0xF) as u8
461 }
462
463 pub(super) fn is_request(&self) -> bool {
464 self.words[0] & (1 << 5) != 0
465 }
466
467 pub(super) fn is_extended(&self) -> bool {
468 self.words[0] & (1 << 6) != 0
469 }
470
471 pub(super) fn is_fd(&self) -> bool {
472 self.words[0] & (1 << 7) != 0
473 }
474
475 pub(super) fn is_bit_rate_switched(&self) -> bool {
476 self.words[0] & (1 << 9) != 0
477 }
478
479 pub(super) fn error_state_indicator(&self) -> bool {
480 self.words[0] & (1 << 10) != 0
481 }
482
483 fn word_count(&self) -> u8 {
488 ((self.words[0] >> 11) & 0x1F) as u8
489 }
490
491 pub(super) fn id(&self) -> Id {
492 if self.is_extended() {
493 Id::Extended(unsafe { ExtendedId::new_unchecked(self.words[1] & EXT_ID_MASK) })
495 } else {
496 let raw = (self.words[1] >> IDENTIFIER_BASE_SHIFT) & STD_ID_MASK;
497 Id::Standard(unsafe { StandardId::new_unchecked(raw as u16) })
498 }
499 }
500
501 pub(super) fn timestamp(&self) -> u64 {
502 (self.words[2] as u64) | ((self.words[3] as u64) << 32)
503 }
504
505 pub(super) fn data_len(&self) -> usize {
510 if self.is_request() {
511 return 0;
512 }
513 let len = dlc_to_len(self.dlc()) as usize;
514 if self.is_fd() {
515 len
516 } else {
517 len.min(CLASSIC_MAX_DATA_LEN)
518 }
519 }
520
521 pub(super) fn requested_len(&self) -> usize {
523 (dlc_to_len(self.dlc()) as usize).min(CLASSIC_MAX_DATA_LEN)
524 }
525
526 pub(super) fn data(&self) -> &[u8] {
528 let words = &self.words[Self::DATA_WORD_OFFSET..];
529 let bytes =
531 unsafe { core::slice::from_raw_parts(words.as_ptr().cast::<u8>(), words.len() * 4) };
532 &bytes[..self.data_len()]
533 }
534
535 pub(super) fn build(header: FrameHeader, data: &[u8]) -> Self {
537 debug_assert!(header.dlc <= MAX_DLC);
538 debug_assert!(data.len() <= MAX_DATA_LEN);
539
540 let mut frame = Self::new();
541
542 let (id, extended) = match header.id {
543 Id::Standard(id) => ((u32::from(id.as_raw())) << IDENTIFIER_BASE_SHIFT, false),
544 Id::Extended(id) => (id.as_raw(), true),
545 };
546
547 frame.words[0] = (header.dlc as u32 & 0xF)
548 | ((header.request as u32) << 5)
549 | ((extended as u32) << 6)
550 | ((header.fd as u32) << 7)
551 | ((header.bit_rate_switch as u32) << 9);
552 frame.words[1] = id;
553 for (i, &byte) in data.iter().enumerate() {
557 frame.words[Self::DATA_WORD_OFFSET + i / 4] |= (byte as u32) << (8 * (i % 4));
558 }
559
560 frame
561 }
562}
563
564pub(super) const fn dlc_to_len(dlc: u8) -> u8 {
566 match dlc {
567 0..=8 => dlc,
568 9..=12 => (dlc - 8) * 4 + 8,
569 13 => 32,
570 14 => 48,
571 _ => 64,
572 }
573}
574
575pub(super) const fn len_to_dlc(len: u8) -> u8 {
578 match len {
579 0..=8 => len,
580 9..=24 => (len - 8).div_ceil(4) + 8,
581 25..=32 => (len - 24).div_ceil(8) + 12,
582 33..=64 => (len - 32).div_ceil(16) + 13,
583 _ => MAX_DLC,
584 }
585}
586
587pub(super) struct Driver {
589 regs: *const RegisterBlock,
590}
591
592unsafe impl Send for Driver {}
594unsafe impl Sync for Driver {}
595
596impl Driver {
597 pub(super) fn new(regs: *const RegisterBlock) -> Self {
598 Self { regs }
599 }
600
601 fn r(&self) -> &RegisterBlock {
602 unsafe { &*self.regs }
603 }
604
605 pub(super) fn device_id(&self) -> u16 {
606 self.r().device_id_version().read().device_id().bits()
607 }
608
609 pub(super) fn version(&self) -> (u8, u8) {
611 let r = self.r().device_id_version().read();
612 (r.ver_major().bits(), r.ver_minor().bits())
613 }
614
615 pub(super) fn reset(&self) {
617 self.r().mode_settings().modify(|_, w| w.rst().set_bit());
618 }
619
620 pub(super) fn enable(&self, enable: bool) {
621 self.r().mode_settings().modify(|_, w| w.ena().bit(enable));
622 }
623
624 pub(super) fn is_enabled(&self) -> bool {
625 self.r().mode_settings().read().ena().bit_is_set()
626 }
627
628 pub(super) fn apply_mode_settings(&self, settings: &ModeSettings) {
630 debug_assert!(!self.is_enabled(), "mode may only change while disabled");
631
632 self.r().mode_settings().modify(|_, w| {
633 w.bmm().bit(settings.listen_only);
636 w.rom().bit(settings.listen_only);
637 w.acf().bit(settings.listen_only);
638 w.stm().bit(settings.self_test);
639 w.ilbp().bit(settings.loopback);
640 w.fde().bit(settings.fd_enabled);
641 w.pex().bit(settings.protocol_exception);
642 w.rxbam().bit(settings.rx_auto_increment);
643 w.afm().bit(settings.filters_enabled);
644 w.tbfbo().bit(settings.bus_off_tx_fail);
645 w.fdrf().bit(settings.drop_request_frames);
646 w.tttm().bit(settings.time_triggered_tx);
647 match settings.retransmit_limit {
648 Some(limit) => {
649 w.rtrle().set_bit();
650 unsafe { w.rtrth().bits(limit) }
651 }
652 None => w.rtrle().clear_bit(),
653 }
654 });
655 }
656
657 pub(super) fn set_nominal_timing(&self, timing: &Timing) {
658 self.r().btr().write(|w| unsafe {
659 w.brp().bits(timing.baud_rate_prescaler);
660 w.prop().bits(timing.propagation_segment);
661 w.ph1().bits(timing.phase_segment_1);
662 w.ph2().bits(timing.phase_segment_2);
663 w.sjw().bits(timing.sync_jump_width)
664 });
665 }
666
667 pub(super) fn set_fd_timing(&self, timing: &Timing) {
668 self.r().btr_fd().write(|w| unsafe {
669 w.brp_fd().bits(timing.baud_rate_prescaler);
670 w.prop_fd().bits(timing.propagation_segment);
671 w.ph1_fd().bits(timing.phase_segment_1);
672 w.ph2_fd().bits(timing.phase_segment_2);
673 w.sjw_fd().bits(timing.sync_jump_width)
674 });
675 }
676
677 pub(super) fn set_secondary_sample_point(&self, source: SspSource, offset: u8) {
679 self.r().trv_delay_ssp_cfg().modify(|_, w| unsafe {
680 w.ssp_src().bits(source as u8);
681 w.ssp_offset().bits(offset)
682 });
683 }
684
685 pub(super) fn transmitter_delay(&self) -> u8 {
687 self.r().trv_delay_ssp_cfg().read().trv_delay_value().bits()
688 }
689
690 pub(super) fn tx_buffer_count(&self) -> u8 {
691 self.r()
692 .tx_command_txtb_info()
693 .read()
694 .txt_buffer_count()
695 .bits()
696 }
697
698 pub(super) fn tx_buffer_state(&self, index: u8) -> TxBufferState {
700 debug_assert!(index < self.tx_buffer_count());
701
702 let raw = self.r().tx_status().read().bits();
703 TxBufferState::from_bits(((raw >> (4 * index as u32)) & 0xF) as u8)
704 }
705
706 pub(super) fn write_tx_buffer(&self, index: u8, frame: &FrameBuffer) {
708 debug_assert!(index < 4, "the PAC models four TX buffers");
709 let regs = self.r();
710 for (i, &word) in frame.words.iter().enumerate() {
711 match index {
712 0 => regs.txtb1_data(i).write(|w| unsafe { w.data().bits(word) }),
713 1 => regs.txtb2_data(i).write(|w| unsafe { w.data().bits(word) }),
714 2 => regs.txtb3_data(i).write(|w| unsafe { w.data().bits(word) }),
715 _ => regs.txtb4_data(i).write(|w| unsafe { w.data().bits(word) }),
716 };
717 }
718 }
719
720 pub(super) fn set_tx_ready(&self, index: u8) {
721 self.tx_command(index, |w| w.txcr().set_bit());
722 }
723
724 pub(super) fn set_tx_abort(&self, index: u8) {
725 self.tx_command(index, |w| w.txca().set_bit());
726 }
727
728 pub(super) fn set_tx_empty(&self, index: u8) {
729 self.tx_command(index, |w| w.txce().set_bit());
730 }
731
732 fn tx_command<F>(&self, index: u8, cmd: F)
733 where
734 F: FnOnce(
735 &mut crate::pac::twai0::tx_command_txtb_info::W,
736 ) -> &mut crate::pac::twai0::tx_command_txtb_info::W,
737 {
738 self.r().tx_command_txtb_info().write(|w| {
739 cmd(w);
740 match index {
741 0 => w.txb1().set_bit(),
742 1 => w.txb2().set_bit(),
743 2 => w.txb3().set_bit(),
744 3 => w.txb4().set_bit(),
745 4 => w.txb5().set_bit(),
746 5 => w.txb6().set_bit(),
747 6 => w.txb7().set_bit(),
748 _ => w.txb8().set_bit(),
749 }
750 });
751 }
752
753 pub(super) fn set_tx_priority(&self, index: u8, priority: u8) {
754 self.r().tx_priority().modify(|_, w| unsafe {
755 match index {
756 0 => w.txt1p().bits(priority),
757 1 => w.txt2p().bits(priority),
758 2 => w.txt3p().bits(priority),
759 3 => w.txt4p().bits(priority),
760 4 => w.txt5p().bits(priority),
761 5 => w.txt6p().bits(priority),
762 6 => w.txt7p().bits(priority),
763 _ => w.txt8p().bits(priority),
764 }
765 });
766 }
767
768 pub(super) fn rx_buffer_size(&self) -> u16 {
770 self.r().rx_mem_info().read().rx_buff_size().bits()
771 }
772
773 pub(super) fn rx_free_words(&self) -> u16 {
775 self.r().rx_mem_info().read().rx_free().bits()
776 }
777
778 pub(super) fn rx_frame_count(&self) -> u16 {
779 self.r().rx_status_rx_settings().read().rxfrc().bits()
780 }
781
782 pub(super) fn rx_overrun(&self) -> bool {
784 self.r().status().read().dor().bit_is_set()
785 }
786
787 pub(super) fn error_warning(&self) -> bool {
789 self.r().status().read().ewl().bit_is_set()
790 }
791
792 pub(super) fn set_timestamp_point(&self, point: TimestampPoint) {
793 self.r()
794 .rx_status_rx_settings()
795 .modify(|_, w| w.rtsop().bit(point == TimestampPoint::StartOfFrame));
796 }
797
798 pub(super) fn read_rx_frame(&self) -> FrameBuffer {
800 let mut frame = FrameBuffer::new();
801 let rx_data = self.r().rx_data();
802
803 frame.words[0] = rx_data.read().bits();
804 let remaining = (frame.word_count() as usize).min(FRAME_WORDS - 1);
805 for word in frame.words[1..=remaining].iter_mut() {
806 *word = rx_data.read().bits();
807 }
808
809 frame
810 }
811
812 pub(super) fn flush_rx(&self) {
813 self.r().command().write(|w| w.rrb().set_bit());
814 }
815
816 pub(super) fn clear_overrun(&self) {
817 self.r().command().write(|w| w.cdo().set_bit());
818 }
819
820 pub(super) fn request_bus_off_recovery(&self) {
827 self.r().command().write(|w| w.ercrst().set_bit());
828 }
829
830 pub(super) fn reset_traffic_counters(&self) {
831 self.r()
832 .command()
833 .write(|w| w.rxfcrst().set_bit().txfcrst().set_bit());
834 }
835
836 pub(super) fn rec(&self) -> u16 {
837 self.r().rec_tec().read().rec_val().bits()
838 }
839
840 pub(super) fn tec(&self) -> u16 {
841 self.r().rec_tec().read().tec_val().bits()
842 }
843
844 pub(super) fn error_state(&self) -> ErrorState {
845 let r = self.r().ewl_erp_fault_state().read();
846 if r.bof().bit_is_set() {
848 ErrorState::BusOff
849 } else if r.erp().bit_is_set() {
850 ErrorState::Passive
851 } else {
852 ErrorState::Active
853 }
854 }
855
856 pub(super) fn set_error_warning_limit(&self, limit: u8) {
858 debug_assert!(self.r().mode_settings().read().tstm().bit_is_set());
859 self.r()
860 .ewl_erp_fault_state()
861 .modify(|_, w| unsafe { w.ew_limit().bits(limit) });
862 }
863
864 pub(super) fn enable_test_mode(&self, enable: bool) {
866 debug_assert!(!self.is_enabled());
867 self.r().mode_settings().modify(|_, w| w.tstm().bit(enable));
868 }
869
870 pub(super) fn enable_interrupts(&self, mask: u32) {
871 self.r().int_ena_set().write(|w| unsafe { w.bits(mask) });
872 }
873
874 pub(super) fn disable_interrupts(&self, mask: u32) {
875 self.r().int_ena_clr().write(|w| unsafe { w.bits(mask) });
876 }
877
878 pub(super) fn interrupt_status(&self) -> u32 {
879 self.r().int_stat().read().bits()
880 }
881
882 pub(super) fn clear_interrupts(&self, mask: u32) {
883 self.r().int_stat().write(|w| unsafe { w.bits(mask) });
884 }
885
886 pub(super) fn rx_traffic_counter(&self) -> u32 {
887 self.r().rx_fr_ctr().read().val().bits()
888 }
889
890 pub(super) fn tx_traffic_counter(&self) -> u32 {
891 self.r().tx_fr_ctr().read().tx_ctr_val().bits()
892 }
893
894 pub(super) fn set_mask_filter(&self, filter: MaskFilter, extended: bool, code: u32, mask: u32) {
899 let (code, mask) = if extended {
900 (code & EXT_ID_MASK, mask & EXT_ID_MASK)
901 } else {
902 (
903 (code & STD_ID_MASK) << IDENTIFIER_BASE_SHIFT,
904 (mask & STD_ID_MASK) << IDENTIFIER_BASE_SHIFT,
905 )
906 };
907
908 match filter {
909 MaskFilter::A => {
910 self.r()
911 .filter_a_mask()
912 .write(|w| unsafe { w.bit_mask_a_val().bits(mask) });
913 self.r()
914 .filter_a_val()
915 .write(|w| unsafe { w.bit_val_a_val().bits(code) });
916 }
917 MaskFilter::B => {
918 self.r()
919 .filter_b_mask()
920 .write(|w| unsafe { w.bit_mask_b_val().bits(mask) });
921 self.r()
922 .filter_b_val()
923 .write(|w| unsafe { w.bit_val_b_val().bits(code) });
924 }
925 MaskFilter::C => {
926 self.r()
927 .filter_c_mask()
928 .write(|w| unsafe { w.bit_mask_c_val().bits(mask) });
929 self.r()
930 .filter_c_val()
931 .write(|w| unsafe { w.bit_val_c_val().bits(code) });
932 }
933 }
934 }
935
936 pub(super) fn set_range_filter(&self, extended: bool, low: u32, high: u32) {
941 let (low, high) = if extended {
942 (low & EXT_ID_MASK, high & EXT_ID_MASK)
943 } else {
944 (
945 (low & STD_ID_MASK) << IDENTIFIER_BASE_SHIFT,
946 ((high & STD_ID_MASK) << IDENTIFIER_BASE_SHIFT) | 0x3FFFF,
947 )
948 };
949 self.r()
950 .filter_ran_low()
951 .write(|w| unsafe { w.bit_ran_low_val().bits(low) });
952 self.r()
953 .filter_ran_high()
954 .write(|w| unsafe { w.bit_ran_high_val().bits(high) });
955 }
956
957 pub(super) fn set_filter_kinds(
959 &self,
960 a: FrameKinds,
961 b: FrameKinds,
962 c: FrameKinds,
963 range: FrameKinds,
964 ) {
965 let bits = a.bits() | (b.bits() << 4) | (c.bits() << 8) | (range.bits() << 12);
966 self.r()
968 .filter_control_filter_status()
969 .write(|w| unsafe { w.bits(bits) });
970 }
971
972 pub(super) fn error_capture(&self) -> ErrorCapture {
973 let r = self.r().err_capt_retr_ctr_alc_ts_info().read();
974 ErrorCapture {
975 kind: BusErrorKind::from_bits(r.err_type().bits()),
976 position: ErrorPosition::from_bits(r.err_pos().bits()),
977 }
978 }
979
980 pub(super) fn retransmit_count(&self) -> u8 {
981 self.r()
982 .err_capt_retr_ctr_alc_ts_info()
983 .read()
984 .retr_ctr_val()
985 .bits()
986 }
987
988 pub(super) fn nominal_error_count(&self) -> u16 {
989 self.r().err_norm_err_fd().read().err_norm_val().bits()
990 }
991
992 pub(super) fn fd_error_count(&self) -> u16 {
993 self.r().err_norm_err_fd().read().err_fd_val().bits()
994 }
995
996 pub(super) fn timer_bit_width(&self) -> u8 {
997 self.r()
998 .err_capt_retr_ctr_alc_ts_info()
999 .read()
1000 .ts_bits()
1001 .bits()
1002 + 1
1003 }
1004
1005 pub(super) fn timer_enable_config_clock(&self, enable: bool) {
1006 self.r()
1007 .timer_clk_en()
1008 .modify(|_, w| w.clk_en().bit(enable));
1009 }
1010
1011 pub(super) fn timer_enable(&self, enable: bool) {
1012 self.r().timer_cfg().modify(|_, w| w.timer_ce().bit(enable));
1013 }
1014
1015 pub(super) fn timer_count_up(&self, up: bool) {
1016 self.r().timer_cfg().modify(|_, w| w.timer_up_dn().bit(up));
1017 }
1018
1019 pub(super) fn timer_set_divider(&self, divider: u16) {
1024 debug_assert!(divider >= 1);
1025 self.r()
1026 .timer_cfg()
1027 .modify(|_, w| unsafe { w.timer_step().bits(divider - 1) });
1028 }
1029
1030 pub(super) fn timer_clear(&self) {
1031 self.r().timer_cfg().modify(|_, w| w.timer_clr().set_bit());
1032 }
1033
1034 pub(super) fn timer_set_free_running(&self) {
1036 self.r()
1037 .timer_ld_val_l()
1038 .write(|w| unsafe { w.timer_ld_val_l().bits(0) });
1039 self.r()
1040 .timer_ld_val_h()
1041 .write(|w| unsafe { w.timer_ld_val_h().bits(0) });
1042 self.r()
1043 .timer_ct_val_l()
1044 .write(|w| unsafe { w.timer_ct_val_l().bits(u32::MAX) });
1045 self.r()
1046 .timer_ct_val_h()
1047 .write(|w| unsafe { w.timer_ct_val_h().bits(u32::MAX) });
1048 }
1049
1050 pub(super) fn timer_count(&self) -> u64 {
1051 loop {
1053 let high = self.r().timestamp_high().read().bits();
1054 let low = self.r().timestamp_low().read().bits();
1055 if self.r().timestamp_high().read().bits() == high {
1056 return ((high as u64) << 32) | low as u64;
1057 }
1058 }
1059 }
1060}