aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatous Hybl <[email protected]>2022-02-08 14:32:18 +0100
committerMatous Hybl <[email protected]>2022-02-08 17:30:20 +0100
commitd37d714314093747c9042faefcc3a22e2bfee59d (patch)
tree16f9b8ce5d8e58f7b6cf32f8071f394795f8300b
parentfee1de109dc5a81ee4e2a74403faec0923e0369e (diff)
stm32: Add support for FMC
-rw-r--r--embassy-stm32/Cargo.toml1
-rw-r--r--embassy-stm32/src/fmc/mod.rs145
-rw-r--r--embassy-stm32/src/fmc/pins.rs672
-rw-r--r--embassy-stm32/src/lib.rs2
-rw-r--r--examples/stm32h7/Cargo.toml3
-rw-r--r--examples/stm32h7/src/bin/fmc.rs204
-rw-r--r--examples/stm32h7/src/example_common.rs1
7 files changed, 1027 insertions, 1 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 1aa665fb6..edee4e3a5 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -30,6 +30,7 @@ stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", features = ["rt"
30vcell = { version = "0.1.3", optional = true } 30vcell = { version = "0.1.3", optional = true }
31bxcan = "0.6.2" 31bxcan = "0.6.2"
32nb = "1.0.0" 32nb = "1.0.0"
33stm32-fmc = "0.2.4"
33seq-macro = "0.2.2" 34seq-macro = "0.2.2"
34cfg-if = "1.0.0" 35cfg-if = "1.0.0"
35 36
diff --git a/embassy-stm32/src/fmc/mod.rs b/embassy-stm32/src/fmc/mod.rs
new file mode 100644
index 000000000..afdb45af9
--- /dev/null
+++ b/embassy-stm32/src/fmc/mod.rs
@@ -0,0 +1,145 @@
1mod pins;
2
3use core::marker::PhantomData;
4
5use embassy::util::Unborrow;
6use embassy_hal_common::unborrow;
7
8use pins::*;
9
10pub 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
16unsafe impl<'d, T> stm32_fmc::FmcPeripheral for Fmc<'d, T>
17where
18 T: Instance,
19{
20 const REGISTERS: *const () = crate::pac::FMC.0 as *const _;
21
22 fn enable(&mut self) {
23 <T as crate::rcc::sealed::RccPeripheral>::enable();
24 <T as crate::rcc::sealed::RccPeripheral>::reset();
25 }
26
27 fn memory_controller_enable(&mut self) {
28 // The FMCEN bit of the FMC_BCR2..4 registers is don’t
29 // care. It is only enabled through the FMC_BCR1 register.
30 unsafe { T::regs().bcr1().modify(|r| r.set_fmcen(true)) };
31 }
32
33 fn source_clock_hz(&self) -> u32 {
34 <T as crate::rcc::sealed::RccPeripheral>::frequency().0
35 }
36}
37macro_rules! config_pins {
38 ($($pin:ident),*) => {
39 $(
40 $pin.configure();
41 )*
42};
43}
44
45macro_rules! fmc_sdram_constructor {
46 ($name:ident: (
47 addr: [$(($addr_pin_name:ident: $addr_signal:ident)),*],
48 ba: [$(($ba_pin_name:ident: $ba_signal:ident)),*],
49 d: [$(($d_pin_name:ident: $d_signal:ident)),*],
50 nbl: [$(($nbl_pin_name:ident: $nbl_signal:ident)),*],
51 ctrl: [$(($ctrl_pin_name:ident: $ctrl_signal:ident)),*]
52 )) => {
53 pub fn $name<CHIP: stm32_fmc::SdramChip>(
54 _instance: impl Unborrow<Target = T> + 'd,
55 $($addr_pin_name: impl Unborrow<Target = impl $addr_signal> + 'd),*,
56 $($ba_pin_name: impl Unborrow<Target = impl $ba_signal> + 'd),*,
57 $($d_pin_name: impl Unborrow<Target = impl $d_signal> + 'd),*,
58 $($nbl_pin_name: impl Unborrow<Target = impl $nbl_signal> + 'd),*,
59 $($ctrl_pin_name: impl Unborrow<Target = impl $ctrl_signal> + 'd),*,
60 chip: CHIP
61 ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
62 unborrow!(
63 $($addr_pin_name),*,
64 $($ba_pin_name),*,
65 $($d_pin_name),*,
66 $($nbl_pin_name),*,
67 $($ctrl_pin_name),*
68 );
69
70 config_pins!(
71 $($addr_pin_name),*,
72 $($ba_pin_name),*,
73 $($d_pin_name),*,
74 $($nbl_pin_name),*,
75 $($ctrl_pin_name),*
76 );
77
78 let fmc = Self { peri: PhantomData };
79 stm32_fmc::Sdram::new(
80 fmc,
81 (
82 $($addr_pin_name),*,
83 $($ba_pin_name),*,
84 $($d_pin_name),*,
85 $($nbl_pin_name),*,
86 $($ctrl_pin_name),*,
87 ),
88 chip,
89 )
90 }
91 };
92}
93
94impl<'d, T: Instance> Fmc<'d, T> {
95 fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank1: (
96 addr: [
97 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
98 ],
99 ba: [(ba0: BA0Pin), (ba1: BA1Pin)],
100 d: [
101 (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin),
102 (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin),
103 (d16: D16Pin), (d17: D17Pin), (d18: D18Pin), (d19: D19Pin), (d20: D20Pin), (d21: D21Pin), (d22: D22Pin), (d23: D23Pin),
104 (d24: D24Pin), (d25: D25Pin), (d26: D26Pin), (d27: D27Pin), (d28: D28Pin), (d29: D29Pin), (d30: D30Pin), (d31: D31Pin)
105 ],
106 nbl: [
107 (nbl0: NBL0Pin), (nbl1: NBL1Pin), (nbl2: NBL2Pin), (nbl3: NBL3Pin)
108 ],
109 ctrl: [
110 (sdcke: SDCKE0Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE0Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
111 ]
112 ));
113
114 fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank2: (
115 addr: [
116 (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin)
117 ],
118 ba: [(ba0: BA0Pin), (ba1: BA1Pin)],
119 d: [
120 (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin),
121 (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin),
122 (d16: D16Pin), (d17: D17Pin), (d18: D18Pin), (d19: D19Pin), (d20: D20Pin), (d21: D21Pin), (d22: D22Pin), (d23: D23Pin),
123 (d24: D24Pin), (d25: D25Pin), (d26: D26Pin), (d27: D27Pin), (d28: D28Pin), (d29: D29Pin), (d30: D30Pin), (d31: D31Pin)
124 ],
125 nbl: [
126 (nbl0: NBL0Pin), (nbl1: NBL1Pin), (nbl2: NBL2Pin), (nbl3: NBL3Pin)
127 ],
128 ctrl: [
129 (sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
130 ]
131 ));
132}
133
134pub trait Instance: sealed::Instance + 'static {}
135
136crate::pac::peripherals!(
137 (fmc, $inst:ident) => {
138 impl crate::fmc::sealed::Instance for crate::peripherals::$inst {
139 fn regs() -> stm32_metapac::fmc::Fmc {
140 crate::pac::$inst
141 }
142 }
143 impl crate::fmc::Instance for crate::peripherals::$inst {}
144 };
145);
diff --git a/embassy-stm32/src/fmc/pins.rs b/embassy-stm32/src/fmc/pins.rs
new file mode 100644
index 000000000..c42c2792f
--- /dev/null
+++ b/embassy-stm32/src/fmc/pins.rs
@@ -0,0 +1,672 @@
1pub(crate) mod sealed {
2 pub trait Instance: crate::rcc::sealed::RccPeripheral {
3 fn regs() -> crate::pac::fmc::Fmc;
4 }
5
6 macro_rules! declare_pin {
7 ($name:ident) => {
8 pub trait $name {
9 fn configure(&mut self);
10 }
11 };
12 }
13
14 declare_pin!(SDNWEPin);
15 declare_pin!(SDNCASPin);
16 declare_pin!(SDNRASPin);
17
18 declare_pin!(SDNE0Pin);
19 declare_pin!(SDNE1Pin);
20
21 declare_pin!(SDCKE0Pin);
22 declare_pin!(SDCKE1Pin);
23
24 declare_pin!(SDCLKPin);
25
26 declare_pin!(NBL0Pin);
27 declare_pin!(NBL1Pin);
28 declare_pin!(NBL2Pin);
29 declare_pin!(NBL3Pin);
30
31 declare_pin!(INTPin);
32 declare_pin!(NLPin);
33 declare_pin!(NWaitPin);
34
35 declare_pin!(NE1Pin);
36 declare_pin!(NE2Pin);
37 declare_pin!(NE3Pin);
38 declare_pin!(NE4Pin);
39
40 declare_pin!(NCEPin);
41 declare_pin!(NOEPin);
42 declare_pin!(NWEPin);
43 declare_pin!(ClkPin);
44
45 declare_pin!(BA0Pin);
46 declare_pin!(BA1Pin);
47
48 declare_pin!(D0Pin);
49 declare_pin!(D1Pin);
50 declare_pin!(D2Pin);
51 declare_pin!(D3Pin);
52 declare_pin!(D4Pin);
53 declare_pin!(D5Pin);
54 declare_pin!(D6Pin);
55 declare_pin!(D7Pin);
56 declare_pin!(D8Pin);
57 declare_pin!(D9Pin);
58 declare_pin!(D10Pin);
59 declare_pin!(D11Pin);
60 declare_pin!(D12Pin);
61 declare_pin!(D13Pin);
62 declare_pin!(D14Pin);
63 declare_pin!(D15Pin);
64 declare_pin!(D16Pin);
65 declare_pin!(D17Pin);
66 declare_pin!(D18Pin);
67 declare_pin!(D19Pin);
68 declare_pin!(D20Pin);
69 declare_pin!(D21Pin);
70 declare_pin!(D22Pin);
71 declare_pin!(D23Pin);
72 declare_pin!(D24Pin);
73 declare_pin!(D25Pin);
74 declare_pin!(D26Pin);
75 declare_pin!(D27Pin);
76 declare_pin!(D28Pin);
77 declare_pin!(D29Pin);
78 declare_pin!(D30Pin);
79 declare_pin!(D31Pin);
80
81 declare_pin!(DA0Pin);
82 declare_pin!(DA1Pin);
83 declare_pin!(DA2Pin);
84 declare_pin!(DA3Pin);
85 declare_pin!(DA4Pin);
86 declare_pin!(DA5Pin);
87 declare_pin!(DA6Pin);
88 declare_pin!(DA7Pin);
89 declare_pin!(DA8Pin);
90 declare_pin!(DA9Pin);
91 declare_pin!(DA10Pin);
92 declare_pin!(DA11Pin);
93 declare_pin!(DA12Pin);
94 declare_pin!(DA13Pin);
95 declare_pin!(DA14Pin);
96 declare_pin!(DA15Pin);
97
98 declare_pin!(A0Pin);
99 declare_pin!(A1Pin);
100 declare_pin!(A2Pin);
101 declare_pin!(A3Pin);
102 declare_pin!(A4Pin);
103 declare_pin!(A5Pin);
104 declare_pin!(A6Pin);
105 declare_pin!(A7Pin);
106 declare_pin!(A8Pin);
107 declare_pin!(A9Pin);
108 declare_pin!(A10Pin);
109 declare_pin!(A11Pin);
110 declare_pin!(A12Pin);
111 declare_pin!(A13Pin);
112 declare_pin!(A14Pin);
113 declare_pin!(A15Pin);
114 declare_pin!(A16Pin);
115 declare_pin!(A17Pin);
116 declare_pin!(A18Pin);
117 declare_pin!(A19Pin);
118 declare_pin!(A20Pin);
119 declare_pin!(A21Pin);
120 declare_pin!(A22Pin);
121 declare_pin!(A23Pin);
122 declare_pin!(A24Pin);
123 declare_pin!(A25Pin);
124}
125
126macro_rules! declare_pin {
127 ($name:ident, $fmc_pin:ident) => {
128 pub trait $name: sealed::$name + stm32_fmc::$fmc_pin + 'static {}
129 };
130}
131
132declare_pin!(SDNWEPin, SDNWE);
133declare_pin!(SDNCASPin, SDNCAS);
134declare_pin!(SDNRASPin, SDNRAS);
135
136declare_pin!(SDNE0Pin, SDNE0);
137declare_pin!(SDNE1Pin, SDNE1);
138
139declare_pin!(SDCKE0Pin, SDCKE0);
140declare_pin!(SDCKE1Pin, SDCKE1);
141
142declare_pin!(SDCLKPin, SDCLK);
143
144declare_pin!(NBL0Pin, NBL0);
145declare_pin!(NBL1Pin, NBL1);
146declare_pin!(NBL2Pin, NBL2);
147declare_pin!(NBL3Pin, NBL3);
148
149declare_pin!(INTPin, INT);
150declare_pin!(NLPin, NL);
151declare_pin!(NWaitPin, NWAIT);
152
153declare_pin!(NE1Pin, NE1);
154declare_pin!(NE2Pin, NE2);
155declare_pin!(NE3Pin, NE3);
156declare_pin!(NE4Pin, NE4);
157
158declare_pin!(NCEPin, NCE);
159declare_pin!(NOEPin, NOE);
160declare_pin!(NWEPin, NWE);
161declare_pin!(ClkPin, CLK);
162
163declare_pin!(BA0Pin, BA0);
164declare_pin!(BA1Pin, BA1);
165
166declare_pin!(D0Pin, D0);
167declare_pin!(D1Pin, D1);
168declare_pin!(D2Pin, D2);
169declare_pin!(D3Pin, D3);
170declare_pin!(D4Pin, D4);
171declare_pin!(D5Pin, D5);
172declare_pin!(D6Pin, D6);
173declare_pin!(D7Pin, D7);
174declare_pin!(D8Pin, D8);
175declare_pin!(D9Pin, D9);
176declare_pin!(D10Pin, D10);
177declare_pin!(D11Pin, D11);
178declare_pin!(D12Pin, D12);
179declare_pin!(D13Pin, D13);
180declare_pin!(D14Pin, D14);
181declare_pin!(D15Pin, D15);
182declare_pin!(D16Pin, D16);
183declare_pin!(D17Pin, D17);
184declare_pin!(D18Pin, D18);
185declare_pin!(D19Pin, D19);
186declare_pin!(D20Pin, D20);
187declare_pin!(D21Pin, D21);
188declare_pin!(D22Pin, D22);
189declare_pin!(D23Pin, D23);
190declare_pin!(D24Pin, D24);
191declare_pin!(D25Pin, D25);
192declare_pin!(D26Pin, D26);
193declare_pin!(D27Pin, D27);
194declare_pin!(D28Pin, D28);
195declare_pin!(D29Pin, D29);
196declare_pin!(D30Pin, D30);
197declare_pin!(D31Pin, D31);
198
199declare_pin!(DA0Pin, DA0);
200declare_pin!(DA1Pin, DA1);
201declare_pin!(DA2Pin, DA2);
202declare_pin!(DA3Pin, DA3);
203declare_pin!(DA4Pin, DA4);
204declare_pin!(DA5Pin, DA5);
205declare_pin!(DA6Pin, DA6);
206declare_pin!(DA7Pin, DA7);
207declare_pin!(DA8Pin, DA8);
208declare_pin!(DA9Pin, DA9);
209declare_pin!(DA10Pin, DA10);
210declare_pin!(DA11Pin, DA11);
211declare_pin!(DA12Pin, DA12);
212declare_pin!(DA13Pin, DA13);
213declare_pin!(DA14Pin, DA14);
214declare_pin!(DA15Pin, DA15);
215
216declare_pin!(A0Pin, A0);
217declare_pin!(A1Pin, A1);
218declare_pin!(A2Pin, A2);
219declare_pin!(A3Pin, A3);
220declare_pin!(A4Pin, A4);
221declare_pin!(A5Pin, A5);
222declare_pin!(A6Pin, A6);
223declare_pin!(A7Pin, A7);
224declare_pin!(A8Pin, A8);
225declare_pin!(A9Pin, A9);
226declare_pin!(A10Pin, A10);
227declare_pin!(A11Pin, A11);
228declare_pin!(A12Pin, A12);
229declare_pin!(A13Pin, A13);
230declare_pin!(A14Pin, A14);
231declare_pin!(A15Pin, A15);
232declare_pin!(A16Pin, A16);
233declare_pin!(A17Pin, A17);
234declare_pin!(A18Pin, A18);
235declare_pin!(A19Pin, A19);
236declare_pin!(A20Pin, A20);
237declare_pin!(A21Pin, A21);
238declare_pin!(A22Pin, A22);
239declare_pin!(A23Pin, A23);
240declare_pin!(A24Pin, A24);
241declare_pin!(A25Pin, A25);
242
243macro_rules! impl_pin {
244 ($pin:ident, $signal:ident, $fmc_name:ident, $af:expr) => {
245 impl sealed::$signal for crate::peripherals::$pin {
246 fn configure(&mut self) {
247 use crate::gpio::sealed::{AFType::OutputPushPull, Pin as SealedPin};
248 use crate::gpio::Pin;
249 use crate::gpio::Speed;
250 use crate::pac::gpio::vals::Pupdr;
251
252 critical_section::with(|_| unsafe {
253 self.set_as_af($af, OutputPushPull);
254 self.set_speed(Speed::VeryHigh);
255
256 self.block()
257 .pupdr()
258 .modify(|w| w.set_pupdr(self.pin() as usize, Pupdr::PULLUP));
259 })
260 }
261 }
262
263 impl stm32_fmc::$fmc_name for crate::peripherals::$pin {}
264
265 impl $signal for crate::peripherals::$pin {}
266 };
267}
268
269crate::pac::peripheral_pins!(
270 ($inst:ident, fmc, FMC, $pin:ident, A0, $af:expr) => {
271 impl_pin!($pin, A0Pin, A0, $af);
272 };
273
274 ($inst:ident, fmc, FMC, $pin:ident, A1, $af:expr) => {
275 impl_pin!($pin, A1Pin, A1, $af);
276 };
277
278 ($inst:ident, fmc, FMC, $pin:ident, A2, $af:expr) => {
279 impl_pin!($pin, A2Pin, A2, $af);
280 };
281
282 ($inst:ident, fmc, FMC, $pin:ident, A3, $af:expr) => {
283 impl_pin!($pin, A3Pin, A3, $af);
284 };
285
286 ($inst:ident, fmc, FMC, $pin:ident, A4, $af:expr) => {
287 impl_pin!($pin, A4Pin, A4, $af);
288 };
289
290 ($inst:ident, fmc, FMC, $pin:ident, A5, $af:expr) => {
291 impl_pin!($pin, A5Pin, A5, $af);
292 };
293
294 ($inst:ident, fmc, FMC, $pin:ident, A6, $af:expr) => {
295 impl_pin!($pin, A6Pin, A6, $af);
296 };
297
298 ($inst:ident, fmc, FMC, $pin:ident, A7, $af:expr) => {
299 impl_pin!($pin, A7Pin, A7, $af);
300 };
301
302 ($inst:ident, fmc, FMC, $pin:ident, A8, $af:expr) => {
303 impl_pin!($pin, A8Pin, A8, $af);
304 };
305
306 ($inst:ident, fmc, FMC, $pin:ident, A9, $af:expr) => {
307 impl_pin!($pin, A9Pin, A9, $af);
308 };
309
310 ($inst:ident, fmc, FMC, $pin:ident, A10, $af:expr) => {
311 impl_pin!($pin, A10Pin, A10, $af);
312 };
313
314 ($inst:ident, fmc, FMC, $pin:ident, A11, $af:expr) => {
315 impl_pin!($pin, A11Pin, A11, $af);
316 };
317
318 ($inst:ident, fmc, FMC, $pin:ident, A12, $af:expr) => {
319 impl_pin!($pin, A12Pin, A12, $af);
320 };
321
322 ($inst:ident, fmc, FMC, $pin:ident, A13, $af:expr) => {
323 impl_pin!($pin, A13Pin, A13, $af);
324 };
325
326 ($inst:ident, fmc, FMC, $pin:ident, A14, $af:expr) => {
327 impl_pin!($pin, A14Pin, A14, $af);
328 };
329
330 ($inst:ident, fmc, FMC, $pin:ident, A15, $af:expr) => {
331 impl_pin!($pin, A15Pin, A15, $af);
332 };
333
334 ($inst:ident, fmc, FMC, $pin:ident, A16, $af:expr) => {
335 impl_pin!($pin, A16Pin, A16, $af);
336 };
337
338 ($inst:ident, fmc, FMC, $pin:ident, A17, $af:expr) => {
339 impl_pin!($pin, A17Pin, A17, $af);
340 };
341
342 ($inst:ident, fmc, FMC, $pin:ident, A18, $af:expr) => {
343 impl_pin!($pin, A18Pin, A18, $af);
344 };
345
346 ($inst:ident, fmc, FMC, $pin:ident, A19, $af:expr) => {
347 impl_pin!($pin, A19Pin, A19, $af);
348 };
349
350 ($inst:ident, fmc, FMC, $pin:ident, A20, $af:expr) => {
351 impl_pin!($pin, A20Pin, A20, $af);
352 };
353
354 ($inst:ident, fmc, FMC, $pin:ident, A21, $af:expr) => {
355 impl_pin!($pin, A21Pin, A21, $af);
356 };
357
358 ($inst:ident, fmc, FMC, $pin:ident, A22, $af:expr) => {
359 impl_pin!($pin, A22Pin, A22, $af);
360 };
361
362 ($inst:ident, fmc, FMC, $pin:ident, A23, $af:expr) => {
363 impl_pin!($pin, A23Pin, A23, $af);
364 };
365
366 ($inst:ident, fmc, FMC, $pin:ident, A24, $af:expr) => {
367 impl_pin!($pin, A24Pin, A24, $af);
368 };
369
370 ($inst:ident, fmc, FMC, $pin:ident, A25, $af:expr) => {
371 impl_pin!($pin, A25Pin, A25, $af);
372 };
373);
374
375crate::pac::peripheral_pins!(
376 ($inst:ident, fmc, FMC, $pin:ident, D0, $af:expr) => {
377 impl_pin!($pin, D0Pin, D0, $af);
378 };
379
380 ($inst:ident, fmc, FMC, $pin:ident, D1, $af:expr) => {
381 impl_pin!($pin, D1Pin, D1, $af);
382 };
383
384 ($inst:ident, fmc, FMC, $pin:ident, D2, $af:expr) => {
385 impl_pin!($pin, D2Pin, D2, $af);
386 };
387
388 ($inst:ident, fmc, FMC, $pin:ident, D3, $af:expr) => {
389 impl_pin!($pin, D3Pin, D3, $af);
390 };
391
392 ($inst:ident, fmc, FMC, $pin:ident, D4, $af:expr) => {
393 impl_pin!($pin, D4Pin, D4, $af);
394 };
395
396 ($inst:ident, fmc, FMC, $pin:ident, D5, $af:expr) => {
397 impl_pin!($pin, D5Pin, D5, $af);
398 };
399
400 ($inst:ident, fmc, FMC, $pin:ident, D6, $af:expr) => {
401 impl_pin!($pin, D6Pin, D6, $af);
402 };
403
404 ($inst:ident, fmc, FMC, $pin:ident, D7, $af:expr) => {
405 impl_pin!($pin, D7Pin, D7, $af);
406 };
407
408 ($inst:ident, fmc, FMC, $pin:ident, D8, $af:expr) => {
409 impl_pin!($pin, D8Pin, D8, $af);
410 };
411
412 ($inst:ident, fmc, FMC, $pin:ident, D9, $af:expr) => {
413 impl_pin!($pin, D9Pin, D9, $af);
414 };
415
416 ($inst:ident, fmc, FMC, $pin:ident, D10, $af:expr) => {
417 impl_pin!($pin, D10Pin, D10, $af);
418 };
419
420 ($inst:ident, fmc, FMC, $pin:ident, D11, $af:expr) => {
421 impl_pin!($pin, D11Pin, D11, $af);
422 };
423
424 ($inst:ident, fmc, FMC, $pin:ident, D12, $af:expr) => {
425 impl_pin!($pin, D12Pin, D12, $af);
426 };
427
428 ($inst:ident, fmc, FMC, $pin:ident, D13, $af:expr) => {
429 impl_pin!($pin, D13Pin, D13, $af);
430 };
431
432 ($inst:ident, fmc, FMC, $pin:ident, D14, $af:expr) => {
433 impl_pin!($pin, D14Pin, D14, $af);
434 };
435
436 ($inst:ident, fmc, FMC, $pin:ident, D15, $af:expr) => {
437 impl_pin!($pin, D15Pin, D15, $af);
438 };
439
440 ($inst:ident, fmc, FMC, $pin:ident, D16, $af:expr) => {
441 impl_pin!($pin, D16Pin, D16, $af);
442 };
443
444 ($inst:ident, fmc, FMC, $pin:ident, D17, $af:expr) => {
445 impl_pin!($pin, D17Pin, D17, $af);
446 };
447
448 ($inst:ident, fmc, FMC, $pin:ident, D18, $af:expr) => {
449 impl_pin!($pin, D18Pin, D18, $af);
450 };
451
452 ($inst:ident, fmc, FMC, $pin:ident, D19, $af:expr) => {
453 impl_pin!($pin, D19Pin, D19, $af);
454 };
455
456 ($inst:ident, fmc, FMC, $pin:ident, D20, $af:expr) => {
457 impl_pin!($pin, D20Pin, D20, $af);
458 };
459
460 ($inst:ident, fmc, FMC, $pin:ident, D21, $af:expr) => {
461 impl_pin!($pin, D21Pin, D21, $af);
462 };
463
464 ($inst:ident, fmc, FMC, $pin:ident, D22, $af:expr) => {
465 impl_pin!($pin, D22Pin, D22, $af);
466 };
467
468 ($inst:ident, fmc, FMC, $pin:ident, D23, $af:expr) => {
469 impl_pin!($pin, D23Pin, D23, $af);
470 };
471
472 ($inst:ident, fmc, FMC, $pin:ident, D24, $af:expr) => {
473 impl_pin!($pin, D24Pin, D24, $af);
474 };
475
476 ($inst:ident, fmc, FMC, $pin:ident, D25, $af:expr) => {
477 impl_pin!($pin, D25Pin, D25, $af);
478 };
479
480 ($inst:ident, fmc, FMC, $pin:ident, D26, $af:expr) => {
481 impl_pin!($pin, D26Pin, D26, $af);
482 };
483
484 ($inst:ident, fmc, FMC, $pin:ident, D27, $af:expr) => {
485 impl_pin!($pin, D27Pin, D27, $af);
486 };
487
488 ($inst:ident, fmc, FMC, $pin:ident, D28, $af:expr) => {
489 impl_pin!($pin, D28Pin, D28, $af);
490 };
491
492 ($inst:ident, fmc, FMC, $pin:ident, D29, $af:expr) => {
493 impl_pin!($pin, D29Pin, D29, $af);
494 };
495
496 ($inst:ident, fmc, FMC, $pin:ident, D30, $af:expr) => {
497 impl_pin!($pin, D30Pin, D30, $af);
498 };
499
500 ($inst:ident, fmc, FMC, $pin:ident, D31, $af:expr) => {
501 impl_pin!($pin, D31Pin, D31, $af);
502 };
503);
504
505crate::pac::peripheral_pins!(
506 ($inst:ident, fmc, FMC, $pin:ident, DA0, $af:expr) => {
507 impl_pin!($pin, DA0Pin, DA0, $af);
508 };
509
510 ($inst:ident, fmc, FMC, $pin:ident, DA1, $af:expr) => {
511 impl_pin!($pin, DA1Pin, DA1, $af);
512 };
513
514 ($inst:ident, fmc, FMC, $pin:ident, DA2, $af:expr) => {
515 impl_pin!($pin, DA2Pin, DA2, $af);
516 };
517
518 ($inst:ident, fmc, FMC, $pin:ident, DA3, $af:expr) => {
519 impl_pin!($pin, DA3Pin, DA3, $af);
520 };
521
522 ($inst:ident, fmc, FMC, $pin:ident, DA4, $af:expr) => {
523 impl_pin!($pin, DA4Pin, DA4, $af);
524 };
525
526 ($inst:ident, fmc, FMC, $pin:ident, DA5, $af:expr) => {
527 impl_pin!($pin, DA5Pin, DA5, $af);
528 };
529
530 ($inst:ident, fmc, FMC, $pin:ident, DA6, $af:expr) => {
531 impl_pin!($pin, DA6Pin, DA6, $af);
532 };
533
534 ($inst:ident, fmc, FMC, $pin:ident, DA7, $af:expr) => {
535 impl_pin!($pin, DA7Pin, DA7, $af);
536 };
537
538 ($inst:ident, fmc, FMC, $pin:ident, DA8, $af:expr) => {
539 impl_pin!($pin, DA8Pin, DA8, $af);
540 };
541
542 ($inst:ident, fmc, FMC, $pin:ident, DA9, $af:expr) => {
543 impl_pin!($pin, DA9Pin, DA9, $af);
544 };
545
546 ($inst:ident, fmc, FMC, $pin:ident, DA10, $af:expr) => {
547 impl_pin!($pin, DA10Pin, DA10, $af);
548 };
549
550 ($inst:ident, fmc, FMC, $pin:ident, DA11, $af:expr) => {
551 impl_pin!($pin, DA11Pin, DA11, $af);
552 };
553
554 ($inst:ident, fmc, FMC, $pin:ident, DA12, $af:expr) => {
555 impl_pin!($pin, DA12Pin, DA12, $af);
556 };
557
558 ($inst:ident, fmc, FMC, $pin:ident, DA13, $af:expr) => {
559 impl_pin!($pin, DA13Pin, DA13, $af);
560 };
561
562 ($inst:ident, fmc, FMC, $pin:ident, DA14, $af:expr) => {
563 impl_pin!($pin, DA14Pin, DA14, $af);
564 };
565
566 ($inst:ident, fmc, FMC, $pin:ident, DA15, $af:expr) => {
567 impl_pin!($pin, DA15Pin, DA15, $af);
568 };
569
570);
571
572crate::pac::peripheral_pins!(
573 ($inst:ident, fmc, FMC, $pin:ident, SDNWE, $af:expr) => {
574 impl_pin!($pin, SDNWEPin, SDNWE, $af);
575 };
576
577 ($inst:ident, fmc, FMC, $pin:ident, SDNCAS, $af:expr) => {
578 impl_pin!($pin, SDNCASPin, SDNCAS, $af);
579 };
580
581 ($inst:ident, fmc, FMC, $pin:ident, SDNRAS, $af:expr) => {
582 impl_pin!($pin, SDNRASPin, SDNRAS, $af);
583 };
584
585 ($inst:ident, fmc, FMC, $pin:ident, SDNE0, $af:expr) => {
586 impl_pin!($pin, SDNE0Pin, SDNE0, $af);
587 };
588
589 ($inst:ident, fmc, FMC, $pin:ident, SDNE1, $af:expr) => {
590 impl_pin!($pin, SDNE1Pin, SDNE1, $af);
591 };
592
593 ($inst:ident, fmc, FMC, $pin:ident, SDCKE0, $af:expr) => {
594 impl_pin!($pin, SDCKE0Pin, SDCKE0, $af);
595 };
596
597 ($inst:ident, fmc, FMC, $pin:ident, SDCKE1, $af:expr) => {
598 impl_pin!($pin, SDCKE1Pin, SDCKE1, $af);
599 };
600
601 ($inst:ident, fmc, FMC, $pin:ident, SDCLK, $af:expr) => {
602 impl_pin!($pin, SDCLKPin, SDCLK, $af);
603 };
604
605 ($inst:ident, fmc, FMC, $pin:ident, NBL0, $af:expr) => {
606 impl_pin!($pin, NBL0Pin, NBL0, $af);
607 };
608
609 ($inst:ident, fmc, FMC, $pin:ident, NBL1, $af:expr) => {
610 impl_pin!($pin, NBL1Pin, NBL1, $af);
611 };
612
613 ($inst:ident, fmc, FMC, $pin:ident, NBL2, $af:expr) => {
614 impl_pin!($pin, NBL2Pin, NBL2, $af);
615 };
616
617 ($inst:ident, fmc, FMC, $pin:ident, NBL3, $af:expr) => {
618 impl_pin!($pin, NBL3Pin, NBL3, $af);
619 };
620
621 ($inst:ident, fmc, FMC, $pin:ident, INT, $af:expr) => {
622 impl_pin!($pin, INTPin, INT, $af);
623 };
624
625 ($inst:ident, fmc, FMC, $pin:ident, NL, $af:expr) => {
626 impl_pin!($pin, NLPin, NL, $af);
627 };
628
629 ($inst:ident, fmc, FMC, $pin:ident, NWAIT, $af:expr) => {
630 impl_pin!($pin, NWaitPin, NWAIT, $af);
631 };
632
633 ($inst:ident, fmc, FMC, $pin:ident, NE1, $af:expr) => {
634 impl_pin!($pin, NE1Pin, NE1, $af);
635 };
636
637 ($inst:ident, fmc, FMC, $pin:ident, NE2, $af:expr) => {
638 impl_pin!($pin, NE2Pin, NE2, $af);
639 };
640
641 ($inst:ident, fmc, FMC, $pin:ident, NE3, $af:expr) => {
642 impl_pin!($pin, NE3Pin, NE3, $af);
643 };
644
645 ($inst:ident, fmc, FMC, $pin:ident, NE4, $af:expr) => {
646 impl_pin!($pin, NE4Pin, NE4, $af);
647 };
648
649 ($inst:ident, fmc, FMC, $pin:ident, NCE, $af:expr) => {
650 impl_pin!($pin, NCEPin, NCE, $af);
651 };
652
653 ($inst:ident, fmc, FMC, $pin:ident, NOE, $af:expr) => {
654 impl_pin!($pin, NOEPin, NOE, $af);
655 };
656
657 ($inst:ident, fmc, FMC, $pin:ident, NWE, $af:expr) => {
658 impl_pin!($pin, NWEPin, NWE, $af);
659 };
660
661 ($inst:ident, fmc, FMC, $pin:ident, Clk, $af:expr) => {
662 impl_pin!($pin, ClkPin, CLK, $af);
663 };
664
665 ($inst:ident, fmc, FMC, $pin:ident, BA0, $af:expr) => {
666 impl_pin!($pin, BA0Pin, BA0, $af);
667 };
668
669 ($inst:ident, fmc, FMC, $pin:ident, BA1, $af:expr) => {
670 impl_pin!($pin, BA1Pin, BA1, $af);
671 };
672);
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index dfc027733..75a4d22d8 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -36,6 +36,8 @@ pub mod dcmi;
36pub mod eth; 36pub mod eth;
37#[cfg(feature = "exti")] 37#[cfg(feature = "exti")]
38pub mod exti; 38pub mod exti;
39#[cfg(fmc)]
40pub mod fmc;
39#[cfg(i2c)] 41#[cfg(i2c)]
40pub mod i2c; 42pub mod i2c;
41 43
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 463dd83d5..59d99bbcb 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -9,7 +9,7 @@ resolver = "2"
9 9
10[dependencies] 10[dependencies]
11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } 11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
12embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } 12embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
13embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } 13embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] }
14embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] } 14embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] }
15 15
@@ -26,6 +26,7 @@ heapless = { version = "0.7.5", default-features = false }
26rand_core = "0.6.3" 26rand_core = "0.6.3"
27critical-section = "0.2.5" 27critical-section = "0.2.5"
28micromath = "2.0.0" 28micromath = "2.0.0"
29stm32-fmc = "0.2.4"
29 30
30[dependencies.smoltcp] 31[dependencies.smoltcp]
31version = "0.8.0" 32version = "0.8.0"
diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs
new file mode 100644
index 000000000..b9ac1318e
--- /dev/null
+++ b/examples/stm32h7/src/bin/fmc.rs
@@ -0,0 +1,204 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5#[path = "../example_common.rs"]
6mod example_common;
7use embassy::executor::Spawner;
8use embassy::time::{Delay, Duration, Timer};
9use embassy_stm32::fmc::Fmc;
10use embassy_stm32::Peripherals;
11use example_common::*;
12
13#[embassy::main(config = "config()")]
14async fn main(_spawner: Spawner, p: Peripherals) {
15 info!("Hello World!");
16
17 let mut core_peri = cortex_m::Peripherals::take().unwrap();
18
19 // taken from stm32h7xx-hal
20 core_peri.SCB.enable_icache();
21 // See Errata Sheet 2.2.1
22 // core_peri.SCB.enable_dcache(&mut core_peri.CPUID);
23 core_peri.DWT.enable_cycle_counter();
24 // ----------------------------------------------------------
25 // Configure MPU for external SDRAM
26 // MPU config for SDRAM write-through
27 let sdram_size = 32 * 1024 * 1024;
28
29 {
30 let mpu = core_peri.MPU;
31 let scb = &mut core_peri.SCB;
32 let size = sdram_size;
33 // Refer to ARM®v7-M Architecture Reference Manual ARM DDI 0403
34 // Version E.b Section B3.5
35 const MEMFAULTENA: u32 = 1 << 16;
36
37 unsafe {
38 /* Make sure outstanding transfers are done */
39 cortex_m::asm::dmb();
40
41 scb.shcsr.modify(|r| r & !MEMFAULTENA);
42
43 /* Disable the MPU and clear the control register*/
44 mpu.ctrl.write(0);
45 }
46
47 const REGION_NUMBER0: u32 = 0x00;
48 const REGION_BASE_ADDRESS: u32 = 0xD000_0000;
49
50 const REGION_FULL_ACCESS: u32 = 0x03;
51 const REGION_CACHEABLE: u32 = 0x01;
52 const REGION_WRITE_BACK: u32 = 0x01;
53 const REGION_ENABLE: u32 = 0x01;
54
55 crate::assert_eq!(
56 size & (size - 1),
57 0,
58 "SDRAM memory region size must be a power of 2"
59 );
60 crate::assert_eq!(
61 size & 0x1F,
62 0,
63 "SDRAM memory region size must be 32 bytes or more"
64 );
65 fn log2minus1(sz: u32) -> u32 {
66 for i in 5..=31 {
67 if sz == (1 << i) {
68 return i - 1;
69 }
70 }
71 crate::panic!("Unknown SDRAM memory region size!");
72 }
73
74 //info!("SDRAM Memory Size 0x{:x}", log2minus1(size as u32));
75
76 // Configure region 0
77 //
78 // Cacheable, outer and inner write-back, no write allocate. So
79 // reads are cached, but writes always write all the way to SDRAM
80 unsafe {
81 mpu.rnr.write(REGION_NUMBER0);
82 mpu.rbar.write(REGION_BASE_ADDRESS);
83 mpu.rasr.write(
84 (REGION_FULL_ACCESS << 24)
85 | (REGION_CACHEABLE << 17)
86 | (REGION_WRITE_BACK << 16)
87 | (log2minus1(size as u32) << 1)
88 | REGION_ENABLE,
89 );
90 }
91
92 const MPU_ENABLE: u32 = 0x01;
93 const MPU_DEFAULT_MMAP_FOR_PRIVILEGED: u32 = 0x04;
94
95 // Enable
96 unsafe {
97 mpu.ctrl
98 .modify(|r| r | MPU_DEFAULT_MMAP_FOR_PRIVILEGED | MPU_ENABLE);
99
100 scb.shcsr.modify(|r| r | MEMFAULTENA);
101
102 // Ensure MPU settings take effect
103 cortex_m::asm::dsb();
104 cortex_m::asm::isb();
105 }
106 }
107
108 let mut sdram = Fmc::sdram_a12bits_d32bits_4banks_bank2(
109 p.FMC,
110 // A0-A11
111 p.PF0,
112 p.PF1,
113 p.PF2,
114 p.PF3,
115 p.PF4,
116 p.PF5,
117 p.PF12,
118 p.PF13,
119 p.PF14,
120 p.PF15,
121 p.PG0,
122 p.PG1,
123 // BA0-BA1
124 p.PG4,
125 p.PG5,
126 // D0-D31
127 p.PD14,
128 p.PD15,
129 p.PD0,
130 p.PD1,
131 p.PE7,
132 p.PE8,
133 p.PE9,
134 p.PE10,
135 p.PE11,
136 p.PE12,
137 p.PE13,
138 p.PE14,
139 p.PE15,
140 p.PD8,
141 p.PD9,
142 p.PD10,
143 p.PH8,
144 p.PH9,
145 p.PH10,
146 p.PH11,
147 p.PH12,
148 p.PH13,
149 p.PH14,
150 p.PH15,
151 p.PI0,
152 p.PI1,
153 p.PI2,
154 p.PI3,
155 p.PI6,
156 p.PI7,
157 p.PI9,
158 p.PI10,
159 // NBL0 - NBL3
160 p.PE0,
161 p.PE1,
162 p.PI4,
163 p.PI5,
164 p.PH7, // SDCKE1
165 p.PG8, // SDCLK
166 p.PG15, // SDNCAS
167 p.PH6, // SDNE1 (!CS)
168 p.PF11, // SDRAS
169 p.PC0, // SDNWE, change to p.PH5 for EVAL boards
170 stm32_fmc::devices::is42s32800g_6::Is42s32800g {},
171 );
172
173 let mut delay = Delay;
174
175 let ram_slice = unsafe {
176 // Initialise controller and SDRAM
177 let ram_ptr: *mut u32 = sdram.init(&mut delay) as *mut _;
178
179 // Convert raw pointer to slice
180 core::slice::from_raw_parts_mut(ram_ptr, sdram_size / core::mem::size_of::<u32>())
181 };
182
183 // // ----------------------------------------------------------
184 // // Use memory in SDRAM
185 info!("RAM contents before writing: {:x}", ram_slice[..10]);
186
187 ram_slice[0] = 1;
188 ram_slice[1] = 2;
189 ram_slice[2] = 3;
190 ram_slice[3] = 4;
191
192 info!("RAM contents after writing: {:x}", ram_slice[..10]);
193
194 crate::assert_eq!(ram_slice[0], 1);
195 crate::assert_eq!(ram_slice[1], 2);
196 crate::assert_eq!(ram_slice[2], 3);
197 crate::assert_eq!(ram_slice[3], 4);
198
199 info!("Assertions succeeded.");
200
201 loop {
202 Timer::after(Duration::from_millis(1000)).await;
203 }
204}
diff --git a/examples/stm32h7/src/example_common.rs b/examples/stm32h7/src/example_common.rs
index 524bee6d9..b8acc2790 100644
--- a/examples/stm32h7/src/example_common.rs
+++ b/examples/stm32h7/src/example_common.rs
@@ -22,6 +22,7 @@ defmt::timestamp! {"{=u64}", {
22pub fn config() -> Config { 22pub fn config() -> Config {
23 let mut config = Config::default(); 23 let mut config = Config::default();
24 config.rcc.sys_ck = Some(400.mhz().into()); 24 config.rcc.sys_ck = Some(400.mhz().into());
25 config.rcc.hclk = Some(200.mhz().into());
25 config.rcc.pll1.q_ck = Some(100.mhz().into()); 26 config.rcc.pll1.q_ck = Some(100.mhz().into());
26 config 27 config
27} 28}