| 
1 | 1 | //! # Controller Area Network (CAN) Interface  | 
2 | 2 | //!  | 
3 | 3 | 
  | 
 | 4 | +use crate::gpio::alt::CanCommon;  | 
4 | 5 | use crate::rcc::{self, Rcc};  | 
5 | 6 | 
 
  | 
6 |  | -mod sealed {  | 
7 |  | -    /// A TX pin configured for CAN communication  | 
8 |  | -    pub trait Tx<CAN> {}  | 
9 |  | -    /// An RX pin configured for CAN communication  | 
10 |  | -    pub trait Rx<CAN> {}  | 
11 |  | -}  | 
 | 7 | +pub trait Instance: CanCommon + rcc::Instance + crate::Ptr {}  | 
12 | 8 | 
 
  | 
13 | 9 | /// Storage type for the CAN controller  | 
14 | 10 | #[derive(Debug)]  | 
15 |  | -pub struct Can<FDCAN> {  | 
16 |  | -    rb: FDCAN,  | 
 | 11 | +pub struct Can<CAN: Instance> {  | 
 | 12 | +    rb: CAN,  | 
17 | 13 | }  | 
18 | 14 | #[allow(dead_code)]  | 
19 |  | -impl<FDCAN> Can<FDCAN> {  | 
 | 15 | +impl<CAN: Instance> Can<CAN> {  | 
20 | 16 |     /// Returns a reference to the inner peripheral  | 
21 |  | -    fn inner(&self) -> &FDCAN {  | 
 | 17 | +    fn inner(&self) -> &CAN {  | 
22 | 18 |         &self.rb  | 
23 | 19 |     }  | 
24 | 20 | }  | 
25 | 21 | 
 
  | 
26 | 22 | /// Extension trait for CAN controller  | 
27 |  | -pub trait CanExt: Sized  | 
 | 23 | +pub trait CanExt: Sized + Instance  | 
28 | 24 | where  | 
29 |  | -    Self: rcc::Instance,  | 
30 | 25 |     Can<Self>: fdcan::Instance,  | 
31 | 26 | {  | 
32 |  | -    fn fdcan<TX, RX>(  | 
 | 27 | +    fn fdcan(  | 
33 | 28 |         self,  | 
34 |  | -        _tx: TX,  | 
35 |  | -        _rx: RX,  | 
 | 29 | +        pins: (impl Into<Self::Tx>, impl Into<Self::Rx>),  | 
36 | 30 |         rcc: &mut Rcc,  | 
37 |  | -    ) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode>  | 
38 |  | -    where  | 
39 |  | -        TX: sealed::Tx<Self>,  | 
40 |  | -        RX: sealed::Rx<Self>,  | 
41 |  | -    {  | 
 | 31 | +    ) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {  | 
42 | 32 |         Self::enable(rcc);  | 
 | 33 | +        let _pins = (pins.0.into(), pins.1.into());  | 
43 | 34 | 
 
  | 
44 | 35 |         self.fdcan_unchecked()  | 
45 | 36 |     }  | 
46 | 37 | 
 
  | 
47 | 38 |     fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode>;  | 
48 | 39 | }  | 
49 |  | -/// Implements sealed::{Tx,Rx} for pins associated with a CAN peripheral  | 
50 |  | -macro_rules! pins {  | 
51 |  | -    ($PER:ident =>  | 
52 |  | -        (tx: [ $($( #[ $pmetatx:meta ] )* $tx:ident<$txaf:ident>),+ $(,)? ],  | 
53 |  | -         rx: [ $($( #[ $pmetarx:meta ] )* $rx:ident<$rxaf:ident>),+ $(,)? ])) => {  | 
54 |  | -        $(  | 
55 |  | -            $( #[ $pmetatx ] )*  | 
56 |  | -            impl sealed::Tx<$PER> for $tx<$txaf> {}  | 
57 |  | -        )+  | 
58 |  | -        $(  | 
59 |  | -            $( #[ $pmetarx ] )*  | 
60 |  | -            impl sealed::Rx<$PER> for $rx<$rxaf> {}  | 
61 |  | -        )+  | 
62 |  | -    };  | 
 | 40 | + | 
 | 41 | +impl<CAN: Instance> Can<CAN>  | 
 | 42 | +where  | 
 | 43 | +    Self: fdcan::message_ram::Instance,  | 
 | 44 | +{  | 
 | 45 | +    pub fn new(rb: CAN) -> fdcan::FdCan<Self, fdcan::ConfigMode> {  | 
 | 46 | +        fdcan::FdCan::new(Self { rb }).into_config_mode()  | 
 | 47 | +    }  | 
 | 48 | +}  | 
 | 49 | + | 
 | 50 | +unsafe impl<CAN: Instance> fdcan::Instance for Can<CAN>  | 
 | 51 | +where  | 
 | 52 | +    Self: fdcan::message_ram::Instance,  | 
 | 53 | +{  | 
 | 54 | +    const REGISTERS: *mut fdcan::RegisterBlock = CAN::PTR as *mut _;  | 
 | 55 | +}  | 
 | 56 | + | 
 | 57 | +impl<CAN: Instance> CanExt for CAN  | 
 | 58 | +where  | 
 | 59 | +    Can<Self>: fdcan::message_ram::Instance,  | 
 | 60 | +{  | 
 | 61 | +    fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {  | 
 | 62 | +        Can::new(self)  | 
 | 63 | +    }  | 
63 | 64 | }  | 
64 | 65 | 
 
  | 
65 | 66 | mod fdcan1 {  | 
66 |  | -    use super::sealed;  | 
67 |  | -    use super::{Can, CanExt};  | 
68 |  | -    use crate::gpio::{AF9, PA11, PA12, PB8, PB9, PD0, PD1};  | 
 | 67 | +    use super::{Can, Instance};  | 
69 | 68 |     use crate::stm32::FDCAN1;  | 
70 | 69 |     use fdcan;  | 
71 | 70 | 
 
  | 
72 |  | -    // All STM32G4 models with CAN support these pins  | 
73 |  | -    pins! {  | 
74 |  | -        FDCAN1 => (  | 
75 |  | -            tx: [  | 
76 |  | -                PA12<AF9>,  | 
77 |  | -                PB9<AF9>,  | 
78 |  | -                PD1<AF9>,  | 
79 |  | -            ],  | 
80 |  | -            rx: [  | 
81 |  | -                PA11<AF9>,  | 
82 |  | -                PB8<AF9>,  | 
83 |  | -                PD0<AF9>,  | 
84 |  | -            ]  | 
85 |  | -        )  | 
86 |  | -    }  | 
 | 71 | +    impl Instance for FDCAN1 {}  | 
87 | 72 | 
 
  | 
88 |  | -    impl Can<FDCAN1> {  | 
89 |  | -        pub fn fdcan1(rb: FDCAN1) -> fdcan::FdCan<Self, fdcan::ConfigMode> {  | 
90 |  | -            fdcan::FdCan::new(Self { rb }).into_config_mode()  | 
91 |  | -        }  | 
92 |  | -    }  | 
93 |  | -    impl CanExt for FDCAN1 {  | 
94 |  | -        fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {  | 
95 |  | -            Can::fdcan1(self)  | 
96 |  | -        }  | 
97 |  | -    }  | 
98 |  | -    unsafe impl fdcan::Instance for Can<FDCAN1> {  | 
99 |  | -        const REGISTERS: *mut fdcan::RegisterBlock = FDCAN1::ptr() as *mut _;  | 
100 |  | -    }  | 
101 | 73 |     unsafe impl fdcan::message_ram::Instance for Can<FDCAN1> {  | 
102 | 74 |         const MSG_RAM: *mut fdcan::message_ram::RegisterBlock = (0x4000_a400 as *mut _);  | 
103 | 75 |     }  | 
104 | 76 | }  | 
105 | 77 | 
 
  | 
106 |  | -#[cfg(any(  | 
107 |  | -    feature = "stm32g473",  | 
108 |  | -    feature = "stm32g474",  | 
109 |  | -    feature = "stm32g483",  | 
110 |  | -    feature = "stm32g484",  | 
111 |  | -    feature = "stm32g491",  | 
112 |  | -    feature = "stm32g4a1",  | 
113 |  | -))]  | 
 | 78 | +#[cfg(feature = "fdcan2")]  | 
114 | 79 | mod fdcan2 {  | 
115 |  | -    use super::sealed;  | 
116 |  | -    use super::{Can, CanExt};  | 
117 |  | -    use crate::gpio::{AF9, PB12, PB13, PB5, PB6};  | 
 | 80 | +    use super::{Can, Instance};  | 
118 | 81 |     use crate::stm32::FDCAN2;  | 
119 | 82 |     use fdcan;  | 
120 | 83 |     use fdcan::message_ram;  | 
121 | 84 | 
 
  | 
122 |  | -    pins! {  | 
123 |  | -        FDCAN2 => (  | 
124 |  | -            tx: [  | 
125 |  | -                PB6<AF9>,  | 
126 |  | -                PB13<AF9>,  | 
127 |  | -            ],  | 
128 |  | -            rx: [  | 
129 |  | -                PB5<AF9>,  | 
130 |  | -                PB12<AF9>,  | 
131 |  | -        ])  | 
132 |  | -    }  | 
 | 85 | +    impl Instance for FDCAN2 {}  | 
133 | 86 | 
 
  | 
134 |  | -    impl Can<FDCAN2> {  | 
135 |  | -        pub fn fdcan2(rb: FDCAN2) -> fdcan::FdCan<Self, fdcan::ConfigMode> {  | 
136 |  | -            fdcan::FdCan::new(Self { rb }).into_config_mode()  | 
137 |  | -        }  | 
138 |  | -    }  | 
139 |  | -    impl CanExt for FDCAN2 {  | 
140 |  | -        fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {  | 
141 |  | -            Can::fdcan2(self)  | 
142 |  | -        }  | 
143 |  | -    }  | 
144 |  | -    unsafe impl fdcan::Instance for Can<FDCAN2> {  | 
145 |  | -        const REGISTERS: *mut fdcan::RegisterBlock = FDCAN2::ptr() as *mut _;  | 
146 |  | -    }  | 
147 | 87 |     unsafe impl fdcan::message_ram::Instance for Can<FDCAN2> {  | 
148 | 88 |         const MSG_RAM: *mut message_ram::RegisterBlock = (0x4000_a750 as *mut _);  | 
149 | 89 |     }  | 
150 | 90 | }  | 
151 | 91 | 
 
  | 
152 |  | -#[cfg(any(  | 
153 |  | -    feature = "stm32g473",  | 
154 |  | -    feature = "stm32g474",  | 
155 |  | -    feature = "stm32g483",  | 
156 |  | -    feature = "stm32g484",  | 
157 |  | -))]  | 
 | 92 | +#[cfg(feature = "fdcan3")]  | 
158 | 93 | mod fdcan3 {  | 
159 |  | -    use super::sealed;  | 
160 |  | -    use super::{Can, CanExt};  | 
161 |  | -    use crate::gpio::{AF11, PA15, PA8, PB3, PB4};  | 
 | 94 | +    use super::{Can, Instance};  | 
162 | 95 |     use crate::stm32::FDCAN3;  | 
163 | 96 |     use fdcan;  | 
164 | 97 |     use fdcan::message_ram;  | 
165 | 98 | 
 
  | 
166 |  | -    pins! {  | 
167 |  | -        FDCAN3 => (  | 
168 |  | -            tx: [  | 
169 |  | -                PA15<AF11>,  | 
170 |  | -                PB4<AF11>,  | 
171 |  | -            ],  | 
172 |  | -            rx: [  | 
173 |  | -                PA8<AF11>,  | 
174 |  | -                PB3<AF11>,  | 
175 |  | -        ])  | 
176 |  | -    }  | 
 | 99 | +    impl Instance for FDCAN3 {}  | 
177 | 100 | 
 
  | 
178 |  | -    impl Can<FDCAN3> {  | 
179 |  | -        pub fn fdcan3(rb: FDCAN3) -> fdcan::FdCan<Self, fdcan::ConfigMode> {  | 
180 |  | -            fdcan::FdCan::new(Self { rb }).into_config_mode()  | 
181 |  | -        }  | 
182 |  | -    }  | 
183 |  | -    impl CanExt for FDCAN3 {  | 
184 |  | -        fn fdcan_unchecked(self) -> fdcan::FdCan<Can<Self>, fdcan::ConfigMode> {  | 
185 |  | -            Can::fdcan3(self)  | 
186 |  | -        }  | 
187 |  | -    }  | 
188 |  | -    unsafe impl fdcan::Instance for Can<FDCAN3> {  | 
189 |  | -        const REGISTERS: *mut fdcan::RegisterBlock = FDCAN3::ptr() as *mut _;  | 
190 |  | -    }  | 
191 | 101 |     unsafe impl fdcan::message_ram::Instance for Can<FDCAN3> {  | 
192 | 102 |         const MSG_RAM: *mut message_ram::RegisterBlock = (0x4000_aaa0 as *mut _);  | 
193 | 103 |     }  | 
 | 
0 commit comments