stm32f4xx_hal/
can.rs

1//! # Controller Area Network (CAN) Interface
2//!
3
4use crate::gpio;
5use crate::pac::{self, RCC};
6use crate::rcc;
7
8pub trait Instance: crate::Sealed + rcc::Enable + rcc::Reset + gpio::alt::CanCommon {}
9
10macro_rules! can {
11    ($CAN:ty: $Can:ident) => {
12        pub type $Can = Can<$CAN>;
13
14        impl Instance for $CAN {}
15    };
16}
17
18// Implemented by all SPI instances
19can! { pac::CAN1: Can1 }
20#[cfg(feature = "can2")]
21can! { pac::CAN2: Can2 }
22#[cfg(feature = "can3")]
23can! { pac::CAN3: Can3 }
24
25/// Pins and definitions for models with a third CAN peripheral
26#[cfg(feature = "can3")]
27mod can3 {
28    use super::*;
29
30    unsafe impl bxcan::Instance for Can<pac::CAN3> {
31        const REGISTERS: *mut bxcan::RegisterBlock = pac::CAN3::ptr() as *mut _;
32    }
33
34    unsafe impl bxcan::FilterOwner for Can<pac::CAN3> {
35        const NUM_FILTER_BANKS: u8 = 14;
36    }
37}
38
39pub trait CanExt: Sized + Instance {
40    fn can(self, pins: (impl Into<Self::Tx>, impl Into<Self::Rx>), rcc: &mut RCC) -> Can<Self>;
41
42    fn tx(self, tx_pin: impl Into<Self::Tx>, rcc: &mut RCC) -> Can<Self>;
43
44    fn rx(self, rx_pin: impl Into<Self::Rx>, rcc: &mut RCC) -> Can<Self>;
45}
46
47impl<CAN: Instance> CanExt for CAN {
48    fn can(self, pins: (impl Into<Self::Tx>, impl Into<Self::Rx>), rcc: &mut RCC) -> Can<Self> {
49        Can::new(self, pins, rcc)
50    }
51
52    fn tx(self, tx_pin: impl Into<Self::Tx>, rcc: &mut RCC) -> Can<Self> {
53        Can::tx(self, tx_pin, rcc)
54    }
55
56    fn rx(self, rx_pin: impl Into<Self::Rx>, rcc: &mut RCC) -> Can<Self> {
57        Can::rx(self, rx_pin, rcc)
58    }
59}
60
61/// Interface to the CAN peripheral.
62pub struct Can<CAN: Instance> {
63    can: CAN,
64    pins: (Option<CAN::Tx>, Option<CAN::Rx>),
65}
66
67impl<CAN: Instance> Can<CAN> {
68    /// Creates a CAN interface.
69    pub fn new(can: CAN, pins: (impl Into<CAN::Tx>, impl Into<CAN::Rx>), rcc: &mut RCC) -> Self {
70        Self::_new(can, (Some(pins.0.into()), Some(pins.1.into())), rcc)
71    }
72    fn _new(can: CAN, pins: (Option<CAN::Tx>, Option<CAN::Rx>), rcc: &mut RCC) -> Self {
73        CAN::enable(rcc);
74        CAN::reset(rcc);
75
76        Can { can, pins }
77    }
78
79    pub fn release(self) -> (CAN, (Option<CAN::Tx>, Option<CAN::Rx>)) {
80        (self.can, self.pins)
81    }
82}
83
84impl<CAN: Instance> Can<CAN> {
85    pub fn tx(usart: CAN, tx_pin: impl Into<CAN::Tx>, rcc: &mut RCC) -> Self {
86        Self::_new(usart, (Some(tx_pin.into()), None), rcc)
87    }
88
89    pub fn rx(usart: CAN, rx_pin: impl Into<CAN::Rx>, rcc: &mut RCC) -> Self {
90        Self::_new(usart, (None, Some(rx_pin.into())), rcc)
91    }
92}
93
94unsafe impl bxcan::Instance for Can<pac::CAN1> {
95    const REGISTERS: *mut bxcan::RegisterBlock = pac::CAN1::ptr() as *mut _;
96}
97
98#[cfg(feature = "can2")]
99unsafe impl bxcan::Instance for Can<pac::CAN2> {
100    const REGISTERS: *mut bxcan::RegisterBlock = pac::CAN2::ptr() as *mut _;
101}
102
103unsafe impl bxcan::FilterOwner for Can<pac::CAN1> {
104    const NUM_FILTER_BANKS: u8 = 28;
105}
106
107unsafe impl bxcan::MasterInstance for Can<pac::CAN1> {}