Skip to content

Instantly share code, notes, and snippets.

@matoushybl
Created February 2, 2022 09:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matoushybl/7d1b4c95c16b912fe525a3fd1d2d7942 to your computer and use it in GitHub Desktop.
Save matoushybl/7d1b4c95c16b912fe525a3fd1d2d7942 to your computer and use it in GitHub Desktop.
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
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) {
<T as crate::rcc::sealed::RccPeripheral>::reset();
<T as crate::rcc::sealed::RccPeripheral>::enable();
}
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 {
let f = <T as crate::rcc::sealed::RccPeripheral>::frequency().0;
defmt::info!("f: {}", f);
f
}
}
// add support for specifying sdcke0 sdne0
impl<'d, T: Instance> Fmc<'d, T> {
pub fn sdram_32bits<CHIP: stm32_fmc::SdramChip>(
instance: impl Unborrow<Target = T> + 'd,
a0: impl Unborrow<Target = impl A0Pin> + 'd,
a1: impl Unborrow<Target = impl A1Pin> + 'd,
a2: impl Unborrow<Target = impl A2Pin> + 'd,
a3: impl Unborrow<Target = impl A3Pin> + 'd,
a4: impl Unborrow<Target = impl A4Pin> + 'd,
a5: impl Unborrow<Target = impl A5Pin> + 'd,
a6: impl Unborrow<Target = impl A6Pin> + 'd,
a7: impl Unborrow<Target = impl A7Pin> + 'd,
a8: impl Unborrow<Target = impl A8Pin> + 'd,
a9: impl Unborrow<Target = impl A9Pin> + 'd,
a10: impl Unborrow<Target = impl A10Pin> + 'd,
a11: impl Unborrow<Target = impl A11Pin> + 'd,
ba0: impl Unborrow<Target = impl BA0Pin> + 'd,
ba1: impl Unborrow<Target = impl BA1Pin> + 'd,
d0: impl Unborrow<Target = impl D0Pin> + 'd,
d1: impl Unborrow<Target = impl D1Pin> + 'd,
d2: impl Unborrow<Target = impl D2Pin> + 'd,
d3: impl Unborrow<Target = impl D3Pin> + 'd,
d4: impl Unborrow<Target = impl D4Pin> + 'd,
d5: impl Unborrow<Target = impl D5Pin> + 'd,
d6: impl Unborrow<Target = impl D6Pin> + 'd,
d7: impl Unborrow<Target = impl D7Pin> + 'd,
d8: impl Unborrow<Target = impl D8Pin> + 'd,
d9: impl Unborrow<Target = impl D9Pin> + 'd,
d10: impl Unborrow<Target = impl D10Pin> + 'd,
d11: impl Unborrow<Target = impl D11Pin> + 'd,
d12: impl Unborrow<Target = impl D12Pin> + 'd,
d13: impl Unborrow<Target = impl D13Pin> + 'd,
d14: impl Unborrow<Target = impl D14Pin> + 'd,
d15: impl Unborrow<Target = impl D15Pin> + 'd,
d16: impl Unborrow<Target = impl D16Pin> + 'd,
d17: impl Unborrow<Target = impl D17Pin> + 'd,
d18: impl Unborrow<Target = impl D18Pin> + 'd,
d19: impl Unborrow<Target = impl D19Pin> + 'd,
d20: impl Unborrow<Target = impl D20Pin> + 'd,
d21: impl Unborrow<Target = impl D21Pin> + 'd,
d22: impl Unborrow<Target = impl D22Pin> + 'd,
d23: impl Unborrow<Target = impl D23Pin> + 'd,
d24: impl Unborrow<Target = impl D24Pin> + 'd,
d25: impl Unborrow<Target = impl D25Pin> + 'd,
d26: impl Unborrow<Target = impl D26Pin> + 'd,
d27: impl Unborrow<Target = impl D27Pin> + 'd,
d28: impl Unborrow<Target = impl D28Pin> + 'd,
d29: impl Unborrow<Target = impl D29Pin> + 'd,
d30: impl Unborrow<Target = impl D30Pin> + 'd,
d31: impl Unborrow<Target = impl D31Pin> + 'd,
nbl0: impl Unborrow<Target = impl NBL0Pin> + 'd,
nbl1: impl Unborrow<Target = impl NBL1Pin> + 'd,
nbl2: impl Unborrow<Target = impl NBL2Pin> + 'd,
nbl3: impl Unborrow<Target = impl NBL3Pin> + 'd,
sdcke0: impl Unborrow<Target = impl SDCKE1Pin> + 'd,
sdclk: impl Unborrow<Target = impl SDCLKPin> + 'd,
sdncas: impl Unborrow<Target = impl SDNCASPin> + 'd,
sdnras: impl Unborrow<Target = impl SDNRASPin> + 'd,
sdne0: impl Unborrow<Target = impl SDNE1Pin> + 'd,
sdnwe: impl Unborrow<Target = impl SDNWEPin> + 'd,
chip: CHIP,
) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
unborrow!(
instance, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ba0, ba1, d0, d1, d2, d3,
d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21,
d22, d23, d24, d25, d26, d27, d28, d29, d30, d31, nbl0, nbl1, nbl2, nbl3, sdcke0,
sdclk, sdncas, sdnras, sdne0, sdnwe
);
// TODO configure pins?
a0.configure();
a1.configure();
a2.configure();
a3.configure();
a4.configure();
a5.configure();
a6.configure();
a7.configure();
a8.configure();
a9.configure();
a10.configure();
a11.configure();
ba0.configure();
ba1.configure();
d0.configure();
d1.configure();
d2.configure();
d3.configure();
d4.configure();
d5.configure();
d6.configure();
d7.configure();
d8.configure();
d9.configure();
d10.configure();
d11.configure();
d12.configure();
d13.configure();
d14.configure();
d15.configure();
d16.configure();
d17.configure();
d18.configure();
d19.configure();
d20.configure();
d21.configure();
d22.configure();
d23.configure();
d24.configure();
d25.configure();
d26.configure();
d27.configure();
d28.configure();
d29.configure();
d30.configure();
d31.configure();
nbl0.configure();
nbl1.configure();
nbl2.configure();
nbl3.configure();
sdcke0.configure();
sdclk.configure();
sdncas.configure();
sdnras.configure();
sdne0.configure();
sdnwe.configure();
let fmc = Self { peri: PhantomData };
stm32_fmc::Sdram::new(
fmc,
(
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ba0, ba1, d0, d1, d2, d3, d4, d5,
d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21, d22,
d23, d24, d25, d26, d27, d28, d29, d30, d31, nbl0, nbl1, nbl2, nbl3, sdcke0, sdclk,
sdncas, sdne0, sdnras, sdnwe,
),
chip,
)
}
}
mod sealed {
pub trait Instance: crate::rcc::sealed::RccPeripheral {
fn regs() -> crate::pac::fmc::Fmc;
}
macro_rules! declare_pin {
($name:ident) => {
pub trait $name {
fn configure(&mut self);
}
};
}
declare_pin!(SDNWEPin);
declare_pin!(SDNCASPin);
declare_pin!(SDNRASPin);
declare_pin!(SDNE0Pin);
declare_pin!(SDNE1Pin);
declare_pin!(SDCKE0Pin);
declare_pin!(SDCKE1Pin);
declare_pin!(SDCLKPin);
declare_pin!(NBL0Pin);
declare_pin!(NBL1Pin);
declare_pin!(NBL2Pin);
declare_pin!(NBL3Pin);
declare_pin!(INTPin);
declare_pin!(NLPin);
declare_pin!(NWaitPin);
declare_pin!(NE1Pin);
declare_pin!(NE2Pin);
declare_pin!(NE3Pin);
declare_pin!(NE4Pin);
declare_pin!(NCEPin);
declare_pin!(NOEPin);
declare_pin!(NWEPin);
declare_pin!(ClkPin);
declare_pin!(BA0Pin);
declare_pin!(BA1Pin);
declare_pin!(D0Pin);
declare_pin!(D1Pin);
declare_pin!(D2Pin);
declare_pin!(D3Pin);
declare_pin!(D4Pin);
declare_pin!(D5Pin);
declare_pin!(D6Pin);
declare_pin!(D7Pin);
declare_pin!(D8Pin);
declare_pin!(D9Pin);
declare_pin!(D10Pin);
declare_pin!(D11Pin);
declare_pin!(D12Pin);
declare_pin!(D13Pin);
declare_pin!(D14Pin);
declare_pin!(D15Pin);
declare_pin!(D16Pin);
declare_pin!(D17Pin);
declare_pin!(D18Pin);
declare_pin!(D19Pin);
declare_pin!(D20Pin);
declare_pin!(D21Pin);
declare_pin!(D22Pin);
declare_pin!(D23Pin);
declare_pin!(D24Pin);
declare_pin!(D25Pin);
declare_pin!(D26Pin);
declare_pin!(D27Pin);
declare_pin!(D28Pin);
declare_pin!(D29Pin);
declare_pin!(D30Pin);
declare_pin!(D31Pin);
declare_pin!(DA0Pin);
declare_pin!(DA1Pin);
declare_pin!(DA2Pin);
declare_pin!(DA3Pin);
declare_pin!(DA4Pin);
declare_pin!(DA5Pin);
declare_pin!(DA6Pin);
declare_pin!(DA7Pin);
declare_pin!(DA8Pin);
declare_pin!(DA9Pin);
declare_pin!(DA10Pin);
declare_pin!(DA11Pin);
declare_pin!(DA12Pin);
declare_pin!(DA13Pin);
declare_pin!(DA14Pin);
declare_pin!(DA15Pin);
declare_pin!(A0Pin);
declare_pin!(A1Pin);
declare_pin!(A2Pin);
declare_pin!(A3Pin);
declare_pin!(A4Pin);
declare_pin!(A5Pin);
declare_pin!(A6Pin);
declare_pin!(A7Pin);
declare_pin!(A8Pin);
declare_pin!(A9Pin);
declare_pin!(A10Pin);
declare_pin!(A11Pin);
declare_pin!(A12Pin);
declare_pin!(A13Pin);
declare_pin!(A14Pin);
declare_pin!(A15Pin);
declare_pin!(A16Pin);
declare_pin!(A17Pin);
declare_pin!(A18Pin);
declare_pin!(A19Pin);
declare_pin!(A20Pin);
declare_pin!(A21Pin);
declare_pin!(A22Pin);
declare_pin!(A23Pin);
declare_pin!(A24Pin);
declare_pin!(A25Pin);
declare_pin!(A26Pin);
declare_pin!(A27Pin);
declare_pin!(A28Pin);
declare_pin!(A29Pin);
declare_pin!(A30Pin);
declare_pin!(A31Pin);
}
macro_rules! declare_pin {
($name:ident, $fmc_pin:ident) => {
pub trait $name: sealed::$name + stm32_fmc::$fmc_pin + 'static {}
};
}
declare_pin!(SDNWEPin, SDNWE);
declare_pin!(SDNCASPin, SDNCAS);
declare_pin!(SDNRASPin, SDNRAS);
declare_pin!(SDNE0Pin, SDNE0);
declare_pin!(SDNE1Pin, SDNE1);
declare_pin!(SDCKE0Pin, SDCKE0);
declare_pin!(SDCKE1Pin, SDCKE1);
declare_pin!(SDCLKPin, SDCLK);
declare_pin!(NBL0Pin, NBL0);
declare_pin!(NBL1Pin, NBL1);
declare_pin!(NBL2Pin, NBL2);
declare_pin!(NBL3Pin, NBL3);
declare_pin!(INTPin, INT);
declare_pin!(NLPin, NL);
declare_pin!(NWaitPin, NWAIT);
declare_pin!(NE1Pin, NE1);
declare_pin!(NE2Pin, NE2);
declare_pin!(NE3Pin, NE3);
declare_pin!(NE4Pin, NE4);
declare_pin!(NCEPin, NCE);
declare_pin!(NOEPin, NOE);
declare_pin!(NWEPin, NWE);
declare_pin!(ClkPin, CLK);
declare_pin!(BA0Pin, BA0);
declare_pin!(BA1Pin, BA1);
declare_pin!(D0Pin, D0);
declare_pin!(D1Pin, D1);
declare_pin!(D2Pin, D2);
declare_pin!(D3Pin, D3);
declare_pin!(D4Pin, D4);
declare_pin!(D5Pin, D5);
declare_pin!(D6Pin, D6);
declare_pin!(D7Pin, D7);
declare_pin!(D8Pin, D8);
declare_pin!(D9Pin, D9);
declare_pin!(D10Pin, D10);
declare_pin!(D11Pin, D11);
declare_pin!(D12Pin, D12);
declare_pin!(D13Pin, D13);
declare_pin!(D14Pin, D14);
declare_pin!(D15Pin, D15);
declare_pin!(D16Pin, D16);
declare_pin!(D17Pin, D17);
declare_pin!(D18Pin, D18);
declare_pin!(D19Pin, D19);
declare_pin!(D20Pin, D20);
declare_pin!(D21Pin, D21);
declare_pin!(D22Pin, D22);
declare_pin!(D23Pin, D23);
declare_pin!(D24Pin, D24);
declare_pin!(D25Pin, D25);
declare_pin!(D26Pin, D26);
declare_pin!(D27Pin, D27);
declare_pin!(D28Pin, D28);
declare_pin!(D29Pin, D29);
declare_pin!(D30Pin, D30);
declare_pin!(D31Pin, D31);
declare_pin!(DA0Pin, DA0);
declare_pin!(DA1Pin, DA1);
declare_pin!(DA2Pin, DA2);
declare_pin!(DA3Pin, DA3);
declare_pin!(DA4Pin, DA4);
declare_pin!(DA5Pin, DA5);
declare_pin!(DA6Pin, DA6);
declare_pin!(DA7Pin, DA7);
declare_pin!(DA8Pin, DA8);
declare_pin!(DA9Pin, DA9);
declare_pin!(DA10Pin, DA10);
declare_pin!(DA11Pin, DA11);
declare_pin!(DA12Pin, DA12);
declare_pin!(DA13Pin, DA13);
declare_pin!(DA14Pin, DA14);
declare_pin!(DA15Pin, DA15);
declare_pin!(A0Pin, A0);
declare_pin!(A1Pin, A1);
declare_pin!(A2Pin, A2);
declare_pin!(A3Pin, A3);
declare_pin!(A4Pin, A4);
declare_pin!(A5Pin, A5);
declare_pin!(A6Pin, A6);
declare_pin!(A7Pin, A7);
declare_pin!(A8Pin, A8);
declare_pin!(A9Pin, A9);
declare_pin!(A10Pin, A10);
declare_pin!(A11Pin, A11);
declare_pin!(A12Pin, A12);
declare_pin!(A13Pin, A13);
declare_pin!(A14Pin, A14);
declare_pin!(A15Pin, A15);
declare_pin!(A16Pin, A16);
declare_pin!(A17Pin, A17);
declare_pin!(A18Pin, A18);
declare_pin!(A19Pin, A19);
declare_pin!(A20Pin, A20);
declare_pin!(A21Pin, A21);
declare_pin!(A22Pin, A22);
declare_pin!(A23Pin, A23);
declare_pin!(A24Pin, A24);
declare_pin!(A25Pin, A25);
pub trait Instance: sealed::Instance + 'static {}
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 {}
};
);
macro_rules! impl_pin {
($pin:ident, $signal:ident, $fmc_name:ident, $af:expr) => {
impl sealed::$signal for crate::peripherals::$pin {
fn configure(&mut self) {
use crate::gpio::sealed::{AFType::OutputPushPull, Pin as SealedPin};
use crate::gpio::Pin;
use crate::pac::gpio::vals::Ospeedr;
critical_section::with(|_| unsafe {
self.set_as_af($af, OutputPushPull);
self.block()
.ospeedr()
.modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
})
}
}
impl stm32_fmc::$fmc_name for crate::peripherals::$pin {}
impl $signal for crate::peripherals::$pin {}
};
}
crate::pac::peripheral_pins!(
($inst:ident, fmc, FMC, $pin:ident, A0, $af:expr) => {
impl_pin!($pin, A0Pin, A0, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A1, $af:expr) => {
impl_pin!($pin, A1Pin, A1, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A2, $af:expr) => {
impl_pin!($pin, A2Pin, A2, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A3, $af:expr) => {
impl_pin!($pin, A3Pin, A3, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A4, $af:expr) => {
impl_pin!($pin, A4Pin, A4, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A5, $af:expr) => {
impl_pin!($pin, A5Pin, A5, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A6, $af:expr) => {
impl_pin!($pin, A6Pin, A6, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A7, $af:expr) => {
impl_pin!($pin, A7Pin, A7, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A8, $af:expr) => {
impl_pin!($pin, A8Pin, A8, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A9, $af:expr) => {
impl_pin!($pin, A9Pin, A9, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A10, $af:expr) => {
impl_pin!($pin, A10Pin, A10, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A11, $af:expr) => {
impl_pin!($pin, A11Pin, A11, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A12, $af:expr) => {
impl_pin!($pin, A12Pin, A12, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A13, $af:expr) => {
impl_pin!($pin, A13Pin, A13, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A14, $af:expr) => {
impl_pin!($pin, A14Pin, A14, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A15, $af:expr) => {
impl_pin!($pin, A15Pin, A15, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A16, $af:expr) => {
impl_pin!($pin, A16Pin, A16, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A17, $af:expr) => {
impl_pin!($pin, A17Pin, A17, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A18, $af:expr) => {
impl_pin!($pin, A18Pin, A18, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A19, $af:expr) => {
impl_pin!($pin, A19Pin, A19, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A20, $af:expr) => {
impl_pin!($pin, A20Pin, A20, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A21, $af:expr) => {
impl_pin!($pin, A21Pin, A21, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A22, $af:expr) => {
impl_pin!($pin, A22Pin, A22, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A23, $af:expr) => {
impl_pin!($pin, A23Pin, A23, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A24, $af:expr) => {
impl_pin!($pin, A24Pin, A24, $af);
};
($inst:ident, fmc, FMC, $pin:ident, A25, $af:expr) => {
impl_pin!($pin, A25Pin, A25, $af);
};
);
crate::pac::peripheral_pins!(
($inst:ident, fmc, FMC, $pin:ident, D0, $af:expr) => {
impl_pin!($pin, D0Pin, D0, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D1, $af:expr) => {
impl_pin!($pin, D1Pin, D1, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D2, $af:expr) => {
impl_pin!($pin, D2Pin, D2, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D3, $af:expr) => {
impl_pin!($pin, D3Pin, D3, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D4, $af:expr) => {
impl_pin!($pin, D4Pin, D4, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D5, $af:expr) => {
impl_pin!($pin, D5Pin, D5, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D6, $af:expr) => {
impl_pin!($pin, D6Pin, D6, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D7, $af:expr) => {
impl_pin!($pin, D7Pin, D7, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D8, $af:expr) => {
impl_pin!($pin, D8Pin, D8, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D9, $af:expr) => {
impl_pin!($pin, D9Pin, D9, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D10, $af:expr) => {
impl_pin!($pin, D10Pin, D10, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D11, $af:expr) => {
impl_pin!($pin, D11Pin, D11, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D12, $af:expr) => {
impl_pin!($pin, D12Pin, D12, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D13, $af:expr) => {
impl_pin!($pin, D13Pin, D13, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D14, $af:expr) => {
impl_pin!($pin, D14Pin, D14, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D15, $af:expr) => {
impl_pin!($pin, D15Pin, D15, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D16, $af:expr) => {
impl_pin!($pin, D16Pin, D16, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D17, $af:expr) => {
impl_pin!($pin, D17Pin, D17, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D18, $af:expr) => {
impl_pin!($pin, D18Pin, D18, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D19, $af:expr) => {
impl_pin!($pin, D19Pin, D19, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D20, $af:expr) => {
impl_pin!($pin, D20Pin, D20, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D21, $af:expr) => {
impl_pin!($pin, D21Pin, D21, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D22, $af:expr) => {
impl_pin!($pin, D22Pin, D22, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D23, $af:expr) => {
impl_pin!($pin, D23Pin, D23, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D24, $af:expr) => {
impl_pin!($pin, D24Pin, D24, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D25, $af:expr) => {
impl_pin!($pin, D25Pin, D25, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D26, $af:expr) => {
impl_pin!($pin, D26Pin, D26, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D27, $af:expr) => {
impl_pin!($pin, D27Pin, D27, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D28, $af:expr) => {
impl_pin!($pin, D28Pin, D28, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D29, $af:expr) => {
impl_pin!($pin, D29Pin, D29, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D30, $af:expr) => {
impl_pin!($pin, D30Pin, D30, $af);
};
($inst:ident, fmc, FMC, $pin:ident, D31, $af:expr) => {
impl_pin!($pin, D31Pin, D31, $af);
};
);
crate::pac::peripheral_pins!(
($inst:ident, fmc, FMC, $pin:ident, DA0, $af:expr) => {
impl_pin!($pin, DA0Pin, DA0, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA1, $af:expr) => {
impl_pin!($pin, DA1Pin, DA1, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA2, $af:expr) => {
impl_pin!($pin, DA2Pin, DA2, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA3, $af:expr) => {
impl_pin!($pin, DA3Pin, DA3, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA4, $af:expr) => {
impl_pin!($pin, DA4Pin, DA4, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA5, $af:expr) => {
impl_pin!($pin, DA5Pin, DA5, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA6, $af:expr) => {
impl_pin!($pin, DA6Pin, DA6, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA7, $af:expr) => {
impl_pin!($pin, DA7Pin, DA7, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA8, $af:expr) => {
impl_pin!($pin, DA8Pin, DA8, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA9, $af:expr) => {
impl_pin!($pin, DA9Pin, DA9, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA10, $af:expr) => {
impl_pin!($pin, DA10Pin, DA10, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA11, $af:expr) => {
impl_pin!($pin, DA11Pin, DA11, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA12, $af:expr) => {
impl_pin!($pin, DA12Pin, DA12, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA13, $af:expr) => {
impl_pin!($pin, DA13Pin, DA13, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA14, $af:expr) => {
impl_pin!($pin, DA14Pin, DA14, $af);
};
($inst:ident, fmc, FMC, $pin:ident, DA15, $af:expr) => {
impl_pin!($pin, DA15Pin, DA15, $af);
};
);
crate::pac::peripheral_pins!(
($inst:ident, fmc, FMC, $pin:ident, SDNWE, $af:expr) => {
impl_pin!($pin, SDNWEPin, SDNWE, $af);
};
($inst:ident, fmc, FMC, $pin:ident, SDNCAS, $af:expr) => {
impl_pin!($pin, SDNCASPin, SDNCAS, $af);
};
($inst:ident, fmc, FMC, $pin:ident, SDNRAS, $af:expr) => {
impl_pin!($pin, SDNRASPin, SDNRAS, $af);
};
($inst:ident, fmc, FMC, $pin:ident, SDNE0, $af:expr) => {
impl_pin!($pin, SDNE0Pin, SDNE0, $af);
};
($inst:ident, fmc, FMC, $pin:ident, SDNE1, $af:expr) => {
impl_pin!($pin, SDNE1Pin, SDNE1, $af);
};
($inst:ident, fmc, FMC, $pin:ident, SDCKE0, $af:expr) => {
impl_pin!($pin, SDCKE0Pin, SDCKE0, $af);
};
($inst:ident, fmc, FMC, $pin:ident, SDCKE1, $af:expr) => {
impl_pin!($pin, SDCKE1Pin, SDCKE1, $af);
};
($inst:ident, fmc, FMC, $pin:ident, SDCLK, $af:expr) => {
impl_pin!($pin, SDCLKPin, SDCLK, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NBL0, $af:expr) => {
impl_pin!($pin, NBL0Pin, NBL0, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NBL1, $af:expr) => {
impl_pin!($pin, NBL1Pin, NBL1, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NBL2, $af:expr) => {
impl_pin!($pin, NBL2Pin, NBL2, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NBL3, $af:expr) => {
impl_pin!($pin, NBL3Pin, NBL3, $af);
};
($inst:ident, fmc, FMC, $pin:ident, INT, $af:expr) => {
impl_pin!($pin, INTPin, INT, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NL, $af:expr) => {
impl_pin!($pin, NLPin, NL, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NWAIT, $af:expr) => {
impl_pin!($pin, NWaitPin, NWAIT, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NE1, $af:expr) => {
impl_pin!($pin, NE1Pin, NE1, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NE2, $af:expr) => {
impl_pin!($pin, NE2Pin, NE2, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NE3, $af:expr) => {
impl_pin!($pin, NE3Pin, NE3, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NE4, $af:expr) => {
impl_pin!($pin, NE4Pin, NE4, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NCE, $af:expr) => {
impl_pin!($pin, NCEPin, NCE, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NOE, $af:expr) => {
impl_pin!($pin, NOEPin, NOE, $af);
};
($inst:ident, fmc, FMC, $pin:ident, NWE, $af:expr) => {
impl_pin!($pin, NWEPin, NWE, $af);
};
($inst:ident, fmc, FMC, $pin:ident, Clk, $af:expr) => {
impl_pin!($pin, ClkPin, CLK, $af);
};
($inst:ident, fmc, FMC, $pin:ident, BA0, $af:expr) => {
impl_pin!($pin, BA0Pin, BA0, $af);
};
($inst:ident, fmc, FMC, $pin:ident, BA1, $af:expr) => {
impl_pin!($pin, BA1Pin, BA1, $af);
};
);
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
#[path = "../example_common.rs"]
mod example_common;
use embassy::executor::Spawner;
use embassy::time::{Delay, Duration, Timer};
use embassy_stm32::fmc::Fmc;
use embassy_stm32::Peripherals;
use example_common::*;
#[embassy::main(config = "config()")]
async fn main(_spawner: Spawner, p: Peripherals) {
info!("Hello World!");
let mut core_peri = cortex_m::Peripherals::take().unwrap();
// taken from stm32h7xx-hal
core_peri.SCB.enable_icache();
// ----------------------------------------------------------
// Configure MPU for external SDRAM
// MPU config for SDRAM write-through
let sdram_size = 8 * 1024 * 1024;
{
let mpu = core_peri.MPU;
let scb = &mut core_peri.SCB;
let size = sdram_size;
// Refer to ARM®v7-M Architecture Reference Manual ARM DDI 0403
// Version E.b Section B3.5
const MEMFAULTENA: u32 = 1 << 16;
unsafe {
/* Make sure outstanding transfers are done */
cortex_m::asm::dmb();
scb.shcsr.modify(|r| r & !MEMFAULTENA);
/* Disable the MPU and clear the control register*/
mpu.ctrl.write(0);
}
const REGION_NUMBER0: u32 = 0x00;
const REGION_BASE_ADDRESS: u32 = 0xD000_0000;
const REGION_FULL_ACCESS: u32 = 0x03;
const REGION_CACHEABLE: u32 = 0x01;
const REGION_WRITE_BACK: u32 = 0x01;
const REGION_ENABLE: u32 = 0x01;
crate::assert_eq!(
size & (size - 1),
0,
"SDRAM memory region size must be a power of 2"
);
crate::assert_eq!(
size & 0x1F,
0,
"SDRAM memory region size must be 32 bytes or more"
);
fn log2minus1(sz: u32) -> u32 {
for i in 5..=31 {
if sz == (1 << i) {
return i - 1;
}
}
crate::panic!("Unknown SDRAM memory region size!");
}
//info!("SDRAM Memory Size 0x{:x}", log2minus1(size as u32));
// Configure region 0
//
// Cacheable, outer and inner write-back, no write allocate. So
// reads are cached, but writes always write all the way to SDRAM
unsafe {
mpu.rnr.write(REGION_NUMBER0);
mpu.rbar.write(REGION_BASE_ADDRESS);
mpu.rasr.write(
(REGION_FULL_ACCESS << 24)
| (REGION_CACHEABLE << 17)
| (REGION_WRITE_BACK << 16)
| (log2minus1(size as u32) << 1)
| REGION_ENABLE,
);
}
const MPU_ENABLE: u32 = 0x01;
const MPU_DEFAULT_MMAP_FOR_PRIVILEGED: u32 = 0x04;
// Enable
unsafe {
mpu.ctrl
.modify(|r| r | MPU_DEFAULT_MMAP_FOR_PRIVILEGED | MPU_ENABLE);
scb.shcsr.modify(|r| r | MEMFAULTENA);
// Ensure MPU settings take effect
cortex_m::asm::dsb();
cortex_m::asm::isb();
}
}
let mut sdram = Fmc::sdram_32bits(
p.FMC,
// A0-A11
p.PF0,
p.PF1,
p.PF2,
p.PF3,
p.PF4,
p.PF5,
p.PF12,
p.PF13,
p.PF14,
p.PF15,
p.PG0,
p.PG1,
// BA0-BA1
p.PG4,
p.PG5,
// D0-D31
p.PD14,
p.PD15,
p.PD0,
p.PD1,
p.PE7,
p.PE8,
p.PE9,
p.PE10,
p.PE11,
p.PE12,
p.PE13,
p.PE14,
p.PE15,
p.PD8,
p.PD9,
p.PD10,
p.PH8,
p.PH9,
p.PH10,
p.PH11,
p.PH12,
p.PH13,
p.PH14,
p.PH15,
p.PI0,
p.PI1,
p.PI2,
p.PI3,
p.PI6,
p.PI7,
p.PI9,
p.PI10,
// NBL0 - NBL3
p.PE0,
p.PE1,
p.PI4,
p.PI5,
p.PH7, // SDCKE1
p.PG8, // SDCLK
p.PG15, // SDNCAS
p.PF11, // SDRAS
p.PH6, // SDNE1 (!CS)
p.PH5, // SDNWE,
stm32_fmc::devices::is42s32800g_6::Is42s32800g {},
);
let mut delay = Delay;
let ram_slice = unsafe {
// Initialise controller and SDRAM
let ram_ptr: *mut u32 = sdram.init(&mut delay);
// Get 16-bit words
let ram_ptr = ram_ptr as *mut u32;
// Convert raw pointer to slice
let ram_slice = core::slice::from_raw_parts_mut(ram_ptr, sdram_size);
// Return a 4-word slice
let size = 5usize;
let mut chunks = ram_slice.chunks_exact_mut(size);
chunks.next().unwrap()
};
// // ----------------------------------------------------------
// // Use memory in SDRAM
ram_slice[0] = 1u32;
ram_slice[1] = 2;
ram_slice[2] = 3;
ram_slice[3] = 4;
ram_slice[4] = 5;
defmt::error!("ram: {}", ram_slice.len());
crate::assert_eq!(ram_slice[0], 1);
loop {
info!("high");
Timer::after(Duration::from_millis(500)).await;
info!("low");
Timer::after(Duration::from_millis(500)).await;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment