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