1use crate::pac::CAN1;
6use crate::rcc::{Enable, RccBus, Reset};
7
8mod sealed {
9 pub trait Sealed {}
10}
11
12pub trait Pins: sealed::Sealed {
14 type Instance;
16}
17
18macro_rules! pins {
21 ($($PER:ident => ($tx:ident<$txaf:literal>, $rx:ident<$rxaf:literal>),)+) => {
22 $(
23 impl crate::can::sealed::Sealed for ($tx<crate::gpio::Alternate<PushPull, $txaf, >>, $rx<crate::gpio::Alternate<PushPull, $rxaf>>) {}
24 impl crate::can::Pins for ($tx<crate::gpio::Alternate<PushPull, $txaf, >>, $rx<crate::gpio::Alternate<PushPull, $rxaf>>) {
25 type Instance = $PER;
26 }
27 )+
28 }
29}
30
31mod common_pins {
32 use crate::gpio::{
33 gpioa::{PA11, PA12},
34 gpiob::{PB8, PB9},
35 gpiod::{PD0, PD1},
36 PushPull,
37 };
38 use crate::pac::CAN1;
39
40 pins! {
42 CAN1 => (PA12<9>, PA11<9>),
43 CAN1 => (PD1<9>, PD0<9>),
44 CAN1 => (PB9<9>, PB8<9>),
45 }
46}
47
48#[cfg(any(feature = "stm32l431", feature = "stm32l451", feature = "stm32l471"))]
50mod pb13_pb12_af10 {
51 use crate::gpio::{
52 gpiob::{PB12, PB13},
53 PushPull,
54 };
55 use crate::pac::CAN1;
56 pins! { CAN1 => (PB13<10>, PB12<10>), }
57}
58
59impl crate::can::sealed::Sealed for crate::pac::CAN1 {}
60
61pub struct Can<CAN, Pins> {
63 can: CAN,
64 pins: Pins,
65}
66
67impl<CAN, P> Can<CAN, P>
68where
69 CAN: Enable + Reset,
70 P: Pins<Instance = CAN>,
71{
72 pub fn new(apb: &mut <CAN as RccBus>::Bus, can: CAN, pins: P) -> Can<CAN, P> {
74 CAN::enable(apb);
75 CAN::reset(apb);
76 Can { can, pins }
77 }
78
79 pub fn split(self) -> (CAN, P) {
81 (self.can, self.pins)
82 }
83}
84
85unsafe impl<Pins> bxcan::Instance for Can<CAN1, Pins> {
86 const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _;
87}
88
89unsafe impl<Pins> bxcan::FilterOwner for Can<CAN1, Pins> {
90 const NUM_FILTER_BANKS: u8 = 14;
91}
92
93unsafe impl<Pins> bxcan::MasterInstance for Can<CAN1, Pins> {}