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/FSMCperipheral - Takes ownership of any structures / ZSTs related to the power or clock for the
FMC/FSMCperipheral - Contains the frequency of the
FMC/FSMCsource 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>> {}
// ...