stm32f3xx_hal/
can.rs

1//! Controller Area Network.
2//!
3//! CAN is currently not enabled by default, and
4//! can be enabled by the `can` feature.
5//!
6//! It is a implementation of the [`bxcan`][can] traits.
7//!
8//! [can]: bxcan
9//!
10//! A usage example of the can peripheral can be found at [examples/can.rs]
11//!
12//! [examples/can.rs]: https://github.com/stm32-rs/stm32f3xx-hal/blob/v0.10.0/examples/can.rs
13
14use crate::gpio::{gpioa, gpiob};
15use crate::gpio::{PushPull, AF9};
16use crate::pac;
17
18use crate::rcc::{Enable, Reset, APB1};
19
20use bxcan::RegisterBlock;
21
22use cfg_if::cfg_if;
23
24/// Marker trait for pins (with specific AF mode) that can be used as a CAN RX pin.
25pub trait RxPin: crate::private::Sealed {}
26
27/// Marker trait for pins (with specific AF mode) that can be used as a CAN TX pin.
28pub trait TxPin: crate::private::Sealed {}
29
30impl RxPin for gpioa::PA11<AF9<PushPull>> {}
31impl TxPin for gpioa::PA12<AF9<PushPull>> {}
32impl RxPin for gpiob::PB8<AF9<PushPull>> {}
33impl TxPin for gpiob::PB9<AF9<PushPull>> {}
34
35cfg_if! {
36    if #[cfg(any(feature = "gpio-f303", feature = "gpio-f303e", feature = "gpio-f373"))] {
37        use crate::gpio::{gpiod, AF7};
38        impl RxPin for gpiod::PD0<AF7<PushPull>> {}
39        impl TxPin for gpiod::PD1<AF7<PushPull>> {}
40    }
41}
42
43/// Struct representing a CAN peripheral and its configured TX and RX pins.
44///
45/// See [`bxcan::Instance`] for more information on how to use the CAN interface.
46pub struct Can<Tx, Rx> {
47    can: pac::CAN,
48    tx: Tx,
49    rx: Rx,
50}
51
52impl<Tx, Rx> Can<Tx, Rx>
53where
54    Tx: TxPin,
55    Rx: RxPin,
56{
57    /// Create a new `bxcan::CAN` instance.
58    pub fn new(can: pac::CAN, tx: Tx, rx: Rx, apb1: &mut APB1) -> Self {
59        pac::CAN::enable(apb1);
60        pac::CAN::reset(apb1);
61
62        Can { can, tx, rx }
63    }
64
65    /// Releases the CAN peripheral and associated pins
66    pub fn free(self) -> (pac::CAN, Tx, Rx) {
67        (self.can, self.tx, self.rx)
68    }
69}
70
71// SAFETY: Can has ownership of the CAN peripheral and the pointer is pointing to the CAN peripheral
72unsafe impl<Tx, Rx> bxcan::Instance for Can<Tx, Rx> {
73    const REGISTERS: *mut RegisterBlock = pac::CAN::ptr() as *mut _;
74}
75
76// SAFETY: The peripheral does own it's associated filter banks
77unsafe impl<Tx, Rx> bxcan::FilterOwner for Can<Tx, Rx> {
78    const NUM_FILTER_BANKS: u8 = 28;
79}