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)] |
9 | pub 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 | } |
23 | impl 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 |
39 | pub trait AddressPinSet { |
40 | /// The number of address pins in this set of pins |
41 | const ADDRESS_PINS: u8; |
42 | } |
43 | |
44 | macro_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 | } |
58 | address_pin_markers!( |
59 | AddressPins11, 11, "11" ; |
60 | AddressPins12, 12, "12" ; |
61 | AddressPins13, 13, "13" ; |
62 | ); |
63 | |
64 | // ---- SDRAM ---- |
65 | |
66 | #[cfg (feature = "sdram" )] |
67 | use crate::sdram::{PinsSdram, SdramBank1, SdramBank2}; |
68 | |
69 | #[cfg (feature = "sdram" )] |
70 | macro_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" )] |
105 | macro_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" )] |
148 | impl_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" )] |
170 | impl_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" )] |
194 | use crate::nand::PinsNand; |
195 | |
196 | #[cfg (feature = "nand" )] |
197 | #[rustfmt::skip] |
198 | /// 8-bit NAND |
199 | impl<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) |
202 | where 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 |
209 | pub trait A0 {} |
210 | /// Marks a type as an A1 pin |
211 | pub trait A1 {} |
212 | /// Marks a type as an A10 pin |
213 | pub trait A10 {} |
214 | /// Marks a type as an A11 pin |
215 | pub trait A11 {} |
216 | /// Marks a type as an A12 pin |
217 | pub trait A12 {} |
218 | /// Marks a type as an A13 pin |
219 | pub trait A13 {} |
220 | /// Marks a type as an A14 pin |
221 | pub trait A14 {} |
222 | /// Marks a type as an A15 pin |
223 | pub trait A15 {} |
224 | /// Marks a type as an A16 pin |
225 | pub trait A16 {} |
226 | /// Marks a type as an A17 pin |
227 | pub trait A17 {} |
228 | /// Marks a type as an A18 pin |
229 | pub trait A18 {} |
230 | /// Marks a type as an A19 pin |
231 | pub trait A19 {} |
232 | /// Marks a type as an A2 pin |
233 | pub trait A2 {} |
234 | /// Marks a type as an A20 pin |
235 | pub trait A20 {} |
236 | /// Marks a type as an A21 pin |
237 | pub trait A21 {} |
238 | /// Marks a type as an A22 pin |
239 | pub trait A22 {} |
240 | /// Marks a type as an A23 pin |
241 | pub trait A23 {} |
242 | /// Marks a type as an A24 pin |
243 | pub trait A24 {} |
244 | /// Marks a type as an A25 pin |
245 | pub trait A25 {} |
246 | /// Marks a type as an A3 pin |
247 | pub trait A3 {} |
248 | /// Marks a type as an A4 pin |
249 | pub trait A4 {} |
250 | /// Marks a type as an A5 pin |
251 | pub trait A5 {} |
252 | /// Marks a type as an A6 pin |
253 | pub trait A6 {} |
254 | /// Marks a type as an A7 pin |
255 | pub trait A7 {} |
256 | /// Marks a type as an A8 pin |
257 | pub trait A8 {} |
258 | /// Marks a type as an A9 pin |
259 | pub trait A9 {} |
260 | /// Marks a type as a BA0 pin |
261 | pub trait BA0 {} |
262 | /// Marks a type as a BA1 pin |
263 | pub trait BA1 {} |
264 | /// Marks a type as a CLK pin |
265 | pub trait CLK {} |
266 | /// Marks a type as a D0 pin |
267 | pub trait D0 {} |
268 | /// Marks a type as a D1 pin |
269 | pub trait D1 {} |
270 | /// Marks a type as a D10 pin |
271 | pub trait D10 {} |
272 | /// Marks a type as a D11 pin |
273 | pub trait D11 {} |
274 | /// Marks a type as a D12 pin |
275 | pub trait D12 {} |
276 | /// Marks a type as a D13 pin |
277 | pub trait D13 {} |
278 | /// Marks a type as a D14 pin |
279 | pub trait D14 {} |
280 | /// Marks a type as a D15 pin |
281 | pub trait D15 {} |
282 | /// Marks a type as a D16 pin |
283 | pub trait D16 {} |
284 | /// Marks a type as a D17 pin |
285 | pub trait D17 {} |
286 | /// Marks a type as a D18 pin |
287 | pub trait D18 {} |
288 | /// Marks a type as a D19 pin |
289 | pub trait D19 {} |
290 | /// Marks a type as a D2 pin |
291 | pub trait D2 {} |
292 | /// Marks a type as a D20 pin |
293 | pub trait D20 {} |
294 | /// Marks a type as a D21 pin |
295 | pub trait D21 {} |
296 | /// Marks a type as a D22 pin |
297 | pub trait D22 {} |
298 | /// Marks a type as a D23 pin |
299 | pub trait D23 {} |
300 | /// Marks a type as a D24 pin |
301 | pub trait D24 {} |
302 | /// Marks a type as a D25 pin |
303 | pub trait D25 {} |
304 | /// Marks a type as a D26 pin |
305 | pub trait D26 {} |
306 | /// Marks a type as a D27 pin |
307 | pub trait D27 {} |
308 | /// Marks a type as a D28 pin |
309 | pub trait D28 {} |
310 | /// Marks a type as a D29 pin |
311 | pub trait D29 {} |
312 | /// Marks a type as a D3 pin |
313 | pub trait D3 {} |
314 | /// Marks a type as a D30 pin |
315 | pub trait D30 {} |
316 | /// Marks a type as a D31 pin |
317 | pub trait D31 {} |
318 | /// Marks a type as a D4 pin |
319 | pub trait D4 {} |
320 | /// Marks a type as a D5 pin |
321 | pub trait D5 {} |
322 | /// Marks a type as a D6 pin |
323 | pub trait D6 {} |
324 | /// Marks a type as a D7 pin |
325 | pub trait D7 {} |
326 | /// Marks a type as a D8 pin |
327 | pub trait D8 {} |
328 | /// Marks a type as a D9 pin |
329 | pub trait D9 {} |
330 | /// Marks a type as a DA0 pin |
331 | pub trait DA0 {} |
332 | /// Marks a type as a DA1 pin |
333 | pub trait DA1 {} |
334 | /// Marks a type as a DA10 pin |
335 | pub trait DA10 {} |
336 | /// Marks a type as a DA11 pin |
337 | pub trait DA11 {} |
338 | /// Marks a type as a DA12 pin |
339 | pub trait DA12 {} |
340 | /// Marks a type as a DA13 pin |
341 | pub trait DA13 {} |
342 | /// Marks a type as a DA14 pin |
343 | pub trait DA14 {} |
344 | /// Marks a type as a DA15 pin |
345 | pub trait DA15 {} |
346 | /// Marks a type as a DA2 pin |
347 | pub trait DA2 {} |
348 | /// Marks a type as a DA3 pin |
349 | pub trait DA3 {} |
350 | /// Marks a type as a DA4 pin |
351 | pub trait DA4 {} |
352 | /// Marks a type as a DA5 pin |
353 | pub trait DA5 {} |
354 | /// Marks a type as a DA6 pin |
355 | pub trait DA6 {} |
356 | /// Marks a type as a DA7 pin |
357 | pub trait DA7 {} |
358 | /// Marks a type as a DA8 pin |
359 | pub trait DA8 {} |
360 | /// Marks a type as a DA9 pin |
361 | pub trait DA9 {} |
362 | /// Marks a type as an INT pin |
363 | pub trait INT {} |
364 | /// Marks a type as a NBL0 pin |
365 | pub trait NBL0 {} |
366 | /// Marks a type as a NBL1 pin |
367 | pub trait NBL1 {} |
368 | /// Marks a type as a NBL2 pin |
369 | pub trait NBL2 {} |
370 | /// Marks a type as a NBL3 pin |
371 | pub trait NBL3 {} |
372 | /// Marks a type as a NE1 pin |
373 | pub trait NE1 {} |
374 | /// Marks a type as a NE2 pin |
375 | pub trait NE2 {} |
376 | /// Marks a type as a NE3 pin |
377 | pub trait NE3 {} |
378 | /// Marks a type as a NE4 pin |
379 | pub trait NE4 {} |
380 | /// Marks a type as a NL pin |
381 | pub trait NL {} |
382 | /// Marks a type as a NCE pin |
383 | pub trait NCE {} |
384 | /// Marks a type as a NOE pin |
385 | pub trait NOE {} |
386 | /// Marks a type as a NWAIT pin |
387 | pub trait NWAIT {} |
388 | /// Marks a type as a NWE pin |
389 | pub trait NWE {} |
390 | /// Marks a type as a SDCKE0 pin |
391 | pub trait SDCKE0 {} |
392 | /// Marks a type as a SDCKE1 pin |
393 | pub trait SDCKE1 {} |
394 | /// Marks a type as a SDCLK pin |
395 | pub trait SDCLK {} |
396 | /// Marks a type as a SDNCAS pin |
397 | pub trait SDNCAS {} |
398 | /// Marks a type as a SDNE0 pin |
399 | pub trait SDNE0 {} |
400 | /// Marks a type as a SDNE1 pin |
401 | pub trait SDNE1 {} |
402 | /// Marks a type as a SDNRAS pin |
403 | pub trait SDNRAS {} |
404 | /// Marks a type as a SDNWE pin |
405 | pub trait SDNWE {} |
406 | |
407 | use crate::ral::fmc; |
408 | use crate::FmcPeripheral; |
409 | |
410 | #[derive (Copy, Clone)] |
411 | pub(crate) struct FmcRegisters(usize); |
412 | |
413 | impl 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 | } |
424 | |