bxcan_ng/
lib.rs

1//! Driver for the STM32 bxCAN peripheral.
2//!
3//! This crate provides a reusable driver for the bxCAN peripheral found in many low- to middle-end
4//! STM32 microcontrollers. HALs for compatible chips can reexport this crate and implement its
5//! traits to easily expose a featureful CAN driver.
6//!
7//! # Features
8//!
9//! - Supports both single- and dual-peripheral configurations (where one bxCAN instance manages the
10//!   filters of a secondary instance).
11//! - Handles standard and extended frames, and data and remote frames.
12//! - Support for interrupts emitted by the bxCAN peripheral.
13//! - Transmission respects CAN IDs and protects against priority inversion (a lower-priority frame
14//!   may be dequeued when enqueueing a higher-priority one).
15//! - Implements the [`embedded-hal`] traits for interoperability.
16//! - Support for both RX FIFOs (as [`Rx0`] and [`Rx1`]).
17//!
18//! # Limitations
19//!
20//! - Support for querying error states and handling error interrupts is incomplete.
21//!
22//! # Cargo Features
23//!
24//! | Feature | Description |
25//! |---------|-------------|
26//! | `unstable-defmt` | Implements [`defmt`]'s `Format` trait for the types in this crate.[^1] |
27//!
28//! [^1]: The specific version of defmt is unspecified and may be updated in a patch release.
29//!
30//! [`defmt`]: https://docs.rs/defmt
31//! [`embedded-hal`]: https://docs.rs/embedded-hal
32
33#![doc(html_root_url = "https://docs.rs/bxcan/0.8.0")]
34// Deny a few warnings in doctests, since rustdoc `allow`s many warnings by default
35#![doc(test(attr(deny(unused_imports, unused_must_use))))]
36#![no_std]
37#![allow(clippy::unnecessary_operation)] // lint is bugged
38
39mod embedded_can;
40#[cfg(feature = "embedded-hal-02")]
41mod embedded_hal;
42pub mod filter;
43mod frame;
44mod id;
45mod interrupt;
46
47#[allow(clippy::all)] // generated code
48mod pac;
49
50pub use id::{ExtendedId, Id, StandardId};
51
52pub use crate::frame::{Data, Frame, FramePriority};
53pub use crate::interrupt::{Interrupt, Interrupts};
54pub use crate::pac::can::RegisterBlock;
55
56use crate::filter::MasterFilters;
57use core::cmp::{Ord, Ordering};
58use core::convert::{Infallible, TryInto};
59use core::marker::PhantomData;
60use core::mem;
61use core::ptr::NonNull;
62
63use self::pac::generic::*; // To make the PAC extraction build
64
65/// A bxCAN peripheral instance.
66///
67/// This trait is meant to be implemented for a HAL-specific type that represent ownership of
68/// the CAN peripheral (and any pins required by it, although that is entirely up to the HAL).
69///
70/// # Safety
71///
72/// It is only safe to implement this trait, when:
73///
74/// * The implementing type has ownership of the peripheral, preventing any other accesses to the
75///   register block.
76/// * `REGISTERS` is a pointer to that peripheral's register block and can be safely accessed for as
77///   long as ownership or a borrow of the implementing type is present.
78pub unsafe trait Instance {
79    /// Pointer to the instance's register block.
80    const REGISTERS: *mut RegisterBlock;
81}
82
83/// A bxCAN instance that owns filter banks.
84///
85/// In master-slave-instance setups, only the master instance owns the filter banks, and needs to
86/// split some of them off for use by the slave instance. In that case, the master instance should
87/// implement [`FilterOwner`] and [`MasterInstance`], while the slave instance should only implement
88/// [`Instance`].
89///
90/// In single-instance configurations, the instance owns all filter banks and they can not be split
91/// off. In that case, the instance should implement [`Instance`] and [`FilterOwner`].
92///
93/// # Safety
94///
95/// This trait must only be implemented if the instance does, in fact, own its associated filter
96/// banks, and `NUM_FILTER_BANKS` must be correct.
97pub unsafe trait FilterOwner: Instance {
98    /// The total number of filter banks available to the instance.
99    ///
100    /// This is usually either 14 or 28, and should be specified in the chip's reference manual or
101    /// datasheet.
102    const NUM_FILTER_BANKS: u8;
103}
104
105/// A bxCAN master instance that shares filter banks with a slave instance.
106///
107/// In master-slave-instance setups, this trait should be implemented for the master instance.
108///
109/// # Safety
110///
111/// This trait must only be implemented when there is actually an associated slave instance.
112pub unsafe trait MasterInstance: FilterOwner {}
113
114/// Enum of error status codes from the error status register.
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
117pub enum Error {
118    None,
119    Stuff,
120    Form,
121    Acknowledgement,
122    BitRecessive,
123    BitDominant,
124    Crc,
125    Software,
126}
127
128/// The peripheral's current error status.
129#[derive(Clone, PartialEq, Eq)]
130#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
131pub struct ErrorStatus {
132    pub(crate) recv_count: u8,
133    pub(crate) txmt_count: u8,
134    pub(crate) code: Error,
135    pub(crate) bus_off: bool,
136    pub(crate) err_passive: bool,
137    pub(crate) err_warning: bool,
138}
139
140impl ErrorStatus {
141    /// The receive error counter.
142    #[inline]
143    pub fn receive_counter(&self) -> u8 {
144        self.recv_count
145    }
146
147    /// The transmit error counter.
148    #[inline]
149    pub fn transmit_counter(&self) -> u8 {
150        self.recv_count
151    }
152
153    /// The last error code.
154    #[inline]
155    pub fn last_error(&self) -> Error {
156        self.code
157    }
158
159    /// Returns true if the peripheral is currently in bus-off.
160    ///
161    /// This occurs when the transmit error counter overflows past 255.
162    #[inline]
163    pub fn bus_off(&self) -> bool {
164        self.bus_off
165    }
166
167    /// Returns true if the error passive limit has been reached.
168    ///
169    /// This occurs when the receive or transmit error counters exceed 127.
170    #[inline]
171    pub fn error_passive(&self) -> bool {
172        self.err_passive
173    }
174
175    /// Returns true if the error warning limit has been reached.
176    ///
177    /// This occurs when the receive or transmit error counters are greater than or equal 96.
178    #[inline]
179    pub fn error_warning(&self) -> bool {
180        self.err_warning
181    }
182}
183
184/// Error that indicates that an incoming message has been lost due to buffer overrun.
185#[derive(Debug, Clone, Copy, PartialEq, Eq)]
186#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
187pub struct OverrunError {
188    _priv: (),
189}
190
191/// Identifier of a CAN message.
192///
193/// Can be either a standard identifier (11bit, Range: 0..0x3FF) or a
194/// extendended identifier (29bit , Range: 0..0x1FFFFFFF).
195///
196/// The `Ord` trait can be used to determine the frame’s priority this ID
197/// belongs to.
198/// Lower identifier values have a higher priority. Additionally standard frames
199/// have a higher priority than extended frames and data frames have a higher
200/// priority than remote frames.
201#[derive(Clone, Copy, Debug, PartialEq, Eq)]
202#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
203struct IdReg(u32);
204
205impl IdReg {
206    const STANDARD_SHIFT: u32 = 21;
207
208    const EXTENDED_SHIFT: u32 = 3;
209
210    const IDE_MASK: u32 = 0x0000_0004;
211
212    const RTR_MASK: u32 = 0x0000_0002;
213
214    /// Creates a new standard identifier (11bit, Range: 0..0x7FF)
215    ///
216    /// Panics for IDs outside the allowed range.
217    fn new_standard(id: StandardId) -> Self {
218        Self(u32::from(id.as_raw()) << Self::STANDARD_SHIFT)
219    }
220
221    /// Creates a new extendended identifier (29bit , Range: 0..0x1FFFFFFF).
222    ///
223    /// Panics for IDs outside the allowed range.
224    fn new_extended(id: ExtendedId) -> IdReg {
225        Self(id.as_raw() << Self::EXTENDED_SHIFT | Self::IDE_MASK)
226    }
227
228    fn from_register(reg: u32) -> IdReg {
229        Self(reg & 0xFFFF_FFFE)
230    }
231
232    /// Sets the remote transmission (RTR) flag. This marks the identifier as
233    /// being part of a remote frame.
234    #[must_use = "returns a new IdReg without modifying `self`"]
235    fn with_rtr(self, rtr: bool) -> IdReg {
236        if rtr {
237            Self(self.0 | Self::RTR_MASK)
238        } else {
239            Self(self.0 & !Self::RTR_MASK)
240        }
241    }
242
243    /// Returns the identifier.
244    fn to_id(self) -> Id {
245        if self.is_extended() {
246            Id::Extended(unsafe { ExtendedId::new_unchecked(self.0 >> Self::EXTENDED_SHIFT) })
247        } else {
248            Id::Standard(unsafe {
249                StandardId::new_unchecked((self.0 >> Self::STANDARD_SHIFT) as u16)
250            })
251        }
252    }
253
254    /// Returns `true` if the identifier is an extended identifier.
255    fn is_extended(self) -> bool {
256        self.0 & Self::IDE_MASK != 0
257    }
258
259    /// Returns `true` if the identifier is a standard identifier.
260    fn is_standard(self) -> bool {
261        !self.is_extended()
262    }
263
264    /// Returns `true` if the identifer is part of a remote frame (RTR bit set).
265    fn rtr(self) -> bool {
266        self.0 & Self::RTR_MASK != 0
267    }
268}
269
270/// `IdReg` is ordered by priority.
271impl Ord for IdReg {
272    fn cmp(&self, other: &Self) -> Ordering {
273        // When the IDs match, data frames have priority over remote frames.
274        let rtr = self.rtr().cmp(&other.rtr()).reverse();
275
276        let id_a = self.to_id();
277        let id_b = other.to_id();
278        match (id_a, id_b) {
279            (Id::Standard(a), Id::Standard(b)) => {
280                // Lower IDs have priority over higher IDs.
281                a.as_raw().cmp(&b.as_raw()).reverse().then(rtr)
282            }
283            (Id::Extended(a), Id::Extended(b)) => a.as_raw().cmp(&b.as_raw()).reverse().then(rtr),
284            (Id::Standard(a), Id::Extended(b)) => {
285                // Standard frames have priority over extended frames if their Base IDs match.
286                a.as_raw()
287                    .cmp(&b.standard_id().as_raw())
288                    .reverse()
289                    .then(Ordering::Greater)
290            }
291            (Id::Extended(a), Id::Standard(b)) => a
292                .standard_id()
293                .as_raw()
294                .cmp(&b.as_raw())
295                .reverse()
296                .then(Ordering::Less),
297        }
298    }
299}
300
301impl PartialOrd for IdReg {
302    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
303        Some(self.cmp(other))
304    }
305}
306
307/// Configuration proxy returned by [`Can::modify_config`].
308#[must_use = "`CanConfig` leaves the peripheral in uninitialized state, call `CanConfig::enable` or explicitly drop the value"]
309pub struct CanConfig<'a, I: Instance> {
310    can: &'a mut Can<I>,
311}
312
313impl<I: Instance> CanConfig<'_, I> {
314    /// Configures the bit timings.
315    ///
316    /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter
317    /// parameters as follows:
318    ///
319    /// - *Clock Rate*: The input clock speed to the CAN peripheral (*not* the CPU clock speed).
320    ///   This is the clock rate of the peripheral bus the CAN peripheral is attached to (eg. APB1).
321    /// - *Sample Point*: Should normally be left at the default value of 87.5%.
322    /// - *SJW*: Should normally be left at the default value of 1.
323    ///
324    /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr`
325    /// parameter to this method.
326    pub fn set_bit_timing(self, btr: u32) -> Self {
327        self.can.set_bit_timing(btr);
328        self
329    }
330
331    /// Enables or disables loopback mode: Internally connects the TX and RX
332    /// signals together.
333    pub fn set_loopback(self, enabled: bool) -> Self {
334        let can = self.can.registers();
335        can.btr.modify(|_, w| w.lbkm().bit(enabled));
336        self
337    }
338
339    /// Enables or disables silent mode: Disconnects the TX signal from the pin.
340    pub fn set_silent(self, enabled: bool) -> Self {
341        let can = self.can.registers();
342        can.btr.modify(|_, w| w.silm().bit(enabled));
343        self
344    }
345
346    /// Enables or disables automatic retransmission of messages.
347    ///
348    /// If this is enabled, the CAN peripheral will automatically try to retransmit each frame
349    /// until it can be sent. Otherwise, it will try only once to send each frame.
350    ///
351    /// Automatic retransmission is enabled by default.
352    pub fn set_automatic_retransmit(self, enabled: bool) -> Self {
353        let can = self.can.registers();
354        can.mcr.modify(|_, w| w.nart().bit(!enabled));
355        self
356    }
357
358    /// Leaves initialization mode and enables the peripheral.
359    ///
360    /// To sync with the CAN bus, this will block until 11 consecutive recessive bits are detected
361    /// on the bus.
362    ///
363    /// If you want to finish configuration without enabling the peripheral, you can call
364    /// [`CanConfig::leave_disabled`] or [`drop`] the [`CanConfig`] instead.
365    pub fn enable(mut self) {
366        self.leave_init_mode();
367
368        match nb::block!(self.can.enable_non_blocking()) {
369            Ok(()) => {}
370            Err(void) => match void {},
371        }
372
373        // Don't run the destructor.
374        mem::forget(self);
375    }
376
377    /// Leaves initialization mode, but keeps the peripheral in sleep mode.
378    ///
379    /// Before the [`Can`] instance can be used, you have to enable it by calling
380    /// [`Can::enable_non_blocking`].
381    pub fn leave_disabled(mut self) {
382        self.leave_init_mode();
383    }
384
385    /// Leaves initialization mode, enters sleep mode.
386    fn leave_init_mode(&mut self) {
387        let can = self.can.registers();
388        can.mcr
389            .modify(|_, w| w.sleep().set_bit().inrq().clear_bit());
390        loop {
391            let msr = can.msr.read();
392            if msr.slak().bit_is_set() && msr.inak().bit_is_clear() {
393                break;
394            }
395        }
396    }
397}
398
399impl<I: Instance> Drop for CanConfig<'_, I> {
400    #[inline]
401    fn drop(&mut self) {
402        self.leave_init_mode();
403    }
404}
405
406/// Builder returned by [`Can::builder`].
407#[must_use = "`CanBuilder` leaves the peripheral in uninitialized state, call `CanBuilder::enable` or `CanBuilder::leave_disabled`"]
408pub struct CanBuilder<I: Instance> {
409    can: Can<I>,
410}
411
412impl<I: Instance> CanBuilder<I> {
413    /// Configures the bit timings.
414    ///
415    /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter
416    /// parameters as follows:
417    ///
418    /// - *Clock Rate*: The input clock speed to the CAN peripheral (*not* the CPU clock speed).
419    ///   This is the clock rate of the peripheral bus the CAN peripheral is attached to (eg. APB1).
420    /// - *Sample Point*: Should normally be left at the default value of 87.5%.
421    /// - *SJW*: Should normally be left at the default value of 1.
422    ///
423    /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr`
424    /// parameter to this method.
425    pub fn set_bit_timing(mut self, btr: u32) -> Self {
426        self.can.set_bit_timing(btr);
427        self
428    }
429
430    /// Enables or disables loopback mode: Internally connects the TX and RX
431    /// signals together.
432    pub fn set_loopback(self, enabled: bool) -> Self {
433        let can = self.can.registers();
434        can.btr.modify(|_, w| w.lbkm().bit(enabled));
435        self
436    }
437
438    /// Enables or disables silent mode: Disconnects the TX signal from the pin.
439    pub fn set_silent(self, enabled: bool) -> Self {
440        let can = self.can.registers();
441        can.btr.modify(|_, w| w.silm().bit(enabled));
442        self
443    }
444
445    /// Enables or disables automatic retransmission of messages.
446    ///
447    /// If this is enabled, the CAN peripheral will automatically try to retransmit each frame
448    /// until it can be sent. Otherwise, it will try only once to send each frame.
449    ///
450    /// Automatic retransmission is enabled by default.
451    pub fn set_automatic_retransmit(self, enabled: bool) -> Self {
452        let can = self.can.registers();
453        can.mcr.modify(|_, w| w.nart().bit(!enabled));
454        self
455    }
456
457    /// Leaves initialization mode and enables the peripheral.
458    ///
459    /// To sync with the CAN bus, this will block until 11 consecutive recessive bits are detected
460    /// on the bus.
461    ///
462    /// If you want to finish configuration without enabling the peripheral, you can call
463    /// [`CanBuilder::leave_disabled`] instead.
464    pub fn enable(mut self) -> Can<I> {
465        self.leave_init_mode();
466
467        match nb::block!(self.can.enable_non_blocking()) {
468            Ok(()) => self.can,
469            Err(void) => match void {},
470        }
471    }
472
473    /// Returns the [`Can`] interface without enabling it.
474    ///
475    /// This leaves initialization mode, but keeps the peripheral in sleep mode instead of enabling
476    /// it.
477    ///
478    /// Before the [`Can`] instance can be used, you have to enable it by calling
479    /// [`Can::enable_non_blocking`].
480    pub fn leave_disabled(mut self) -> Can<I> {
481        self.leave_init_mode();
482        self.can
483    }
484
485    /// Leaves initialization mode, enters sleep mode.
486    fn leave_init_mode(&mut self) {
487        let can = self.can.registers();
488        can.mcr
489            .modify(|_, w| w.sleep().set_bit().inrq().clear_bit());
490        loop {
491            let msr = can.msr.read();
492            if msr.slak().bit_is_set() && msr.inak().bit_is_clear() {
493                break;
494            }
495        }
496    }
497}
498
499/// Interface to a bxCAN peripheral.
500pub struct Can<I: Instance> {
501    instance: I,
502}
503
504impl<I> Can<I>
505where
506    I: Instance,
507{
508    /// Creates a [`CanBuilder`] for constructing a CAN interface.
509    pub fn builder(instance: I) -> CanBuilder<I> {
510        let can_builder = CanBuilder {
511            can: Can { instance },
512        };
513
514        let can_reg = can_builder.can.registers();
515        // Enter init mode.
516        can_reg
517            .mcr
518            .modify(|_, w| w.sleep().clear_bit().inrq().set_bit());
519        loop {
520            let msr = can_reg.msr.read();
521            if msr.slak().bit_is_clear() && msr.inak().bit_is_set() {
522                break;
523            }
524        }
525
526        can_builder
527    }
528
529    fn registers(&self) -> &RegisterBlock {
530        unsafe { &*I::REGISTERS }
531    }
532
533    fn set_bit_timing(&mut self, btr: u32) {
534        // Mask of all non-reserved BTR bits, except the mode flags.
535        const MASK: u32 = 0x037F_03FF;
536
537        let can = self.registers();
538        can.btr.modify(|r, w| unsafe {
539            let mode_bits = r.bits() & 0xC000_0000;
540            w.bits(mode_bits | (btr & MASK))
541        });
542    }
543
544    /// Returns a reference to the peripheral instance.
545    ///
546    /// This allows accessing HAL-specific data stored in the instance type.
547    pub fn instance(&mut self) -> &mut I {
548        &mut self.instance
549    }
550
551    /// Disables the CAN interface and returns back the raw peripheral it was created from.
552    ///
553    /// The peripheral is disabled by setting `RESET` in `CAN_MCR`, which causes the peripheral to
554    /// enter sleep mode.
555    pub fn free(self) -> I {
556        self.registers().mcr.write(|w| w.reset().set_bit());
557        self.instance
558    }
559
560    /// Configure bit timings and silent/loop-back mode.
561    ///
562    /// Calling this method will enter initialization mode.
563    pub fn modify_config(&mut self) -> CanConfig<'_, I> {
564        let can = self.registers();
565
566        // Enter init mode.
567        can.mcr
568            .modify(|_, w| w.sleep().clear_bit().inrq().set_bit());
569        loop {
570            let msr = can.msr.read();
571            if msr.slak().bit_is_clear() && msr.inak().bit_is_set() {
572                break;
573            }
574        }
575
576        CanConfig { can: self }
577    }
578
579    /// Configures the automatic wake-up feature.
580    ///
581    /// This is turned off by default.
582    ///
583    /// When turned on, an incoming frame will cause the peripheral to wake up from sleep and
584    /// receive the frame. If enabled, [`Interrupt::Wakeup`] will also be triggered by the incoming
585    /// frame.
586    pub fn set_automatic_wakeup(&mut self, enabled: bool) {
587        let can = self.registers();
588        can.mcr.modify(|_, w| w.awum().bit(enabled));
589    }
590
591    /// Leaves initialization mode and enables the peripheral (non-blocking version).
592    ///
593    /// Usually, it is recommended to call [`CanConfig::enable`] instead. This method is only needed
594    /// if you want non-blocking initialization.
595    ///
596    /// If this returns [`WouldBlock`][nb::Error::WouldBlock], the peripheral will enable itself
597    /// in the background. The peripheral is enabled and ready to use when this method returns
598    /// successfully.
599    pub fn enable_non_blocking(&mut self) -> nb::Result<(), Infallible> {
600        let can = self.registers();
601        let msr = can.msr.read();
602        if msr.slak().bit_is_set() {
603            can.mcr
604                .modify(|_, w| w.abom().set_bit().sleep().clear_bit());
605            Err(nb::Error::WouldBlock)
606        } else {
607            Ok(())
608        }
609    }
610
611    /// Puts the peripheral in a sleep mode to save power.
612    ///
613    /// While in sleep mode, an incoming CAN frame will trigger [`Interrupt::Wakeup`] if enabled.
614    pub fn sleep(&mut self) {
615        let can = self.registers();
616        can.mcr
617            .modify(|_, w| w.sleep().set_bit().inrq().clear_bit());
618        loop {
619            let msr = can.msr.read();
620            if msr.slak().bit_is_set() && msr.inak().bit_is_clear() {
621                break;
622            }
623        }
624    }
625
626    /// Wakes up from sleep mode.
627    ///
628    /// Note that this will not trigger [`Interrupt::Wakeup`], only reception of an incoming CAN
629    /// frame will cause that interrupt.
630    pub fn wakeup(&mut self) {
631        let can = self.registers();
632        can.mcr
633            .modify(|_, w| w.sleep().clear_bit().inrq().clear_bit());
634        loop {
635            let msr = can.msr.read();
636            if msr.slak().bit_is_clear() && msr.inak().bit_is_clear() {
637                break;
638            }
639        }
640    }
641
642    /// Starts listening for a CAN interrupt.
643    pub fn enable_interrupt(&mut self, interrupt: Interrupt) {
644        self.enable_interrupts(Interrupts::from_bits_truncate(interrupt as u32))
645    }
646
647    /// Starts listening for a set of CAN interrupts.
648    pub fn enable_interrupts(&mut self, interrupts: Interrupts) {
649        self.registers()
650            .ier
651            .modify(|r, w| unsafe { w.bits(r.bits() | interrupts.bits()) })
652    }
653
654    /// Stops listening for a CAN interrupt.
655    pub fn disable_interrupt(&mut self, interrupt: Interrupt) {
656        self.disable_interrupts(Interrupts::from_bits_truncate(interrupt as u32))
657    }
658
659    /// Stops listening for a set of CAN interrupts.
660    pub fn disable_interrupts(&mut self, interrupts: Interrupts) {
661        self.registers()
662            .ier
663            .modify(|r, w| unsafe { w.bits(r.bits() & !interrupts.bits()) })
664    }
665
666    /// Clears the pending flag of [`Interrupt::Sleep`].
667    pub fn clear_sleep_interrupt(&self) {
668        let can = self.registers();
669        // Read-only register with write-1-to-clear, so `&self` is sufficient.
670        can.msr.write(|w| w.slaki().set_bit());
671    }
672
673    /// Clears the pending flag of [`Interrupt::Wakeup`].
674    pub fn clear_wakeup_interrupt(&self) {
675        let can = self.registers();
676        // Read-only register with write-1-to-clear, so `&self` is sufficient.
677        can.msr.write(|w| w.wkui().set_bit());
678    }
679
680    /// Clears the "Request Completed" (RQCP) flag of a transmit mailbox.
681    ///
682    /// Returns the [`Mailbox`] whose flag was cleared. If no mailbox has the flag set, returns
683    /// `None`.
684    ///
685    /// Once this function returns `None`, a pending [`Interrupt::TransmitMailboxEmpty`] is
686    /// considered acknowledged.
687    pub fn clear_request_completed_flag(&mut self) -> Option<Mailbox> {
688        let can = self.registers();
689        let tsr = can.tsr.read();
690        if tsr.rqcp0().bit_is_set() {
691            can.tsr.modify(|_, w| w.rqcp0().set_bit());
692            Some(Mailbox::Mailbox0)
693        } else if tsr.rqcp1().bit_is_set() {
694            can.tsr.modify(|_, w| w.rqcp1().set_bit());
695            Some(Mailbox::Mailbox1)
696        } else if tsr.rqcp2().bit_is_set() {
697            can.tsr.modify(|_, w| w.rqcp2().set_bit());
698            Some(Mailbox::Mailbox2)
699        } else {
700            None
701        }
702    }
703
704    /// Clears a pending TX interrupt ([`Interrupt::TransmitMailboxEmpty`]).
705    ///
706    /// This does not return the mailboxes that have finished tranmission. If you need that
707    /// information, call [`Can::clear_request_completed_flag`] instead.
708    pub fn clear_tx_interrupt(&mut self) {
709        while self.clear_request_completed_flag().is_some() {}
710    }
711
712    /// Clears the error interrupt flag ([`Interrupt::Error`]).
713    ///
714    /// To read the error status, use [`Can::error_status`] to get the [`ErrorStatus`] before
715    /// clearing the interrupt flag.
716    pub fn clear_error_interrupt(&mut self) {
717        let can = self.registers();
718        can.msr.write(|w| w.erri().set_bit());
719    }
720
721    /// Reads the error status register's data.
722    ///
723    /// This does not clear the error interrupt flag.
724    pub fn error_status(&self) -> ErrorStatus {
725        let can = self.registers();
726        let esr = can.esr.read();
727
728        ErrorStatus {
729            recv_count: esr.rec().bits,
730            txmt_count: esr.tec().bits,
731            code: (match esr.lec().bits {
732                0b000 => Error::None,
733                0b001 => Error::Stuff,
734                0b010 => Error::Form,
735                0b011 => Error::Acknowledgement,
736                0b100 => Error::BitRecessive,
737                0b101 => Error::BitDominant,
738                0b110 => Error::Crc,
739                0b111 => Error::Software,
740                _ => unreachable!(),
741            }),
742            bus_off: esr.boff().bits,
743            err_passive: esr.epvf().bits,
744            err_warning: esr.ewgf().bits,
745        }
746    }
747
748    /// Puts a CAN frame in a free transmit mailbox for transmission on the bus.
749    ///
750    /// Frames are transmitted to the bus based on their priority (see [`FramePriority`]).
751    /// Transmit order is preserved for frames with identical priority.
752    ///
753    /// If all transmit mailboxes are full, and `frame` has a higher priority than the
754    /// lowest-priority message in the transmit mailboxes, transmission of the enqueued frame is
755    /// cancelled and `frame` is enqueued instead. The frame that was replaced is returned as
756    /// [`TransmitStatus::dequeued_frame`].
757    pub fn transmit(&mut self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> {
758        // Safety: We have a `&mut self` and have unique access to the peripheral.
759        unsafe { Tx::<I>::conjure().transmit(frame) }
760    }
761
762    /// Returns `true` if no frame is pending for transmission.
763    pub fn is_transmitter_idle(&self) -> bool {
764        // Safety: Read-only operation.
765        unsafe { Tx::<I>::conjure().is_idle() }
766    }
767
768    /// Attempts to abort the sending of a frame that is pending in a mailbox.
769    ///
770    /// If there is no frame in the provided mailbox, or its transmission succeeds before it can be
771    /// aborted, this function has no effect and returns `false`.
772    ///
773    /// If there is a frame in the provided mailbox, and it is canceled successfully, this function
774    /// returns `true`.
775    pub fn abort(&mut self, mailbox: Mailbox) -> bool {
776        // Safety: We have a `&mut self` and have unique access to the peripheral.
777        unsafe { Tx::<I>::conjure().abort(mailbox) }
778    }
779
780    /// Returns a received frame if available.
781    ///
782    /// This will first check FIFO 0 for a message or error. If none are available, FIFO 1 is
783    /// checked.
784    ///
785    /// Returns `Err` when a frame was lost due to buffer overrun.
786    pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> {
787        // Safety: We have a `&mut self` and have unique access to the peripheral.
788        let mut rx0 = unsafe { Rx0::<I>::conjure() };
789        let mut rx1 = unsafe { Rx1::<I>::conjure() };
790
791        match rx0.receive() {
792            Err(nb::Error::WouldBlock) => rx1.receive(),
793            result => result,
794        }
795    }
796
797    /// Returns a reference to the RX FIFO 0.
798    pub fn rx0(&mut self) -> &mut Rx0<I> {
799        // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime.
800        unsafe { Rx0::conjure_by_ref() }
801    }
802
803    /// Returns a reference to the RX FIFO 1.
804    pub fn rx1(&mut self) -> &mut Rx1<I> {
805        // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime.
806        unsafe { Rx1::conjure_by_ref() }
807    }
808
809    /// Splits this `Can` instance into transmitting and receiving halves, by reference.
810    pub fn split_by_ref(&mut self) -> (&mut Tx<I>, &mut Rx0<I>, &mut Rx1<I>) {
811        // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime.
812        let tx = unsafe { Tx::conjure_by_ref() };
813        let rx0 = unsafe { Rx0::conjure_by_ref() };
814        let rx1 = unsafe { Rx1::conjure_by_ref() };
815        (tx, rx0, rx1)
816    }
817
818    /// Consumes this `Can` instance and splits it into transmitting and receiving halves.
819    pub fn split(self) -> (Tx<I>, Rx0<I>, Rx1<I>) {
820        // Safety: `Self` is not `Copy` and is destroyed by moving it into this method.
821        unsafe { (Tx::conjure(), Rx0::conjure(), Rx1::conjure()) }
822    }
823}
824
825impl<I: FilterOwner> Can<I> {
826    /// Accesses the filter banks owned by this CAN peripheral.
827    ///
828    /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master
829    /// peripheral instead.
830    pub fn modify_filters(&mut self) -> MasterFilters<'_, I> {
831        unsafe { MasterFilters::new() }
832    }
833}
834
835/// Interface to the CAN transmitter part.
836pub struct Tx<I> {
837    _can: PhantomData<I>,
838}
839
840#[inline]
841const fn ok_mask(idx: usize) -> u32 {
842    0x02 << (8 * idx)
843}
844
845#[inline]
846const fn abort_mask(idx: usize) -> u32 {
847    0x80 << (8 * idx)
848}
849
850impl<I> Tx<I>
851where
852    I: Instance,
853{
854    unsafe fn conjure() -> Self {
855        Self { _can: PhantomData }
856    }
857
858    /// Creates a `&mut Self` out of thin air.
859    ///
860    /// This is only safe if it is the only way to access a `Tx<I>`.
861    unsafe fn conjure_by_ref<'a>() -> &'a mut Self {
862        // Cause out of bounds access when `Self` is not zero-sized.
863        [()][core::mem::size_of::<Self>()];
864
865        // Any aligned pointer is valid for ZSTs.
866        &mut *NonNull::dangling().as_ptr()
867    }
868
869    fn registers(&self) -> &RegisterBlock {
870        unsafe { &*I::REGISTERS }
871    }
872
873    /// Puts a CAN frame in a transmit mailbox for transmission on the bus.
874    ///
875    /// Frames are transmitted to the bus based on their priority (see [`FramePriority`]).
876    /// Transmit order is preserved for frames with identical priority.
877    ///
878    /// If all transmit mailboxes are full, and `frame` has a higher priority than the
879    /// lowest-priority message in the transmit mailboxes, transmission of the enqueued frame is
880    /// cancelled and `frame` is enqueued instead. The frame that was replaced is returned as
881    /// [`TransmitStatus::dequeued_frame`].
882    pub fn transmit(&mut self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> {
883        let can = self.registers();
884
885        // Get the index of the next free mailbox or the one with the lowest priority.
886        let tsr = can.tsr.read();
887        let idx = tsr.code().bits() as usize;
888
889        let frame_is_pending =
890            tsr.tme0().bit_is_clear() || tsr.tme1().bit_is_clear() || tsr.tme2().bit_is_clear();
891        let pending_frame = if frame_is_pending {
892            // High priority frames are transmitted first by the mailbox system.
893            // Frames with identical identifier shall be transmitted in FIFO order.
894            // The controller schedules pending frames of same priority based on the
895            // mailbox index instead. As a workaround check all pending mailboxes
896            // and only accept higher priority frames.
897            self.check_priority(0, frame.id)?;
898            self.check_priority(1, frame.id)?;
899            self.check_priority(2, frame.id)?;
900
901            let all_frames_are_pending =
902                tsr.tme0().bit_is_clear() && tsr.tme1().bit_is_clear() && tsr.tme2().bit_is_clear();
903            if all_frames_are_pending {
904                // No free mailbox is available. This can only happen when three frames with
905                // ascending priority (descending IDs) were requested for transmission and all
906                // of them are blocked by bus traffic with even higher priority.
907                // To prevent a priority inversion abort and replace the lowest priority frame.
908                self.read_pending_mailbox(idx)
909            } else {
910                // There was a free mailbox.
911                None
912            }
913        } else {
914            // All mailboxes are available: Send frame without performing any checks.
915            None
916        };
917
918        self.write_mailbox(idx, frame);
919
920        let mailbox = match idx {
921            0 => Mailbox::Mailbox0,
922            1 => Mailbox::Mailbox1,
923            2 => Mailbox::Mailbox2,
924            _ => unreachable!(),
925        };
926        Ok(TransmitStatus {
927            dequeued_frame: pending_frame,
928            mailbox,
929        })
930    }
931
932    /// Returns `Ok` when the mailbox is free or if it contains pending frame with a
933    /// lower priority (higher ID) than the identifier `id`.
934    fn check_priority(&self, idx: usize, id: IdReg) -> nb::Result<(), Infallible> {
935        let can = self.registers();
936
937        // Read the pending frame's id to check its priority.
938        assert!(idx < 3);
939        let tir = &can.tx[idx].tir.read();
940
941        // Check the priority by comparing the identifiers. But first make sure the
942        // frame has not finished the transmission (`TXRQ` == 0) in the meantime.
943        if tir.txrq().bit_is_set() && id <= IdReg::from_register(tir.bits()) {
944            // There's a mailbox whose priority is higher or equal
945            // the priority of the new frame.
946            return Err(nb::Error::WouldBlock);
947        }
948
949        Ok(())
950    }
951
952    fn write_mailbox(&mut self, idx: usize, frame: &Frame) {
953        let can = self.registers();
954
955        debug_assert!(idx < 3);
956        let mb = unsafe { &can.tx.get_unchecked(idx) };
957
958        mb.tdtr
959            .write(|w| unsafe { w.dlc().bits(frame.dlc() as u8) });
960        mb.tdlr.write(|w| unsafe {
961            w.bits(u32::from_ne_bytes(
962                frame.data.bytes[0..4].try_into().unwrap(),
963            ))
964        });
965        mb.tdhr.write(|w| unsafe {
966            w.bits(u32::from_ne_bytes(
967                frame.data.bytes[4..8].try_into().unwrap(),
968            ))
969        });
970        mb.tir
971            .write(|w| unsafe { w.bits(frame.id.0).txrq().set_bit() });
972    }
973
974    fn read_pending_mailbox(&mut self, idx: usize) -> Option<Frame> {
975        if self.abort_by_index(idx) {
976            let can = self.registers();
977            debug_assert!(idx < 3);
978            let mb = unsafe { &can.tx.get_unchecked(idx) };
979
980            // Read back the pending frame.
981            let mut pending_frame = Frame {
982                id: IdReg(mb.tir.read().bits()),
983                data: Data::empty(),
984            };
985            pending_frame.data.bytes[0..4].copy_from_slice(&mb.tdlr.read().bits().to_ne_bytes());
986            pending_frame.data.bytes[4..8].copy_from_slice(&mb.tdhr.read().bits().to_ne_bytes());
987            pending_frame.data.len = mb.tdtr.read().dlc().bits();
988
989            Some(pending_frame)
990        } else {
991            // Abort request failed because the frame was already sent (or being sent) on
992            // the bus. All mailboxes are now free. This can happen for small prescaler
993            // values (e.g. 1MBit/s bit timing with a source clock of 8MHz) or when an ISR
994            // has preempted the execution.
995            None
996        }
997    }
998
999    /// Tries to abort a pending frame. Returns `true` when aborted.
1000    fn abort_by_index(&mut self, idx: usize) -> bool {
1001        let can = self.registers();
1002
1003        can.tsr.write(|w| unsafe { w.bits(abort_mask(idx)) });
1004
1005        // Wait for the abort request to be finished.
1006        loop {
1007            let tsr = can.tsr.read().bits();
1008            if tsr & abort_mask(idx) == 0 {
1009                break tsr & ok_mask(idx) == 0;
1010            }
1011        }
1012    }
1013
1014    /// Attempts to abort the sending of a frame that is pending in a mailbox.
1015    ///
1016    /// If there is no frame in the provided mailbox, or its transmission succeeds before it can be
1017    /// aborted, this function has no effect and returns `false`.
1018    ///
1019    /// If there is a frame in the provided mailbox, and it is canceled successfully, this function
1020    /// returns `true`.
1021    pub fn abort(&mut self, mailbox: Mailbox) -> bool {
1022        // If the mailbox is empty, the value of TXOKx depends on what happened with the previous
1023        // frame in that mailbox. Only call abort_by_index() if the mailbox is not empty.
1024        let tsr = self.registers().tsr.read();
1025        let mailbox_empty = match mailbox {
1026            Mailbox::Mailbox0 => tsr.tme0().bit_is_set(),
1027            Mailbox::Mailbox1 => tsr.tme1().bit_is_set(),
1028            Mailbox::Mailbox2 => tsr.tme2().bit_is_set(),
1029        };
1030        if mailbox_empty {
1031            false
1032        } else {
1033            self.abort_by_index(mailbox as usize)
1034        }
1035    }
1036
1037    /// Returns `true` if no frame is pending for transmission.
1038    pub fn is_idle(&self) -> bool {
1039        let can = self.registers();
1040        let tsr = can.tsr.read();
1041        tsr.tme0().bit_is_set() && tsr.tme1().bit_is_set() && tsr.tme2().bit_is_set()
1042    }
1043
1044    /// Clears the request complete flag for all mailboxes.
1045    pub fn clear_interrupt_flags(&mut self) {
1046        let can = self.registers();
1047        can.tsr
1048            .write(|w| w.rqcp2().set_bit().rqcp1().set_bit().rqcp0().set_bit());
1049    }
1050}
1051
1052/// Interface to receiver FIFO 0.
1053pub struct Rx0<I> {
1054    _can: PhantomData<I>,
1055}
1056
1057impl<I> Rx0<I>
1058where
1059    I: Instance,
1060{
1061    unsafe fn conjure() -> Self {
1062        Self { _can: PhantomData }
1063    }
1064
1065    /// Creates a `&mut Self` out of thin air.
1066    ///
1067    /// This is only safe if it is the only way to access an `Rx<I>`.
1068    unsafe fn conjure_by_ref<'a>() -> &'a mut Self {
1069        // Cause out of bounds access when `Self` is not zero-sized.
1070        [()][core::mem::size_of::<Self>()];
1071
1072        // Any aligned pointer is valid for ZSTs.
1073        &mut *NonNull::dangling().as_ptr()
1074    }
1075
1076    /// Returns a received frame if available.
1077    ///
1078    /// Returns `Err` when a frame was lost due to buffer overrun.
1079    pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> {
1080        receive_fifo(self.registers(), 0)
1081    }
1082
1083    fn registers(&self) -> &RegisterBlock {
1084        unsafe { &*I::REGISTERS }
1085    }
1086}
1087
1088/// Interface to receiver FIFO 1.
1089pub struct Rx1<I> {
1090    _can: PhantomData<I>,
1091}
1092
1093impl<I> Rx1<I>
1094where
1095    I: Instance,
1096{
1097    unsafe fn conjure() -> Self {
1098        Self { _can: PhantomData }
1099    }
1100
1101    /// Creates a `&mut Self` out of thin air.
1102    ///
1103    /// This is only safe if it is the only way to access an `Rx<I>`.
1104    unsafe fn conjure_by_ref<'a>() -> &'a mut Self {
1105        // Cause out of bounds access when `Self` is not zero-sized.
1106        [()][core::mem::size_of::<Self>()];
1107
1108        // Any aligned pointer is valid for ZSTs.
1109        &mut *NonNull::dangling().as_ptr()
1110    }
1111
1112    /// Returns a received frame if available.
1113    ///
1114    /// Returns `Err` when a frame was lost due to buffer overrun.
1115    pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> {
1116        receive_fifo(self.registers(), 1)
1117    }
1118
1119    fn registers(&self) -> &RegisterBlock {
1120        unsafe { &*I::REGISTERS }
1121    }
1122}
1123
1124fn receive_fifo(can: &RegisterBlock, fifo_nr: usize) -> nb::Result<Frame, OverrunError> {
1125    assert!(fifo_nr < 2);
1126    let rfr = &can.rfr[fifo_nr];
1127    let rx = &can.rx[fifo_nr];
1128
1129    // Check if a frame is available in the mailbox.
1130    let rfr_read = rfr.read();
1131    if rfr_read.fmp().bits() == 0 {
1132        return Err(nb::Error::WouldBlock);
1133    }
1134
1135    // Check for RX FIFO overrun.
1136    if rfr_read.fovr().bit_is_set() {
1137        rfr.write(|w| w.fovr().set_bit());
1138        return Err(nb::Error::Other(OverrunError { _priv: () }));
1139    }
1140
1141    // Read the frame.
1142    let mut frame = Frame {
1143        id: IdReg(rx.rir.read().bits()),
1144        data: [0; 8].into(),
1145    };
1146    frame.data[0..4].copy_from_slice(&rx.rdlr.read().bits().to_ne_bytes());
1147    frame.data[4..8].copy_from_slice(&rx.rdhr.read().bits().to_ne_bytes());
1148    frame.data.len = rx.rdtr.read().dlc().bits();
1149
1150    // Release the mailbox.
1151    rfr.write(|w| w.rfom().set_bit());
1152
1153    Ok(frame)
1154}
1155
1156/// Identifies one of the two receive FIFOs.
1157#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
1158#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
1159pub enum Fifo {
1160    Fifo0 = 0,
1161    Fifo1 = 1,
1162}
1163
1164/// Identifies one of the three transmit mailboxes.
1165#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
1166#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
1167pub enum Mailbox {
1168    /// Transmit mailbox 0
1169    Mailbox0 = 0,
1170    /// Transmit mailbox 1
1171    Mailbox1 = 1,
1172    /// Transmit mailbox 2
1173    Mailbox2 = 2,
1174}
1175
1176/// Contains information about a frame enqueued for transmission via [`Can::transmit`] or
1177/// [`Tx::transmit`].
1178pub struct TransmitStatus {
1179    dequeued_frame: Option<Frame>,
1180    mailbox: Mailbox,
1181}
1182
1183impl TransmitStatus {
1184    /// Returns the lower-priority frame that was dequeued to make space for the new frame.
1185    #[inline]
1186    pub fn dequeued_frame(&self) -> Option<&Frame> {
1187        self.dequeued_frame.as_ref()
1188    }
1189
1190    /// Returns the [`Mailbox`] the frame was enqueued in.
1191    #[inline]
1192    pub fn mailbox(&self) -> Mailbox {
1193        self.mailbox
1194    }
1195}