embassy_stm32/
fmc.rs

1//! Flexible Memory Controller (FMC) / Flexible Static Memory Controller (FSMC)
2use core::marker::PhantomData;
3
4use embassy_hal_internal::into_ref;
5
6use crate::gpio::{AfType, OutputType, Pull, Speed};
7use crate::{rcc, Peripheral};
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: impl Peripheral<P = T> + 'd) -> 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        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        /// Create a new FMC instance.
94        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/// FMC instance trait.
247#[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);