Skip to main content

esp_hal/canfd/
ll.rs

1//! Low-level register access for the CTU CAN FD core.
2//!
3//! Ported from ESP-IDF's [`twaifd_ll.h`](https://github.com/espressif/esp-idf/blob/96f54947e08c196cf71c0588243dfc8e33807acc/components/esp_hal_twai/esp32c5/include/hal/twaifd_ll.h).
4//! "TRM" below means the ESP32-C5 TRM v1.1, chapter 38.
5
6use 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
14/// Words in a frame buffer: 1 format + 1 identifier + 2 timestamp + 16 data.
15pub(super) const FRAME_WORDS: usize = 20;
16/// Largest data length code of CAN FD.
17pub(super) const MAX_DLC: u8 = 15;
18/// Largest payload of a CAN FD frame, in bytes.
19pub(super) const MAX_DATA_LEN: usize = 64;
20/// Largest payload of a classic CAN frame, in bytes.
21pub(super) const CLASSIC_MAX_DATA_LEN: usize = 8;
22
23/// Mask of the 11-bit base identifier.
24pub(super) const STD_ID_MASK: u32 = 0x0000_07FF;
25/// Mask of the 29-bit extended identifier.
26pub(super) const EXT_ID_MASK: u32 = 0x1FFF_FFFF;
27/// Bit position of the base identifier inside the identifier word.
28const IDENTIFIER_BASE_SHIFT: u32 = 18;
29
30/// Largest value a register field of `width` bits can hold.
31const fn field_max(width: u8) -> u8 {
32    ((1u16 << width) - 1) as u8
33}
34
35/// Largest retransmission limit the `RTRTH` field can hold.
36pub const MAX_RETRANSMIT_LIMIT: u8 = field_max(<RTRTH_W<'static, MODE_SETTINGS_SPEC>>::WIDTH);
37
38/// Largest TX buffer priority the `TXTnP` fields can hold.
39pub const MAX_TX_PRIORITY: u8 = field_max(<TXT1P_W<'static, TX_PRIORITY_SPEC>>::WIDTH);
40
41/// Hardware limits for one set of bit timing parameters.
42///
43/// The maxima are the register field widths from TRM 38.7; the minima come from
44/// ESP-IDF's `twaifd_ll.h`.
45#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
46#[cfg_attr(feature = "defmt", derive(defmt::Format))]
47pub struct TimingLimits {
48    /// Smallest value of each parameter, included.
49    pub min: Timing,
50    /// Largest value of each parameter, included.
51    pub max: Timing,
52}
53
54/// Limits for the nominal (arbitration phase) bit timing.
55pub 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
72/// Limits for the data phase bit timing.
73pub 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/// Bit timing parameters for one phase (nominal or data).
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
92#[cfg_attr(feature = "defmt", derive(defmt::Format))]
93pub struct Timing {
94    /// Bit rate prescaler. Divides the function clock to produce the time quantum.
95    pub baud_rate_prescaler: u8,
96    /// Propagation segment, in time quanta.
97    pub propagation_segment: u8,
98    /// Phase segment 1, in time quanta.
99    pub phase_segment_1: u8,
100    /// Phase segment 2, in time quanta.
101    pub phase_segment_2: u8,
102    /// Synchronization jump width, in time quanta.
103    pub sync_jump_width: u8,
104}
105
106impl Timing {
107    /// Returns whether every parameter fits the given limits.
108    ///
109    /// Also checks the two constraints of TRM 38.3.7.7, which are expressed in
110    /// system clock periods and therefore include the prescaler.
111    pub const fn is_valid(&self, limits: &TimingLimits) -> bool {
112        // Phase_Seg2 >= 2 minimal time quanta.
113        if (self.baud_rate_prescaler as u32) * (self.phase_segment_2 as u32) < 2 {
114            return false;
115        }
116        // Sync_Seg + Prop_Seg + Phase_Seg1 > 2 minimal time quanta.
117        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    /// Returns the total bit time in time quanta, including the sync segment.
138    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    /// Returns the bit rate in bits per second for a given function clock.
145    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    /// Returns the sample point in per mille of the bit time.
150    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/// Source used to place the secondary sample point (TRM 38.3.7.3).
157#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
158#[cfg_attr(feature = "defmt", derive(defmt::Format))]
159#[repr(u8)]
160pub enum SspSource {
161    /// Measured transmitter delay plus the configured offset.
162    MeasuredPlusOffset = 0,
163    /// Secondary sampling is disabled.
164    Disabled           = 1,
165    /// The configured offset alone. Not used by the driver.
166    #[allow(dead_code)]
167    OffsetOnly         = 2,
168}
169
170/// State of a single TX buffer (TRM figure 38.3-8).
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
172#[cfg_attr(feature = "defmt", derive(defmt::Format))]
173pub enum TxBufferState {
174    /// The buffer is not implemented by this core.
175    NotExist,
176    /// Armed for transmission.
177    Ready,
178    /// Currently being transmitted.
179    InProgress,
180    /// Abort requested while a transmission was in progress.
181    AbortInProgress,
182    /// Last transmission succeeded.
183    Ok,
184    /// Last transmission failed.
185    Failed,
186    /// Last transmission was aborted.
187    Aborted,
188    /// Ready to be filled by software.
189    Empty,
190    /// Hardware reported a state this driver does not model.
191    Unknown(u8),
192}
193
194impl TxBufferState {
195    fn from_bits(bits: u8) -> Self {
196        // Codes from TRM 38.22; ESP-IDF's header only names 0x4/0x6/0x7.
197        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    /// Returns whether software can write to a buffer in this state (TRM 38.3.8).
211    pub fn is_writable(self) -> bool {
212        matches!(self, Self::Empty | Self::Ok | Self::Failed | Self::Aborted)
213    }
214}
215
216/// Fault confinement state (TRM 38.3.10).
217///
218/// The error warning limit is not a state of its own; see
219/// [`super::CanFd::error_warning`].
220#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
221#[cfg_attr(feature = "defmt", derive(defmt::Format))]
222pub enum ErrorState {
223    /// Takes part in the bus normally and signals errors actively.
224    Active,
225    /// Still communicates, but signals errors passively.
226    Passive,
227    /// Off the bus after TEC passed 255.
228    BusOff,
229}
230
231/// Point in the frame at which a received frame is timestamped.
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233#[cfg_attr(feature = "defmt", derive(defmt::Format))]
234#[repr(u8)]
235pub enum TimestampPoint {
236    /// Sixth bit of the end-of-frame field, when the frame becomes valid.
237    EndOfFrame   = 0,
238    /// Start-of-frame bit.
239    StartOfFrame = 1,
240}
241
242/// Every bit of `MODE_SETTINGS` the driver configures, applied in one write.
243#[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    /// Retransmission attempts, or `None` to retry forever.
256    pub retransmit_limit: Option<u8>,
257}
258
259/// One of the three mask filter instances.
260#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
261#[cfg_attr(feature = "defmt", derive(defmt::Format))]
262pub enum MaskFilter {
263    /// Filter A.
264    A,
265    /// Filter B.
266    B,
267    /// Filter C.
268    C,
269}
270
271/// Frame formats a filter accepts.
272#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
273#[cfg_attr(feature = "defmt", derive(defmt::Format))]
274pub enum FrameFormats {
275    /// Classic CAN frames only.
276    Classic,
277    /// CAN FD frames only.
278    Fd,
279    /// Both classic CAN and CAN FD frames.
280    #[default]
281    Both,
282}
283
284/// Which kinds of frame a filter accepts, as the hardware encodes it.
285///
286/// A filter with none of these set is disabled (TRM 38.3.9.8).
287#[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    /// Accepts every kind of frame.
297    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    /// Accepts nothing, which disables the filter.
305    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    /// Accepts the given frame formats, with identifiers of one format only.
313    ///
314    /// The identifier format decides between base and extended, and only
315    /// classic and FD vary, as in ESP-IDF's
316    /// [`twai_hal_configure_mask_filter`](https://github.com/espressif/esp-idf/blob/96f54947e08c196cf71c0588243dfc8e33807acc/components/esp_hal_twai/twai_hal_v2.c#L118-L131).
317    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/// Reason the core last flagged a bus error (TRM 38.3.13.1).
337#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
338#[cfg_attr(feature = "defmt", derive(defmt::Format))]
339pub enum BusErrorKind {
340    /// The transmitted bit did not match the bit sampled back.
341    Bit,
342    /// The frame's CRC did not match.
343    Crc,
344    /// A fixed-form field held an illegal value.
345    Form,
346    /// No node acknowledged the frame.
347    Ack,
348    /// A stuffing rule was violated.
349    Stuff,
350    /// Hardware reported a code this driver does not model.
351    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/// Where in a frame the core last flagged an error (TRM 38.3.13.1).
368#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
369#[cfg_attr(feature = "defmt", derive(defmt::Format))]
370pub enum ErrorPosition {
371    /// Start of frame.
372    StartOfFrame,
373    /// Arbitration field.
374    Arbitration,
375    /// Control field.
376    Control,
377    /// Data field.
378    Data,
379    /// CRC field.
380    Crc,
381    /// CRC delimiter, ACK field or ACK delimiter.
382    Ack,
383    /// End-of-frame field.
384    EndOfFrame,
385    /// During an error frame.
386    ErrorFrame,
387    /// During an overload frame.
388    OverloadFrame,
389    /// Somewhere else. Also what the register reads out of reset.
390    Other,
391    /// Hardware reported a code this driver does not model.
392    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/// Details of the last bus error the core captured.
414///
415/// The registers behind this are not cleared, so the value is only meaningful
416/// after a bus error. Out of reset it reads as [`BusErrorKind::Bit`] at
417/// [`ErrorPosition::Other`].
418#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
419#[cfg_attr(feature = "defmt", derive(defmt::Format))]
420pub struct ErrorCapture {
421    /// What went wrong.
422    pub kind: BusErrorKind,
423    /// Where in the frame it happened.
424    pub position: ErrorPosition,
425}
426
427/// The format and identifier fields of a frame to transmit.
428#[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/// A frame in the layout the hardware TX and RX buffers use.
438///
439/// Word 0 is the format word, word 1 the identifier, words 2 and 3 the
440/// timestamp, and words 4..20 the payload.
441#[derive(Clone, Copy, PartialEq, Eq)]
442pub(super) struct FrameBuffer {
443    words: [u32; FRAME_WORDS],
444}
445
446// The payload is viewed as bytes in place, which relies on the word layout
447// matching the wire order.
448const _: () = 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    /// Number of words that follow word 0 for this frame.
484    ///
485    /// The RWCNT field. ESP-IDF's `twaifd_struct.h` mislabels it as a
486    /// retransmission counter; its own RX loop uses it as a word count.
487    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            // Masked to the field width, so the value is always in range.
494            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    /// Returns the payload length in bytes.
506    ///
507    /// Only CAN FD frames use the extended data length codes; a classic frame
508    /// with a DLC above 8 still carries 8 bytes. A request frame carries none.
509    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    /// Returns the payload length a request frame asks for, in bytes.
522    pub(super) fn requested_len(&self) -> usize {
523        (dlc_to_len(self.dlc()) as usize).min(CLASSIC_MAX_DATA_LEN)
524    }
525
526    /// Returns the payload.
527    pub(super) fn data(&self) -> &[u8] {
528        let words = &self.words[Self::DATA_WORD_OFFSET..];
529        // Little-endian words hold the payload in wire order, checked above.
530        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    /// Builds a frame buffer ready to be written to a TX buffer.
536    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        // Words 2 and 3 are the trigger time; zero transmits as soon as the
554        // bus is idle (TRM 38.3.8.2).
555
556        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
564/// Converts a data length code to a payload length in bytes.
565pub(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
575/// Converts a payload length in bytes to the smallest data length code that
576/// can carry it.
577pub(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
587/// Register access for one CAN FD controller.
588pub(super) struct Driver {
589    regs: *const RegisterBlock,
590}
591
592// The pointer addresses a memory-mapped register block.
593unsafe 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    /// IP core version as `(major, minor)`.
610    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    /// Issues a soft reset. No wait is required afterwards (TRM 38.3.2).
616    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    /// Applies every mode setting in one write. Only valid while disabled.
629    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            // Listen-only needs `rom` and `acf` alongside `bmm` on the
634            // ESP32-C5 (errata 0v2 issue 5, esp-idf#17461).
635            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    /// Places the secondary sample point. `offset` is in function clock cycles.
678    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    /// Transmitter delay measured by the hardware, in function clock cycles.
686    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    /// State of one TX buffer. `index` must be below [`Self::tx_buffer_count`].
699    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    /// Writes a frame into a TX buffer, which must be writable.
707    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    /// Size of the RX buffer, in 32-bit words.
769    pub(super) fn rx_buffer_size(&self) -> u16 {
770        self.r().rx_mem_info().read().rx_buff_size().bits()
771    }
772
773    /// Free space in the RX buffer, in 32-bit words.
774    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    /// Whether the RX buffer has dropped a frame for lack of space (TRM 38.3.9.4).
783    pub(super) fn rx_overrun(&self) -> bool {
784        self.r().status().read().dor().bit_is_set()
785    }
786
787    /// Whether an error counter has reached the error warning limit.
788    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    /// Reads one frame out of the RX buffer. Requires RX auto-increment mode.
799    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    /// Requests error counter reset, which is how a bus-off node rejoins.
821    ///
822    /// TRM register 38.3 says this has no effect outside bus-off. Measured on an
823    /// ESP32-C5, a request made while error-active is remembered and
824    /// reintegrates the controller the next time it goes bus-off, so callers
825    /// must check the state themselves.
826    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        // More than one bit can be set while a transition settles.
847        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    /// Sets the error warning limit. Only writable in test mode (TRM 38.3.10).
857    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    /// Enables test mode. Only valid while the controller is disabled.
865    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    /// Sets a mask filter's acceptance code and mask.
895    ///
896    /// The identifier word holds a base identifier in bits 28..18 and an
897    /// extended one in bits 28..0 (TRM 38.3.9.9).
898    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    /// Sets the identifier range the range filter accepts.
937    ///
938    /// For a base identifier range the low 18 bits of the upper bound are set,
939    /// so the whole base identifier is covered (TRM 38.3.9.10).
940    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    /// Sets which frame kinds each filter accepts.
958    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        // The upper half of the register is read-only status.
967        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    /// Sets the timer prescaler to `divider` function clock cycles per tick.
1020    ///
1021    /// TRM 38.13 describes `TIMER_STEP` as a count step; measured on an
1022    /// ESP32-C5 it is a divider of `TIMER_STEP + 1`.
1023    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    /// Makes the counter free-running over its whole width (TRM 38.14 to 38.17).
1035    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        // Re-read the high word if the low word wrapped between the reads.
1052        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}