Expand description
Hardware Abstraction Layer for STM32 Memory Controllers (FMC/FSMC)
Implementation Guide
You can use the functionality in this crate by implementing the
FmcPeripheral
trait. You should implement this trait for a
structure that:
- Takes ownership of the
FMC
/FSMC
peripheral - Takes ownership of any structures / ZSTs related to the power or clock for the
FMC
/FSMC
peripheral - Contains the frequency of the
FMC
/FSMC
source clock (usually HCLK)
A basic structure:
pub struct FMC {
source_clock: u32,
// any other fields here...
}
An implementation of FmcPeripheral
:
use stm32_fmc::FmcPeripheral;
unsafe impl Sync for FMC {}
unsafe impl FmcPeripheral for FMC {
const REGISTERS: *const () = stm32::FMC::ptr() as *const ();
fn enable(&mut self) {
// Enable and reset the FMC/FSMC using the RCC registers
// Typically RCC.AHBxEN and RCC.AHBxRST
}
fn memory_controller_enable(&mut self) {
// Only required if your part has an `FMCEN` bit
}
fn source_clock_hz(&self) -> u32 {
self.source_clock
}
}
In a HAL, you can allow users to construct your structure by implementing a
new
method, or by making the fields public.
Wrap constructor methods
Each memory controller type (Sdram
, Nand
, ..) provides both
new
and new_unchecked
methods.
For the convenience of users, you may want to wrap these with your new
method,
so that each memory can be created from the peripheral in one step.
use stm32_fmc::{
AddressPinSet, PinsSdram, Sdram, SdramChip, SdramPinSet, SdramTargetBank,
};
impl FMC {
/// A new SDRAM memory via the Flexible Memory Controller
pub fn sdram<
BANK: SdramPinSet,
ADDR: AddressPinSet,
PINS: PinsSdram<BANK, ADDR>,
CHIP: SdramChip,
>(
fmc: stm32::FMC,
pins: PINS,
chip: CHIP,
clocks: &CoreClocks,
) -> Sdram<FMC, CHIP> {
let fmc = Self::new(fmc, clocks);
Sdram::new(fmc, pins, chip)
}
/// A new SDRAM memory via the Flexible Memory Controller
pub fn sdram_unchecked<CHIP: SdramChip, BANK: Into<SdramTargetBank>>(
fmc: stm32::FMC,
bank: BANK,
chip: CHIP,
clocks: &CoreClocks,
) -> Sdram<FMC, CHIP> {
let fmc = Self::new(fmc, clocks);
Sdram::new_unchecked(fmc, bank, chip)
}
}
Pin implementations
In contrast with the new_unchecked
methods, the new
methods require the user
pass a tuple as the pins
argument. In a HAL, you can mark which types are
suitable as follows:
impl stm32_fmc::A0 for gpiof::PF0<Alternate<AF12>> {}
// ...