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