1use core::marker::PhantomData;
3
4use embassy_hal_internal::into_ref;
5
6use crate::gpio::{AfType, OutputType, Pull, Speed};
7use crate::{rcc, Peripheral};
8
9pub struct Fmc<'d, T: Instance> {
11 peri: PhantomData<&'d mut T>,
12}
13
14unsafe impl<'d, T> Send for Fmc<'d, T> where T: Instance {}
15
16impl<'d, T> Fmc<'d, T>
17where
18 T: Instance,
19{
20 pub fn new_raw(_instance: impl Peripheral<P = T> + 'd) -> Self {
25 Self { peri: PhantomData }
26 }
27
28 pub fn enable(&mut self) {
30 rcc::enable_and_reset::<T>();
31 }
32
33 pub fn memory_controller_enable(&mut self) {
35 #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fmc_v4)))]
39 T::REGS.bcr1().modify(|r| r.set_fmcen(true));
40 #[cfg(any(fmc_v4))]
41 T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true));
42 }
43
44 pub fn source_clock_hz(&self) -> u32 {
46 <T as crate::rcc::SealedRccPeripheral>::frequency().0
47 }
48}
49
50unsafe impl<'d, T> stm32_fmc::FmcPeripheral for Fmc<'d, T>
51where
52 T: Instance,
53{
54 const REGISTERS: *const () = T::REGS.as_ptr() as *const _;
55
56 fn enable(&mut self) {
57 rcc::enable_and_reset::<T>();
58 }
59
60 fn memory_controller_enable(&mut self) {
61 #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fmc_v4)))]
65 T::REGS.bcr1().modify(|r| r.set_fmcen(true));
66 #[cfg(any(fmc_v4))]
67 T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true));
68 }
69
70 fn source_clock_hz(&self) -> u32 {
71 <T as crate::rcc::SealedRccPeripheral>::frequency().0
72 }
73}
74
75macro_rules! config_pins {
76 ($($pin:ident),*) => {
77 into_ref!($($pin),*);
78 $(
79 $pin.set_as_af($pin.af_num(), AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up));
80 )*
81 };
82}
83
84macro_rules! fmc_sdram_constructor {
85 ($name:ident: (
86 bank: $bank:expr,
87 addr: [$(($addr_pin_name:ident: $addr_signal:ident)),*],
88 ba: [$(($ba_pin_name:ident: $ba_signal:ident)),*],
89 d: [$(($d_pin_name:ident: $d_signal:ident)),*],
90 nbl: [$(($nbl_pin_name:ident: $nbl_signal:ident)),*],
91 ctrl: [$(($ctrl_pin_name:ident: $ctrl_signal:ident)),*]
92 )) => {
93 pub fn $name<CHIP: stm32_fmc::SdramChip>(
95 _instance: impl Peripheral<P = T> + 'd,
96 $($addr_pin_name: impl Peripheral<P = impl $addr_signal<T>> + 'd),*,
97 $($ba_pin_name: impl Peripheral<P = impl $ba_signal<T>> + 'd),*,
98 $($d_pin_name: impl Peripheral<P = impl $d_signal<T>> + 'd),*,
99 $($nbl_pin_name: impl Peripheral<P = impl $nbl_signal<T>> + 'd),*,
100 $($ctrl_pin_name: impl Peripheral<P = impl $ctrl_signal<T>> + 'd),*,
101 chip: CHIP
102 ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
103
104 critical_section::with(|_| {
105 config_pins!(
106 $($addr_pin_name),*,
107 $($ba_pin_name),*,
108 $($d_pin_name),*,
109 $($nbl_pin_name),*,
110 $($ctrl_pin_name),*
111 );
112 });
113
114 let fmc = Self { peri: PhantomData };
115 stm32_fmc::Sdram::new_unchecked(
116 fmc,
117 $bank,
118 chip,
119 )
120 }
121 };
122}
123
124impl<'d, T: Instance> Fmc<'d, T> {
125 fmc_sdram_constructor!(sdram_a12bits_d16bits_4banks_bank1: (
126 bank: stm32_fmc::SdramTargetBank::Bank1,
127 addr: [
128 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
129 ],
130 ba: [(ba0: BA0Pin), (ba1: BA1Pin)],
131 d: [
132 (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin),
133 (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin)
134 ],
135 nbl: [
136 (nbl0: NBL0Pin), (nbl1: NBL1Pin)
137 ],
138 ctrl: [
139 (sdcke: SDCKE0Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE0Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
140 ]
141 ));
142
143 fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank1: (
144 bank: stm32_fmc::SdramTargetBank::Bank1,
145 addr: [
146 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
147 ],
148 ba: [(ba0: BA0Pin), (ba1: BA1Pin)],
149 d: [
150 (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin),
151 (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin),
152 (d16: D16Pin), (d17: D17Pin), (d18: D18Pin), (d19: D19Pin), (d20: D20Pin), (d21: D21Pin), (d22: D22Pin), (d23: D23Pin),
153 (d24: D24Pin), (d25: D25Pin), (d26: D26Pin), (d27: D27Pin), (d28: D28Pin), (d29: D29Pin), (d30: D30Pin), (d31: D31Pin)
154 ],
155 nbl: [
156 (nbl0: NBL0Pin), (nbl1: NBL1Pin), (nbl2: NBL2Pin), (nbl3: NBL3Pin)
157 ],
158 ctrl: [
159 (sdcke: SDCKE0Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE0Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
160 ]
161 ));
162
163 fmc_sdram_constructor!(sdram_a13bits_d32bits_4banks_bank1: (
164 bank: stm32_fmc::SdramTargetBank::Bank1,
165 addr: [
166 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin), (a12: A12Pin)
167 ],
168 ba: [(ba0: BA0Pin), (ba1: BA1Pin)],
169 d: [
170 (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin),
171 (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin),
172 (d16: D16Pin), (d17: D17Pin), (d18: D18Pin), (d19: D19Pin), (d20: D20Pin), (d21: D21Pin), (d22: D22Pin), (d23: D23Pin),
173 (d24: D24Pin), (d25: D25Pin), (d26: D26Pin), (d27: D27Pin), (d28: D28Pin), (d29: D29Pin), (d30: D30Pin), (d31: D31Pin)
174 ],
175 nbl: [
176 (nbl0: NBL0Pin), (nbl1: NBL1Pin), (nbl2: NBL2Pin), (nbl3: NBL3Pin)
177 ],
178 ctrl: [
179 (sdcke: SDCKE0Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE0Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
180 ]
181 ));
182
183 fmc_sdram_constructor!(sdram_a12bits_d16bits_4banks_bank2: (
184 bank: stm32_fmc::SdramTargetBank::Bank2,
185 addr: [
186 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
187 ],
188 ba: [(ba0: BA0Pin), (ba1: BA1Pin)],
189 d: [
190 (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin),
191 (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin)
192 ],
193 nbl: [
194 (nbl0: NBL0Pin), (nbl1: NBL1Pin)
195 ],
196 ctrl: [
197 (sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
198 ]
199 ));
200
201 fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank2: (
202 bank: stm32_fmc::SdramTargetBank::Bank2,
203 addr: [
204 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
205 ],
206 ba: [(ba0: BA0Pin), (ba1: BA1Pin)],
207 d: [
208 (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin),
209 (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin),
210 (d16: D16Pin), (d17: D17Pin), (d18: D18Pin), (d19: D19Pin), (d20: D20Pin), (d21: D21Pin), (d22: D22Pin), (d23: D23Pin),
211 (d24: D24Pin), (d25: D25Pin), (d26: D26Pin), (d27: D27Pin), (d28: D28Pin), (d29: D29Pin), (d30: D30Pin), (d31: D31Pin)
212 ],
213 nbl: [
214 (nbl0: NBL0Pin), (nbl1: NBL1Pin), (nbl2: NBL2Pin), (nbl3: NBL3Pin)
215 ],
216 ctrl: [
217 (sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
218 ]
219 ));
220
221 fmc_sdram_constructor!(sdram_a13bits_d32bits_4banks_bank2: (
222 bank: stm32_fmc::SdramTargetBank::Bank2,
223 addr: [
224 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin), (a12: A12Pin)
225 ],
226 ba: [(ba0: BA0Pin), (ba1: BA1Pin)],
227 d: [
228 (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin),
229 (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin),
230 (d16: D16Pin), (d17: D17Pin), (d18: D18Pin), (d19: D19Pin), (d20: D20Pin), (d21: D21Pin), (d22: D22Pin), (d23: D23Pin),
231 (d24: D24Pin), (d25: D25Pin), (d26: D26Pin), (d27: D27Pin), (d28: D28Pin), (d29: D29Pin), (d30: D30Pin), (d31: D31Pin)
232 ],
233 nbl: [
234 (nbl0: NBL0Pin), (nbl1: NBL1Pin), (nbl2: NBL2Pin), (nbl3: NBL3Pin)
235 ],
236 ctrl: [
237 (sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
238 ]
239 ));
240}
241
242trait SealedInstance: crate::rcc::RccPeripheral {
243 const REGS: crate::pac::fmc::Fmc;
244}
245
246#[allow(private_bounds)]
248pub trait Instance: SealedInstance + 'static {}
249
250foreach_peripheral!(
251 (fmc, $inst:ident) => {
252 impl crate::fmc::SealedInstance for crate::peripherals::$inst {
253 const REGS: crate::pac::fmc::Fmc = crate::pac::$inst;
254 }
255 impl crate::fmc::Instance for crate::peripherals::$inst {}
256 };
257);
258
259pin_trait!(SDNWEPin, Instance);
260pin_trait!(SDNCASPin, Instance);
261pin_trait!(SDNRASPin, Instance);
262
263pin_trait!(SDNE0Pin, Instance);
264pin_trait!(SDNE1Pin, Instance);
265
266pin_trait!(SDCKE0Pin, Instance);
267pin_trait!(SDCKE1Pin, Instance);
268
269pin_trait!(SDCLKPin, Instance);
270
271pin_trait!(NBL0Pin, Instance);
272pin_trait!(NBL1Pin, Instance);
273pin_trait!(NBL2Pin, Instance);
274pin_trait!(NBL3Pin, Instance);
275
276pin_trait!(INTPin, Instance);
277pin_trait!(NLPin, Instance);
278pin_trait!(NWaitPin, Instance);
279
280pin_trait!(NE1Pin, Instance);
281pin_trait!(NE2Pin, Instance);
282pin_trait!(NE3Pin, Instance);
283pin_trait!(NE4Pin, Instance);
284
285pin_trait!(NCEPin, Instance);
286pin_trait!(NOEPin, Instance);
287pin_trait!(NWEPin, Instance);
288pin_trait!(ClkPin, Instance);
289
290pin_trait!(BA0Pin, Instance);
291pin_trait!(BA1Pin, Instance);
292
293pin_trait!(D0Pin, Instance);
294pin_trait!(D1Pin, Instance);
295pin_trait!(D2Pin, Instance);
296pin_trait!(D3Pin, Instance);
297pin_trait!(D4Pin, Instance);
298pin_trait!(D5Pin, Instance);
299pin_trait!(D6Pin, Instance);
300pin_trait!(D7Pin, Instance);
301pin_trait!(D8Pin, Instance);
302pin_trait!(D9Pin, Instance);
303pin_trait!(D10Pin, Instance);
304pin_trait!(D11Pin, Instance);
305pin_trait!(D12Pin, Instance);
306pin_trait!(D13Pin, Instance);
307pin_trait!(D14Pin, Instance);
308pin_trait!(D15Pin, Instance);
309pin_trait!(D16Pin, Instance);
310pin_trait!(D17Pin, Instance);
311pin_trait!(D18Pin, Instance);
312pin_trait!(D19Pin, Instance);
313pin_trait!(D20Pin, Instance);
314pin_trait!(D21Pin, Instance);
315pin_trait!(D22Pin, Instance);
316pin_trait!(D23Pin, Instance);
317pin_trait!(D24Pin, Instance);
318pin_trait!(D25Pin, Instance);
319pin_trait!(D26Pin, Instance);
320pin_trait!(D27Pin, Instance);
321pin_trait!(D28Pin, Instance);
322pin_trait!(D29Pin, Instance);
323pin_trait!(D30Pin, Instance);
324pin_trait!(D31Pin, Instance);
325
326pin_trait!(DA0Pin, Instance);
327pin_trait!(DA1Pin, Instance);
328pin_trait!(DA2Pin, Instance);
329pin_trait!(DA3Pin, Instance);
330pin_trait!(DA4Pin, Instance);
331pin_trait!(DA5Pin, Instance);
332pin_trait!(DA6Pin, Instance);
333pin_trait!(DA7Pin, Instance);
334pin_trait!(DA8Pin, Instance);
335pin_trait!(DA9Pin, Instance);
336pin_trait!(DA10Pin, Instance);
337pin_trait!(DA11Pin, Instance);
338pin_trait!(DA12Pin, Instance);
339pin_trait!(DA13Pin, Instance);
340pin_trait!(DA14Pin, Instance);
341pin_trait!(DA15Pin, Instance);
342
343pin_trait!(A0Pin, Instance);
344pin_trait!(A1Pin, Instance);
345pin_trait!(A2Pin, Instance);
346pin_trait!(A3Pin, Instance);
347pin_trait!(A4Pin, Instance);
348pin_trait!(A5Pin, Instance);
349pin_trait!(A6Pin, Instance);
350pin_trait!(A7Pin, Instance);
351pin_trait!(A8Pin, Instance);
352pin_trait!(A9Pin, Instance);
353pin_trait!(A10Pin, Instance);
354pin_trait!(A11Pin, Instance);
355pin_trait!(A12Pin, Instance);
356pin_trait!(A13Pin, Instance);
357pin_trait!(A14Pin, Instance);
358pin_trait!(A15Pin, Instance);
359pin_trait!(A16Pin, Instance);
360pin_trait!(A17Pin, Instance);
361pin_trait!(A18Pin, Instance);
362pin_trait!(A19Pin, Instance);
363pin_trait!(A20Pin, Instance);
364pin_trait!(A21Pin, Instance);
365pin_trait!(A22Pin, Instance);
366pin_trait!(A23Pin, Instance);
367pin_trait!(A24Pin, Instance);
368pin_trait!(A25Pin, Instance);