use core::marker::PhantomData; use embassy::util::Unborrow; use embassy_hal_common::unborrow; use crate::gpio::sealed::AFType::OutputPushPull; use crate::gpio::Speed; use crate::pac::gpio::vals::Pupdr; mod pins; pub use pins::*; pub struct Fmc<'d, T: Instance> { peri: PhantomData<&'d mut T>, } unsafe impl<'d, T> Send for Fmc<'d, T> where T: Instance {} unsafe impl<'d, T> stm32_fmc::FmcPeripheral for Fmc<'d, T> where T: Instance, { const REGISTERS: *const () = crate::pac::FMC.0 as *const _; fn enable(&mut self) { ::enable(); ::reset(); } fn memory_controller_enable(&mut self) { // The FMCEN bit of the FMC_BCR2..4 registers is don’t // care. It is only enabled through the FMC_BCR1 register. unsafe { T::regs().bcr1().modify(|r| r.set_fmcen(true)) }; } fn source_clock_hz(&self) -> u32 { ::frequency().0 } } macro_rules! config_pins { ($($pin:ident),*) => { unborrow!($($pin),*); $( $pin.set_as_af($pin.af_num(), OutputPushPull); $pin.set_speed(Speed::VeryHigh); $pin.block().pupdr().modify(|w| w.set_pupdr($pin.pin() as usize, Pupdr::PULLUP)); )* }; } macro_rules! fmc_sdram_constructor { ($name:ident: ( bank: $bank:expr, addr: [$(($addr_pin_name:ident: $addr_signal:ident)),*], ba: [$(($ba_pin_name:ident: $ba_signal:ident)),*], d: [$(($d_pin_name:ident: $d_signal:ident)),*], nbl: [$(($nbl_pin_name:ident: $nbl_signal:ident)),*], ctrl: [$(($ctrl_pin_name:ident: $ctrl_signal:ident)),*] )) => { pub fn $name( _instance: impl Unborrow + 'd, $($addr_pin_name: impl Unborrow> + 'd),*, $($ba_pin_name: impl Unborrow> + 'd),*, $($d_pin_name: impl Unborrow> + 'd),*, $($nbl_pin_name: impl Unborrow> + 'd),*, $($ctrl_pin_name: impl Unborrow> + 'd),*, chip: CHIP ) -> stm32_fmc::Sdram, CHIP> { critical_section::with(|_| unsafe { config_pins!( $($addr_pin_name),*, $($ba_pin_name),*, $($d_pin_name),*, $($nbl_pin_name),*, $($ctrl_pin_name),* ); }); let fmc = Self { peri: PhantomData }; stm32_fmc::Sdram::new_unchecked( fmc, $bank, chip, ) } }; } impl<'d, T: Instance> Fmc<'d, T> { fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank1: ( bank: stm32_fmc::SdramTargetBank::Bank1, addr: [ (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin) ], ba: [(ba0: BA0Pin), (ba1: BA1Pin)], d: [ (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin), (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin), (d16: D16Pin), (d17: D17Pin), (d18: D18Pin), (d19: D19Pin), (d20: D20Pin), (d21: D21Pin), (d22: D22Pin), (d23: D23Pin), (d24: D24Pin), (d25: D25Pin), (d26: D26Pin), (d27: D27Pin), (d28: D28Pin), (d29: D29Pin), (d30: D30Pin), (d31: D31Pin) ], nbl: [ (nbl0: NBL0Pin), (nbl1: NBL1Pin), (nbl2: NBL2Pin), (nbl3: NBL3Pin) ], ctrl: [ (sdcke: SDCKE0Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE0Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin) ] )); fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank2: ( bank: stm32_fmc::SdramTargetBank::Bank2, addr: [ (a0: A0Pin), (a1: A1Pin), (a2: A2Pin), (a3: A3Pin), (a4: A4Pin), (a5: A5Pin), (a6: A6Pin), (a7: A7Pin), (a8: A8Pin), (a9: A9Pin), (a10: A10Pin), (a11: A11Pin) ], ba: [(ba0: BA0Pin), (ba1: BA1Pin)], d: [ (d0: D0Pin), (d1: D1Pin), (d2: D2Pin), (d3: D3Pin), (d4: D4Pin), (d5: D5Pin), (d6: D6Pin), (d7: D7Pin), (d8: D8Pin), (d9: D9Pin), (d10: D10Pin), (d11: D11Pin), (d12: D12Pin), (d13: D13Pin), (d14: D14Pin), (d15: D15Pin), (d16: D16Pin), (d17: D17Pin), (d18: D18Pin), (d19: D19Pin), (d20: D20Pin), (d21: D21Pin), (d22: D22Pin), (d23: D23Pin), (d24: D24Pin), (d25: D25Pin), (d26: D26Pin), (d27: D27Pin), (d28: D28Pin), (d29: D29Pin), (d30: D30Pin), (d31: D31Pin) ], nbl: [ (nbl0: NBL0Pin), (nbl1: NBL1Pin), (nbl2: NBL2Pin), (nbl3: NBL3Pin) ], ctrl: [ (sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin) ] )); } crate::pac::peripherals!( (fmc, $inst:ident) => { impl crate::fmc::sealed::Instance for crate::peripherals::$inst { fn regs() -> stm32_metapac::fmc::Fmc { crate::pac::$inst } } impl crate::fmc::Instance for crate::peripherals::$inst {} }; );