1use 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
18can! { pac::CAN1: Can1 }
20#[cfg(feature = "can2")]
21can! { pac::CAN2: Can2 }
22#[cfg(feature = "can3")]
23can! { pac::CAN3: Can3 }
24
25#[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
61pub struct Can<CAN: Instance> {
63 can: CAN,
64 pins: (Option<CAN::Tx>, Option<CAN::Rx>),
65}
66
67impl<CAN: Instance> Can<CAN> {
68 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> {}