stm32: Add support for FMC

This commit is contained in:
Matous Hybl 2022-02-08 14:32:18 +01:00
parent fee1de109d
commit d37d714314
7 changed files with 1027 additions and 1 deletions

View file

@ -30,6 +30,7 @@ stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", features = ["rt"
vcell = { version = "0.1.3", optional = true }
bxcan = "0.6.2"
nb = "1.0.0"
stm32-fmc = "0.2.4"
seq-macro = "0.2.2"
cfg-if = "1.0.0"

View file

@ -0,0 +1,145 @@
mod pins;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
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) {
<T as crate::rcc::sealed::RccPeripheral>::enable();
<T as crate::rcc::sealed::RccPeripheral>::reset();
}
fn memory_controller_enable(&mut self) {
// The FMCEN bit of the FMC_BCR2..4 registers is dont
// 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 {
<T as crate::rcc::sealed::RccPeripheral>::frequency().0
}
}
macro_rules! config_pins {
($($pin:ident),*) => {
$(
$pin.configure();
)*
};
}
macro_rules! fmc_sdram_constructor {
($name:ident: (
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<CHIP: stm32_fmc::SdramChip>(
_instance: impl Unborrow<Target = T> + 'd,
$($addr_pin_name: impl Unborrow<Target = impl $addr_signal> + 'd),*,
$($ba_pin_name: impl Unborrow<Target = impl $ba_signal> + 'd),*,
$($d_pin_name: impl Unborrow<Target = impl $d_signal> + 'd),*,
$($nbl_pin_name: impl Unborrow<Target = impl $nbl_signal> + 'd),*,
$($ctrl_pin_name: impl Unborrow<Target = impl $ctrl_signal> + 'd),*,
chip: CHIP
) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
unborrow!(
$($addr_pin_name),*,
$($ba_pin_name),*,
$($d_pin_name),*,
$($nbl_pin_name),*,
$($ctrl_pin_name),*
);
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(
fmc,
(
$($addr_pin_name),*,
$($ba_pin_name),*,
$($d_pin_name),*,
$($nbl_pin_name),*,
$($ctrl_pin_name),*,
),
chip,
)
}
};
}
impl<'d, T: Instance> Fmc<'d, T> {
fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_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: (
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)
]
));
}
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 {}
};
);

View file

@ -0,0 +1,672 @@
pub(crate) 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);
}
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);
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::gpio::Speed;
use crate::pac::gpio::vals::Pupdr;
critical_section::with(|_| unsafe {
self.set_as_af($af, OutputPushPull);
self.set_speed(Speed::VeryHigh);
self.block()
.pupdr()
.modify(|w| w.set_pupdr(self.pin() as usize, Pupdr::PULLUP));
})
}
}
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);
};
);

View file

@ -36,6 +36,8 @@ pub mod dcmi;
pub mod eth;
#[cfg(feature = "exti")]
pub mod exti;
#[cfg(fmc)]
pub mod fmc;
#[cfg(i2c)]
pub mod i2c;

View file

@ -9,7 +9,7 @@ resolver = "2"
[dependencies]
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] }
embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] }
@ -26,6 +26,7 @@ heapless = { version = "0.7.5", default-features = false }
rand_core = "0.6.3"
critical-section = "0.2.5"
micromath = "2.0.0"
stm32-fmc = "0.2.4"
[dependencies.smoltcp]
version = "0.8.0"

View file

@ -0,0 +1,204 @@
#![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();
// See Errata Sheet 2.2.1
// core_peri.SCB.enable_dcache(&mut core_peri.CPUID);
core_peri.DWT.enable_cycle_counter();
// ----------------------------------------------------------
// Configure MPU for external SDRAM
// MPU config for SDRAM write-through
let sdram_size = 32 * 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_a12bits_d32bits_4banks_bank2(
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.PH6, // SDNE1 (!CS)
p.PF11, // SDRAS
p.PC0, // SDNWE, change to p.PH5 for EVAL boards
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) as *mut _;
// Convert raw pointer to slice
core::slice::from_raw_parts_mut(ram_ptr, sdram_size / core::mem::size_of::<u32>())
};
// // ----------------------------------------------------------
// // Use memory in SDRAM
info!("RAM contents before writing: {:x}", ram_slice[..10]);
ram_slice[0] = 1;
ram_slice[1] = 2;
ram_slice[2] = 3;
ram_slice[3] = 4;
info!("RAM contents after writing: {:x}", ram_slice[..10]);
crate::assert_eq!(ram_slice[0], 1);
crate::assert_eq!(ram_slice[1], 2);
crate::assert_eq!(ram_slice[2], 3);
crate::assert_eq!(ram_slice[3], 4);
info!("Assertions succeeded.");
loop {
Timer::after(Duration::from_millis(1000)).await;
}
}

View file

@ -22,6 +22,7 @@ defmt::timestamp! {"{=u64}", {
pub fn config() -> Config {
let mut config = Config::default();
config.rcc.sys_ck = Some(400.mhz().into());
config.rcc.hclk = Some(200.mhz().into());
config.rcc.pll1.q_ck = Some(100.mhz().into());
config
}