1use crate::afio::{self, RInto, Rmp};
20use crate::gpio::{Floating, UpMode};
21use crate::pac::{self, RCC};
22
23pub trait CanExt: Sized + Instance {
24 fn can<PULL: UpMode>(
25 self,
26 #[cfg(not(feature = "connectivity"))] usb: pac::USB,
27 pins: (impl RInto<Self::Tx, 0>, impl RInto<Self::Rx<PULL>, 0>),
28 rcc: &mut RCC,
29 ) -> Can<Self, PULL>;
30 fn can_loopback(
31 self,
32 #[cfg(not(feature = "connectivity"))] usb: pac::USB,
33 rcc: &mut RCC,
34 ) -> Can<Self, Floating>;
35}
36
37impl<CAN: Instance> CanExt for CAN {
38 fn can<PULL: UpMode>(
39 self,
40 #[cfg(not(feature = "connectivity"))] usb: pac::USB,
41 pins: (impl RInto<Self::Tx, 0>, impl RInto<Self::Rx<PULL>, 0>),
42 rcc: &mut RCC,
43 ) -> Can<Self, PULL> {
44 Can::new(
45 self,
46 #[cfg(not(feature = "connectivity"))]
47 usb,
48 pins,
49 rcc,
50 )
51 }
52 fn can_loopback(
53 self,
54 #[cfg(not(feature = "connectivity"))] usb: pac::USB,
55 rcc: &mut RCC,
56 ) -> Can<Self, Floating> {
57 Can::new_loopback(
58 self,
59 #[cfg(not(feature = "connectivity"))]
60 usb,
61 rcc,
62 )
63 }
64}
65
66pub trait Instance: crate::rcc::Enable + afio::CanCommon {}
67#[cfg(not(feature = "connectivity"))]
68use pac::CAN as CAN1;
69#[cfg(feature = "connectivity")]
70use pac::CAN1;
71
72impl Instance for CAN1 {}
73#[cfg(feature = "connectivity")]
74impl Instance for pac::CAN2 {}
75
76#[allow(unused)]
78pub struct Can<CAN: Instance, PULL = Floating> {
79 can: CAN,
80 pins: (Option<CAN::Tx>, Option<CAN::Rx<PULL>>),
81}
82
83impl<CAN: Instance, const R: u8> Rmp<CAN, R> {
84 pub fn can<PULL: UpMode>(
85 self,
86 #[cfg(not(feature = "connectivity"))] _usb: pac::USB,
87 pins: (impl RInto<CAN::Tx, R>, impl RInto<CAN::Rx<PULL>, R>),
88 rcc: &mut RCC,
89 ) -> Can<CAN, PULL> {
90 CAN::enable(rcc);
91
92 let pins = (Some(pins.0.rinto()), Some(pins.1.rinto()));
93 Can { can: self.0, pins }
94 }
95 pub fn can_loopback(
96 self,
97 #[cfg(not(feature = "connectivity"))] usb: pac::USB,
98 rcc: &mut RCC,
99 ) -> Can<CAN, Floating> {
100 Can::new_loopback(
101 self.0,
102 #[cfg(not(feature = "connectivity"))]
103 usb,
104 rcc,
105 )
106 }
107}
108
109impl<CAN: Instance, PULL: UpMode> Can<CAN, PULL> {
110 pub fn new<const R: u8>(
115 can: impl Into<Rmp<CAN, R>>,
116 #[cfg(not(feature = "connectivity"))] _usb: pac::USB,
117 pins: (impl RInto<CAN::Tx, R>, impl RInto<CAN::Rx<PULL>, R>),
118 rcc: &mut RCC,
119 ) -> Can<CAN, PULL> {
120 can.into().can(
121 #[cfg(not(feature = "connectivity"))]
122 _usb,
123 pins,
124 rcc,
125 )
126 }
127
128 pub fn new_loopback(
130 can: CAN,
131 #[cfg(not(feature = "connectivity"))] _usb: pac::USB,
132 rcc: &mut RCC,
133 ) -> Can<CAN, PULL> {
134 CAN::enable(rcc);
135
136 Can {
137 can,
138 pins: (None, None),
139 }
140 }
141}
142
143unsafe impl<PULL> bxcan::Instance for Can<CAN1, PULL> {
144 const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _;
145}
146
147#[cfg(feature = "connectivity")]
148unsafe impl<PULL> bxcan::Instance for Can<pac::CAN2, PULL> {
149 const REGISTERS: *mut bxcan::RegisterBlock = pac::CAN2::ptr() as *mut _;
150}
151
152unsafe impl<PULL> bxcan::FilterOwner for Can<CAN1, PULL> {
153 const NUM_FILTER_BANKS: u8 = 28;
154}
155
156#[cfg(feature = "connectivity")]
157unsafe impl<PULL> bxcan::MasterInstance for Can<CAN1, PULL> {}