| 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 | |