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}