1use stm32_fmc::FmcPeripheral;
7use stm32_fmc::{AddressPinSet, PinsSdram, Sdram, SdramChip, SdramPinSet, SdramTargetBank};
8
9use crate::pac;
10use crate::rcc::{BusClock, Clocks, Enable, Reset};
11use fugit::HertzU32 as Hertz;
12
13use crate::gpio::{self, Alternate};
14
15pub struct FMC {
17 pub fmc: pac::FMC,
18 hclk: Hertz,
19}
20
21pub trait FmcExt: Sized {
23 fn fmc(self, clocks: &Clocks) -> FMC;
24
25 fn sdram<
27 BANK: SdramPinSet,
28 ADDR: AddressPinSet,
29 PINS: PinsSdram<BANK, ADDR>,
30 CHIP: SdramChip,
31 >(
32 self,
33 pins: PINS,
34 chip: CHIP,
35 clocks: &Clocks,
36 ) -> Sdram<FMC, CHIP> {
37 let fmc = self.fmc(clocks);
38 Sdram::new(fmc, pins, chip)
39 }
40
41 fn sdram_unchecked<CHIP: SdramChip, BANK: Into<SdramTargetBank>>(
43 self,
44 bank: BANK,
45 chip: CHIP,
46 clocks: &Clocks,
47 ) -> Sdram<FMC, CHIP> {
48 let fmc = self.fmc(clocks);
49 Sdram::new_unchecked(fmc, bank, chip)
50 }
51}
52
53impl FmcExt for pac::FMC {
54 fn fmc(self, clocks: &Clocks) -> FMC {
56 FMC {
57 fmc: self,
58 hclk: pac::FMC::clock(clocks),
59 }
60 }
61}
62
63unsafe impl FmcPeripheral for FMC {
64 const REGISTERS: *const () = pac::FMC::ptr() as *const ();
65
66 fn enable(&mut self) {
67 unsafe {
69 pac::FMC::enable_unchecked();
71 pac::FMC::reset_unchecked();
73 }
74 }
75
76 fn source_clock_hz(&self) -> u32 {
77 self.hclk.raw()
79 }
80}
81
82macro_rules! pins {
83 (FMC: $($pin:ident: [$($( #[ $pmeta:meta ] )* $inst:ty$(,)*)*])+) => {
84 $(
85 $(
86 $( #[ $pmeta ] )*
87 impl stm32_fmc::$pin for $inst {}
88 )*
89 )+
90 }
91}
92
93pins! {
94 FMC:
95 A0: [
96 gpio::PF0<Alternate<12>>
97 ]
98 A1: [
99 gpio::PF1<Alternate<12>>
100 ]
101 A10: [
102 gpio::PG0<Alternate<12>>
103 ]
104 A11: [
105 gpio::PG1<Alternate<12>>
106 ]
107 A12: [
108 gpio::PG2<Alternate<12>>
109 ]
110 A13: [
111 gpio::PG3<Alternate<12>>
112 ]
113 A14: [
114 gpio::PG4<Alternate<12>>
115 ]
116 A15: [
117 gpio::PG5<Alternate<12>>
118 ]
119 A16: [
120 gpio::PD11<Alternate<12>>
121 ]
122 A17: [
123 gpio::PD12<Alternate<12>>
124 ]
125 A18: [
126 gpio::PD13<Alternate<12>>
127 ]
128 A19: [
129 gpio::PE3<Alternate<12>>
130 ]
131 A2: [
132 gpio::PF2<Alternate<12>>
133 ]
134 A20: [
135 gpio::PE4<Alternate<12>>
136 ]
137 A21: [
138 gpio::PE5<Alternate<12>>
139 ]
140 A22: [
141 gpio::PE6<Alternate<12>>
142 ]
143 A23: [
144 gpio::PE2<Alternate<12>>
145 ]
146 A24: [
147 gpio::PG13<Alternate<12>>
148 ]
149 A25: [
150 gpio::PG14<Alternate<12>>
151 ]
152 A3: [
153 gpio::PF3<Alternate<12>>
154 ]
155 A4: [
156 gpio::PF4<Alternate<12>>
157 ]
158 A5: [
159 gpio::PF5<Alternate<12>>
160 ]
161 A6: [
162 gpio::PF12<Alternate<12>>
163 ]
164 A7: [
165 gpio::PF13<Alternate<12>>
166 ]
167 A8: [
168 gpio::PF14<Alternate<12>>
169 ]
170 A9: [
171 gpio::PF15<Alternate<12>>
172 ]
173 BA0: [
174 gpio::PG4<Alternate<12>>
175 ]
176 BA1: [
177 gpio::PG5<Alternate<12>>
178 ]
179 CLK: [
180 gpio::PD3<Alternate<12>>
181 ]
182 D0: [
183 gpio::PD14<Alternate<12>>
184 ]
185 D1: [
186 gpio::PD15<Alternate<12>>
187 ]
188 D10: [
189 gpio::PE13<Alternate<12>>
190 ]
191 D11: [
192 gpio::PE14<Alternate<12>>
193 ]
194 D12: [
195 gpio::PE15<Alternate<12>>
196 ]
197 D13: [
198 gpio::PD8<Alternate<12>>
199 ]
200 D14: [
201 gpio::PD9<Alternate<12>>
202 ]
203 D15: [
204 gpio::PD10<Alternate<12>>
205 ]
206 D16: [
207 gpio::PH8<Alternate<12>>,
208 ]
209 D17: [
210 gpio::PH9<Alternate<12>>,
211 ]
212 D18: [
213 gpio::PH10<Alternate<12>>,
214 ]
215 D19: [
216 gpio::PH11<Alternate<12>>,
217 ]
218 D2: [
219 gpio::PD0<Alternate<12>>
220 ]
221 D20: [
222 gpio::PH12<Alternate<12>>,
223 ]
224 D21: [
225 gpio::PH13<Alternate<12>>,
226 ]
227 D22: [
228 gpio::PH14<Alternate<12>>,
229 ]
230 D23: [
231 gpio::PH15<Alternate<12>>,
232 ]
233 D24: [
234 gpio::PI0<Alternate<12>>
235 ]
236 D25: [
237 gpio::PI1<Alternate<12>>
238 ]
239 D26: [
240 gpio::PI2<Alternate<12>>,
241 ]
242 D27: [
243 gpio::PI3<Alternate<12>>
244 ]
245 D28: [
246 gpio::PI6<Alternate<12>>
247 ]
248 D29: [
249 gpio::PI7<Alternate<12>>
250 ]
251 D3: [
252 gpio::PD1<Alternate<12>>
253 ]
254 D30: [
255 gpio::PI9<Alternate<12>>
256 ]
257 D31: [
258 gpio::PI10<Alternate<12>>
259 ]
260 D4: [
261 gpio::PE7<Alternate<12>>
262 ]
263 D5: [
264 gpio::PE8<Alternate<12>>
265 ]
266 D6: [
267 gpio::PE9<Alternate<12>>
268 ]
269 D7: [
270 gpio::PE10<Alternate<12>>
271 ]
272 D8: [
273 gpio::PE11<Alternate<12>>
274 ]
275 D9: [
276 gpio::PE12<Alternate<12>>
277 ]
278 DA0: [
279 gpio::PD14<Alternate<12>>
280 ]
281 DA1: [
282 gpio::PD15<Alternate<12>>
283 ]
284 DA10: [
285 gpio::PE13<Alternate<12>>
286 ]
287 DA11: [
288 gpio::PE14<Alternate<12>>
289 ]
290 DA12: [
291 gpio::PE15<Alternate<12>>
292 ]
293 DA13: [
294 gpio::PD8<Alternate<12>>
295 ]
296 DA14: [
297 gpio::PD9<Alternate<12>>
298 ]
299 DA15: [
300 gpio::PD10<Alternate<12>>
301 ]
302 DA2: [
303 gpio::PD0<Alternate<12>>
304 ]
305 DA3: [
306 gpio::PD1<Alternate<12>>
307 ]
308 DA4: [
309 gpio::PE7<Alternate<12>>
310 ]
311 DA5: [
312 gpio::PE8<Alternate<12>>
313 ]
314 DA6: [
315 gpio::PE9<Alternate<12>>
316 ]
317 DA7: [
318 gpio::PE10<Alternate<12>>
319 ]
320 DA8: [
321 gpio::PE11<Alternate<12>>
322 ]
323 DA9: [
324 gpio::PE12<Alternate<12>>
325 ]
326 INT: [
327 gpio::PG7<Alternate<12>>,
328 #[cfg(any(feature = "stm32f722",
329 feature = "stm32f723",
330 feature = "stm32f730",
331 feature = "stm32f732",
332 feature = "stm32f733"))]
333 gpio::PG11<Alternate<12>>
334 ]
335 NBL0: [
336 gpio::PE0<Alternate<12>>
337 ]
338 NBL1: [
339 gpio::PE1<Alternate<12>>
340 ]
341 NBL2: [
342 gpio::PI4<Alternate<12>>
343 ]
344 NBL3: [
345 gpio::PI5<Alternate<12>>
346 ]
347 NCE: [
348 #[cfg(any(feature = "stm32f765",
349 feature = "stm32f767",
350 feature = "stm32f769",
351 feature = "stm32f777",
352 feature = "stm32f778",
353 feature = "stm32f779"))]
354 gpio::PC8<Alternate<9>>,
355 gpio::PG9<Alternate<12>>
356 ]
357 NE1: [
358 #[cfg(any(feature = "stm32f765",
359 feature = "stm32f767",
360 feature = "stm32f769",
361 feature = "stm32f777",
362 feature = "stm32f778",
363 feature = "stm32f779"))]
364 gpio::PC7<Alternate<9>>,
365 gpio::PD7<Alternate<12>>
366 ]
367 NE2: [
368 #[cfg(any(feature = "stm32f765",
369 feature = "stm32f767",
370 feature = "stm32f769",
371 feature = "stm32f777",
372 feature = "stm32f778",
373 feature = "stm32f779"))]
374 gpio::PC8<Alternate<9>>,
375 gpio::PG9<Alternate<12>>
376 ]
377 NE3: [
378 #[cfg(any(feature = "stm32f765",
379 feature = "stm32f767",
380 feature = "stm32f769",
381 feature = "stm32f777",
382 feature = "stm32f778",
383 feature = "stm32f779"))]
384 gpio::PG6<Alternate<12>>,
385 gpio::PG10<Alternate<12>>
386 ]
387 NE4: [
388 gpio::PG12<Alternate<12>>
389 ]
390 NL: [
391 gpio::PB7<Alternate<12>>
392 ]
393 NOE: [
394 gpio::PD4<Alternate<12>>
395 ]
396 NWAIT: [
397 #[cfg(any(feature = "stm32f765",
398 feature = "stm32f767",
399 feature = "stm32f769",
400 feature = "stm32f777",
401 feature = "stm32f778",
402 feature = "stm32f779"))]
403 gpio::PC6<Alternate<9>>,
404 gpio::PD6<Alternate<12>>
405 ]
406 NWE: [
407 gpio::PD5<Alternate<12>>
408 ]
409 SDCKE0: [
410 gpio::PC3<Alternate<12>>,
411 gpio::PC5<Alternate<12>>,
412 gpio::PH2<Alternate<12>>
413 ]
414 SDCKE1: [
415 gpio::PB5<Alternate<12>>,
416 gpio::PH7<Alternate<12>>
417 ]
418 SDCLK: [
419 gpio::PG8<Alternate<12>>
420 ]
421 SDNCAS: [
422 gpio::PG15<Alternate<12>>
423 ]
424 SDNE0: [
425 gpio::PC2<Alternate<12>>,
426 gpio::PC4<Alternate<12>>,
427 gpio::PH3<Alternate<12>>
428 ]
429 SDNE1: [
430 gpio::PB6<Alternate<12>>,
431 gpio::PH6<Alternate<12>>
432 ]
433 SDNRAS: [
434 gpio::PF11<Alternate<12>>
435 ]
436 SDNWE: [
437 gpio::PA7<Alternate<12>>,
438 gpio::PC0<Alternate<12>>,
439 gpio::PH5<Alternate<12>>
440 ]
441}