embassy_stm32/
fmc.rs

1//! Flexible Memory Controller (FMC) / Flexible Static Memory Controller (FSMC)
2use core::marker::PhantomData;
3
4use embassy_hal_internal::PeripheralType;
5
6use crate::gpio::{AfType, OutputType, Pull, Speed};
7use crate::{rcc, Peri};
8
9/// FMC driver
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
16impl<'d, T> Fmc<'d, T>
17where
18    T: Instance,
19{
20    /// Create a raw FMC instance.
21    ///
22    /// **Note:** This is currently used to provide access to some basic FMC functions
23    /// for manual configuration for memory types that stm32-fmc does not support.
24    pub fn new_raw(_instance: Peri<'d, T>) -> Self {
25        Self { peri: PhantomData }
26    }
27
28    /// Enable the FMC peripheral and reset it.
29    pub fn enable(&mut self) {
30        rcc::enable_and_reset::<T>();
31    }
32
33    /// Enable the memory controller on applicable chips.
34    pub fn memory_controller_enable(&mut self) {
35        // fmc v1 and v2 does not have the fmcen bit
36        // fsmc v1, v2 and v3 does not have the fmcen bit
37        // This is a "not" because it is expected that all future versions have this bit
38        #[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    /// Get the kernel clock currently in use for this FMC instance.
45    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        // fmc v1 and v2 does not have the fmcen bit
62        // fsmc v1, v2 and v3 does not have the fmcen bit
63        // This is a "not" because it is expected that all future versions have this bit
64        #[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        /// Create a new FMC instance.
93        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/// FMC instance trait.
246#[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);