embassy/embassy-stm32/src/fmc/mod.rs

163 lines
6.2 KiB
Rust
Raw Normal View History

2022-02-08 14:32:18 +01:00
use core::marker::PhantomData;
2022-06-12 22:15:44 +02:00
use embassy_hal_common::into_ref;
2022-02-08 14:32:18 +01:00
use crate::gpio::sealed::AFType;
use crate::gpio::{Pull, Speed};
use crate::Peripheral;
mod pins;
pub use pins::*;
2022-02-08 14:32:18 +01:00
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) {
// fmc v1 and v2 does not have the fmcen bit
2023-02-07 14:14:47 +01:00
// fsmc v1, v2 and v3 does not have the fmcen bit
// This is a "not" because it is expected that all future versions have this bit
2023-02-07 15:06:16 +01:00
#[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1)))]
unsafe {
T::regs().bcr1().modify(|r| r.set_fmcen(true))
};
2022-02-08 14:32:18 +01:00
}
fn source_clock_hz(&self) -> u32 {
<T as crate::rcc::sealed::RccPeripheral>::frequency().0
}
}
2022-02-08 14:32:18 +01:00
macro_rules! config_pins {
($($pin:ident),*) => {
into_ref!($($pin),*);
2022-02-08 14:32:18 +01:00
$(
$pin.set_as_af_pull($pin.af_num(), AFType::OutputPushPull, Pull::Up);
$pin.set_speed(Speed::VeryHigh);
2022-02-08 14:32:18 +01:00
)*
};
2022-02-08 14:32:18 +01:00
}
macro_rules! fmc_sdram_constructor {
($name:ident: (
bank: $bank:expr,
2022-02-08 14:32:18 +01:00
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 Peripheral<P = T> + 'd,
$($addr_pin_name: impl Peripheral<P = impl $addr_signal<T>> + 'd),*,
$($ba_pin_name: impl Peripheral<P = impl $ba_signal<T>> + 'd),*,
$($d_pin_name: impl Peripheral<P = impl $d_signal<T>> + 'd),*,
$($nbl_pin_name: impl Peripheral<P = impl $nbl_signal<T>> + 'd),*,
$($ctrl_pin_name: impl Peripheral<P = impl $ctrl_signal<T>> + 'd),*,
2022-02-08 14:32:18 +01:00
chip: CHIP
) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
critical_section::with(|_| unsafe {
2022-02-08 14:32:18 +01:00
config_pins!(
$($addr_pin_name),*,
$($ba_pin_name),*,
$($d_pin_name),*,
$($nbl_pin_name),*,
$($ctrl_pin_name),*
);
});
2022-02-08 14:32:18 +01:00
let fmc = Self { peri: PhantomData };
stm32_fmc::Sdram::new_unchecked(
2022-02-08 14:32:18 +01:00
fmc,
$bank,
2022-02-08 14:32:18 +01:00
chip,
)
}
};
}
impl<'d, T: Instance> Fmc<'d, T> {
fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank1: (
bank: stm32_fmc::SdramTargetBank::Bank1,
2022-02-08 14:32:18 +01:00
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)
]
));
2023-02-07 16:06:59 +01:00
fmc_sdram_constructor!(sdram_a12bits_d16bits_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)
],
nbl: [
(nbl0: NBL0Pin), (nbl1: NBL1Pin)
],
ctrl: [
(sdcke: SDCKE1Pin), (sdclk: SDCLKPin), (sdncas: SDNCASPin), (sdne: SDNE1Pin), (sdnras: SDNRASPin), (sdnwe: SDNWEPin)
]
));
2022-02-08 14:32:18 +01:00
fmc_sdram_constructor!(sdram_a12bits_d32bits_4banks_bank2: (
bank: stm32_fmc::SdramTargetBank::Bank2,
2022-02-08 14:32:18 +01:00
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)
]
));
}
foreach_peripheral!(
2022-02-08 14:32:18 +01:00
(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 {}
};
);