stm32_fmc/
fmc.rs

1//! HAL for Flexible memory controller (FMC)
2
3/// FMC banks
4///
5/// For example, see RM0433 rev 7 Figure 98.
6#[derive(Clone, Copy, Debug, PartialEq)]
7#[cfg_attr(feature = "defmt", derive(defmt::Format))]
8#[allow(unused)]
9pub enum FmcBank {
10    /// Bank1: NOR/PSRAM/SRAM
11    Bank1,
12    /// Bank2:
13    Bank2,
14    /// Bank3: NAND Flash
15    Bank3,
16    /// Bank4:
17    Bank4,
18    /// Bank5: SDRAM 1
19    Bank5,
20    /// Bank6: SDRAM 2
21    Bank6,
22}
23impl FmcBank {
24    /// Return a pointer to this FMC bank
25    pub fn ptr(self) -> *mut u32 {
26        use FmcBank::*;
27        (match self {
28            Bank1 => 0x6000_0000u32,
29            Bank2 => 0x7000_0000u32,
30            Bank3 => 0x8000_0000u32,
31            Bank4 => 0x9000_0000u32, // Not used
32            Bank5 => 0xC000_0000u32,
33            Bank6 => 0xD000_0000u32,
34        }) as *mut u32
35    }
36}
37
38/// Set of address pins
39pub trait AddressPinSet {
40    /// The number of address pins in this set of pins
41    const ADDRESS_PINS: u8;
42}
43
44macro_rules! address_pin_markers {
45    ($($AddressPins:ident, $addr:tt, $doc:expr;)+) => {
46        $(
47            /// Type to mark that there are
48            #[doc=$doc]
49            /// address pins
50            #[derive(Clone, Copy, Debug)]
51            pub struct $AddressPins;
52            impl AddressPinSet for $AddressPins {
53                const ADDRESS_PINS: u8 = $addr;
54            }
55        )+
56    };
57}
58address_pin_markers!(
59    AddressPins11, 11, "11";
60    AddressPins12, 12, "12";
61    AddressPins13, 13, "13";
62);
63
64// ---- SDRAM ----
65
66#[cfg(feature = "sdram")]
67use crate::sdram::{PinsSdram, SdramBank1, SdramBank2};
68
69#[cfg(feature = "sdram")]
70macro_rules! impl_16bit_sdram {
71    ($($pins:tt: [$ckeN:tt, $neN:tt,
72                  $nInternalB:expr
73                  $(, $pba1:ident: $ba1:tt)* ; // BA1 pins
74                  $addressPins:ident
75                  [ $($pa:ident: $a:ident),* ] // Address pins
76    ]),+) => {
77        $(
78            #[rustfmt::skip]
79            /// 16-bit SDRAM
80            impl<PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, $($pa,)*
81            PBA0, $($pba1,)* PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8,
82            PD9, PD10, PD11, PD12, PD13, PD14, PD15, PNBL0, PNBL1, PSDCKEn,
83            PSDCLK, PSDNCAS, PSDNEn, PSDNRAS, PSDNWE>
84                PinsSdram<$pins, $addressPins>
85                for (PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, $($pa,)*
86                     PBA0, $($pba1,)* PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7,
87                     PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15, PNBL0, PNBL1,
88                     PSDCKEn, PSDCLK, PSDNCAS, PSDNEn, PSDNRAS, PSDNWE)
89            where PA0: A0, PA1: A1, PA2: A2, PA3: A3, PA4: A4, PA5: A5, PA6: A6,
90                  PA7: A7, PA8: A8, PA9: A9, PA10: A10, $($pa:$a,)*
91                  PBA0: BA0, $($pba1:$ba1,)*
92                  PD0: D0, PD1: D1, PD2: D2, PD3: D3, PD4: D4, PD5: D5, PD6: D6,
93                  PD7: D7, PD8: D8, PD9: D9, PD10: D10, PD11: D11, PD12: D12,
94                  PD13: D13, PD14: D14, PD15: D15,
95                  PNBL0: NBL0, PNBL1: NBL1, PSDCKEn: $ckeN, PSDCLK: SDCLK,
96                  PSDNCAS: SDNCAS, PSDNEn: $neN, PSDNRAS: SDNRAS, PSDNWE: SDNWE {
97
98                const NUMBER_INTERNAL_BANKS: u8 = $nInternalB;
99            }
100        )+
101    }
102}
103
104#[cfg(feature = "sdram")]
105macro_rules! impl_32bit_sdram {
106    ($($pins:tt: [$ckeN:tt, $neN:tt,
107                  $nInternalB:expr
108                  $(, $pba1:ident: $ba1:tt)* ; // BA1 pins
109                  $addressPins:ident
110                  [ $($pa:ident: $a:ident),* ] // Address pins
111            ]),+) => {
112        $(
113            #[rustfmt::skip]
114            /// 32-bit SDRAM
115            impl<PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, $($pa,)*
116            PBA0, $($pba1,)* PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8,
117            PD9, PD10, PD11, PD12, PD13, PD14, PD15, PD16, PD17, PD18, PD19,
118            PD20, PD21, PD22, PD23, PD24, PD25, PD26, PD27, PD28, PD29, PD30,
119            PD31, PNBL0, PNBL1, PNBL2, PNBL3, PSDCKEn, PSDCLK, PSDNCAS,
120            PSDNEn, PSDNRAS, PSDNWE>
121                PinsSdram<$pins, $addressPins>
122                for (PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, $($pa,)*
123                     PBA0, $($pba1,)* PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7,
124                     PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15, PD16, PD17,
125                     PD18, PD19, PD20, PD21, PD22, PD23, PD24, PD25, PD26, PD27,
126                     PD28, PD29, PD30, PD31, PNBL0, PNBL1, PNBL2, PNBL3, PSDCKEn,
127                     PSDCLK, PSDNCAS, PSDNEn, PSDNRAS, PSDNWE)
128            where PA0: A0, PA1: A1, PA2: A2, PA3: A3, PA4: A4, PA5: A5, PA6: A6,
129                  PA7: A7, PA8: A8, PA9: A9, PA10: A10, $($pa:$a,)*
130                  PBA0: BA0, $($pba1:$ba1,)*
131                  PD0: D0, PD1: D1, PD2: D2, PD3: D3, PD4: D4, PD5: D5, PD6: D6,
132                  PD7: D7, PD8: D8, PD9: D9, PD10: D10, PD11: D11, PD12: D12,
133                  PD13: D13, PD14: D14, PD15: D15, PD16: D16, PD17: D17,
134                  PD18: D18, PD19: D19, PD20: D20, PD21: D21, PD22: D22,
135                  PD23: D23, PD24: D24, PD25: D25, PD26: D26, PD27: D27,
136                  PD28: D28, PD29: D29, PD30: D30, PD31: D31,
137                  PNBL0: NBL0, PNBL1: NBL1, PNBL2: NBL2, PNBL3: NBL3,
138                  PSDCKEn: $ckeN, PSDCLK: SDCLK,
139                  PSDNCAS: SDNCAS, PSDNEn: $neN, PSDNRAS: SDNRAS, PSDNWE: SDNWE {
140
141                const NUMBER_INTERNAL_BANKS: u8 = $nInternalB;
142            }
143        )+
144    }
145}
146
147#[cfg(feature = "sdram")]
148impl_16bit_sdram! {
149    // 16-bit SDRAM with 11 address lines, BA0 only
150    SdramBank1: [SDCKE0, SDNE0, 2; AddressPins11 []],
151    SdramBank2: [SDCKE1, SDNE1, 2; AddressPins11 []],
152    // 16-bit SDRAM with 11 address lines, BA0 and BA1
153    SdramBank1: [SDCKE0, SDNE0, 4, PBA1: BA1; AddressPins11 []],
154    SdramBank2: [SDCKE1, SDNE1, 4, PBA1: BA1; AddressPins11 []],
155    // 16-bit SDRAM with 12 address lines, BA0 only
156    SdramBank1: [SDCKE0, SDNE0, 2; AddressPins12 [PA11: A11]],
157    SdramBank2: [SDCKE1, SDNE1, 2; AddressPins12 [PA11: A11]],
158    // 16-bit SDRAM with 12 address lines, BA0 and BA1
159    SdramBank1: [SDCKE0, SDNE0, 4, PBA1: BA1; AddressPins12 [PA11: A11]],
160    SdramBank2: [SDCKE1, SDNE1, 4, PBA1: BA1; AddressPins12 [PA11: A11]],
161    // 16-bit SDRAM with 13 address lines, BA0 only
162    SdramBank1: [SDCKE0, SDNE0, 2; AddressPins13 [PA11: A11, PA12: A12]],
163    SdramBank2: [SDCKE1, SDNE1, 2; AddressPins13 [PA11: A11, PA12: A12]],
164    // 16-bit SDRAM with 13 address lines, BA0 and BA1
165    SdramBank1: [SDCKE0, SDNE0, 4, PBA1: BA1; AddressPins13 [PA11: A11, PA12: A12]],
166    SdramBank2: [SDCKE1, SDNE1, 4, PBA1: BA1; AddressPins13 [PA11: A11, PA12: A12]]
167}
168
169#[cfg(feature = "sdram")]
170impl_32bit_sdram! {
171    // 32-bit SDRAM with 11 address lines, BA0 only
172    SdramBank1: [SDCKE0, SDNE0, 2; AddressPins11 []],
173    SdramBank2: [SDCKE1, SDNE1, 2; AddressPins11 []],
174    // 32-bit SDRAM with 11 address lines, BA0 and BA1
175    SdramBank1: [SDCKE0, SDNE0, 4, PBA1: BA1; AddressPins11 []],
176    SdramBank2: [SDCKE1, SDNE1, 4, PBA1: BA1; AddressPins11 []],
177    // 32-bit SDRAM with 12 address lines, BA0 only
178    SdramBank1: [SDCKE0, SDNE0, 2; AddressPins12 [PA11: A11]],
179    SdramBank2: [SDCKE1, SDNE1, 2; AddressPins12 [PA11: A11]],
180    // 32-bit SDRAM with 12 address lines, BA0 and BA1
181    SdramBank1: [SDCKE0, SDNE0, 4, PBA1: BA1; AddressPins12 [PA11: A11]],
182    SdramBank2: [SDCKE1, SDNE1, 4, PBA1: BA1; AddressPins12 [PA11: A11]],
183    // 32-bit SDRAM with 13 address lines, BA0 only
184    SdramBank1: [SDCKE0, SDNE0, 2; AddressPins13 [PA11: A11, PA12: A12]],
185    SdramBank2: [SDCKE1, SDNE1, 2; AddressPins13 [PA11: A11, PA12: A12]],
186    // 32-bit SDRAM with 13 address lines, BA0 and BA1
187    SdramBank1: [SDCKE0, SDNE0, 4, PBA1: BA1; AddressPins13 [PA11: A11, PA12: A12]],
188    SdramBank2: [SDCKE1, SDNE1, 4, PBA1: BA1; AddressPins13 [PA11: A11, PA12: A12]]
189}
190
191// ---- NAND ----
192
193#[cfg(feature = "nand")]
194use crate::nand::PinsNand;
195
196#[cfg(feature = "nand")]
197#[rustfmt::skip]
198/// 8-bit NAND
199impl<ALE, CLE, PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PNCE, PNOE, PNWE, PNWAIT>
200    PinsNand
201    for (ALE, CLE, PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PNCE, PNOE, PNWE, PNWAIT)
202where ALE: A17, CLE: A16,
203      PD0: D0, PD1: D1, PD2: D2, PD3: D3, PD4: D4, PD5: D5, PD6: D6, PD7: D7,
204      PNCE: NCE, PNOE: NOE, PNWE: NWE, PNWAIT: NWAIT {
205    const N_DATA: usize = 8;
206}
207
208/// Marks a type as an A0 pin
209pub trait A0 {}
210/// Marks a type as an A1 pin
211pub trait A1 {}
212/// Marks a type as an A10 pin
213pub trait A10 {}
214/// Marks a type as an A11 pin
215pub trait A11 {}
216/// Marks a type as an A12 pin
217pub trait A12 {}
218/// Marks a type as an A13 pin
219pub trait A13 {}
220/// Marks a type as an A14 pin
221pub trait A14 {}
222/// Marks a type as an A15 pin
223pub trait A15 {}
224/// Marks a type as an A16 pin
225pub trait A16 {}
226/// Marks a type as an A17 pin
227pub trait A17 {}
228/// Marks a type as an A18 pin
229pub trait A18 {}
230/// Marks a type as an A19 pin
231pub trait A19 {}
232/// Marks a type as an A2 pin
233pub trait A2 {}
234/// Marks a type as an A20 pin
235pub trait A20 {}
236/// Marks a type as an A21 pin
237pub trait A21 {}
238/// Marks a type as an A22 pin
239pub trait A22 {}
240/// Marks a type as an A23 pin
241pub trait A23 {}
242/// Marks a type as an A24 pin
243pub trait A24 {}
244/// Marks a type as an A25 pin
245pub trait A25 {}
246/// Marks a type as an A3 pin
247pub trait A3 {}
248/// Marks a type as an A4 pin
249pub trait A4 {}
250/// Marks a type as an A5 pin
251pub trait A5 {}
252/// Marks a type as an A6 pin
253pub trait A6 {}
254/// Marks a type as an A7 pin
255pub trait A7 {}
256/// Marks a type as an A8 pin
257pub trait A8 {}
258/// Marks a type as an A9 pin
259pub trait A9 {}
260/// Marks a type as a BA0 pin
261pub trait BA0 {}
262/// Marks a type as a BA1 pin
263pub trait BA1 {}
264/// Marks a type as a CLK pin
265pub trait CLK {}
266/// Marks a type as a D0 pin
267pub trait D0 {}
268/// Marks a type as a D1 pin
269pub trait D1 {}
270/// Marks a type as a D10 pin
271pub trait D10 {}
272/// Marks a type as a D11 pin
273pub trait D11 {}
274/// Marks a type as a D12 pin
275pub trait D12 {}
276/// Marks a type as a D13 pin
277pub trait D13 {}
278/// Marks a type as a D14 pin
279pub trait D14 {}
280/// Marks a type as a D15 pin
281pub trait D15 {}
282/// Marks a type as a D16 pin
283pub trait D16 {}
284/// Marks a type as a D17 pin
285pub trait D17 {}
286/// Marks a type as a D18 pin
287pub trait D18 {}
288/// Marks a type as a D19 pin
289pub trait D19 {}
290/// Marks a type as a D2 pin
291pub trait D2 {}
292/// Marks a type as a D20 pin
293pub trait D20 {}
294/// Marks a type as a D21 pin
295pub trait D21 {}
296/// Marks a type as a D22 pin
297pub trait D22 {}
298/// Marks a type as a D23 pin
299pub trait D23 {}
300/// Marks a type as a D24 pin
301pub trait D24 {}
302/// Marks a type as a D25 pin
303pub trait D25 {}
304/// Marks a type as a D26 pin
305pub trait D26 {}
306/// Marks a type as a D27 pin
307pub trait D27 {}
308/// Marks a type as a D28 pin
309pub trait D28 {}
310/// Marks a type as a D29 pin
311pub trait D29 {}
312/// Marks a type as a D3 pin
313pub trait D3 {}
314/// Marks a type as a D30 pin
315pub trait D30 {}
316/// Marks a type as a D31 pin
317pub trait D31 {}
318/// Marks a type as a D4 pin
319pub trait D4 {}
320/// Marks a type as a D5 pin
321pub trait D5 {}
322/// Marks a type as a D6 pin
323pub trait D6 {}
324/// Marks a type as a D7 pin
325pub trait D7 {}
326/// Marks a type as a D8 pin
327pub trait D8 {}
328/// Marks a type as a D9 pin
329pub trait D9 {}
330/// Marks a type as a DA0 pin
331pub trait DA0 {}
332/// Marks a type as a DA1 pin
333pub trait DA1 {}
334/// Marks a type as a DA10 pin
335pub trait DA10 {}
336/// Marks a type as a DA11 pin
337pub trait DA11 {}
338/// Marks a type as a DA12 pin
339pub trait DA12 {}
340/// Marks a type as a DA13 pin
341pub trait DA13 {}
342/// Marks a type as a DA14 pin
343pub trait DA14 {}
344/// Marks a type as a DA15 pin
345pub trait DA15 {}
346/// Marks a type as a DA2 pin
347pub trait DA2 {}
348/// Marks a type as a DA3 pin
349pub trait DA3 {}
350/// Marks a type as a DA4 pin
351pub trait DA4 {}
352/// Marks a type as a DA5 pin
353pub trait DA5 {}
354/// Marks a type as a DA6 pin
355pub trait DA6 {}
356/// Marks a type as a DA7 pin
357pub trait DA7 {}
358/// Marks a type as a DA8 pin
359pub trait DA8 {}
360/// Marks a type as a DA9 pin
361pub trait DA9 {}
362/// Marks a type as an INT pin
363pub trait INT {}
364/// Marks a type as a NBL0 pin
365pub trait NBL0 {}
366/// Marks a type as a NBL1 pin
367pub trait NBL1 {}
368/// Marks a type as a NBL2 pin
369pub trait NBL2 {}
370/// Marks a type as a NBL3 pin
371pub trait NBL3 {}
372/// Marks a type as a NE1 pin
373pub trait NE1 {}
374/// Marks a type as a NE2 pin
375pub trait NE2 {}
376/// Marks a type as a NE3 pin
377pub trait NE3 {}
378/// Marks a type as a NE4 pin
379pub trait NE4 {}
380/// Marks a type as a NL pin
381pub trait NL {}
382/// Marks a type as a NCE pin
383pub trait NCE {}
384/// Marks a type as a NOE pin
385pub trait NOE {}
386/// Marks a type as a NWAIT pin
387pub trait NWAIT {}
388/// Marks a type as a NWE pin
389pub trait NWE {}
390/// Marks a type as a SDCKE0 pin
391pub trait SDCKE0 {}
392/// Marks a type as a SDCKE1 pin
393pub trait SDCKE1 {}
394/// Marks a type as a SDCLK pin
395pub trait SDCLK {}
396/// Marks a type as a SDNCAS pin
397pub trait SDNCAS {}
398/// Marks a type as a SDNE0 pin
399pub trait SDNE0 {}
400/// Marks a type as a SDNE1 pin
401pub trait SDNE1 {}
402/// Marks a type as a SDNRAS pin
403pub trait SDNRAS {}
404/// Marks a type as a SDNWE pin
405pub trait SDNWE {}
406
407use crate::ral::fmc;
408use crate::FmcPeripheral;
409
410#[derive(Copy, Clone)]
411pub(crate) struct FmcRegisters(usize);
412
413impl FmcRegisters {
414    #[inline(always)]
415    pub fn new<FMC: FmcPeripheral>() -> Self {
416        Self(FMC::REGISTERS as usize)
417    }
418
419    #[inline(always)]
420    pub fn global(&self) -> &'static fmc::RegisterBlock {
421        unsafe { &*(self.0 as *const _) }
422    }
423}