#stm32 #memory #fmc #sdram

no-std stm32-fmc

Hardware Abstraction Layer for STM32 Memory Controllers (FMC/FSMC)

8 releases

0.2.4 Oct 5, 2021
0.2.3 May 25, 2021
0.2.2 Mar 27, 2021
0.2.1 Nov 7, 2020
0.1.2 Aug 5, 2020

#38 in Embedded development

Download history 149/week @ 2021-07-02 421/week @ 2021-07-09 311/week @ 2021-07-16 120/week @ 2021-07-23 136/week @ 2021-07-30 39/week @ 2021-08-06 162/week @ 2021-08-13 41/week @ 2021-08-20 77/week @ 2021-08-27 56/week @ 2021-09-03 269/week @ 2021-09-10 147/week @ 2021-09-17 93/week @ 2021-09-24 214/week @ 2021-10-01 173/week @ 2021-10-08 111/week @ 2021-10-15

664 downloads per month
Used in 3 crates





docs.rs Crates.io

Hardware Abstraction Layer for STM32 Memory Controllers (FMC/FSMC)

Currently only SDRAM functions are implemented.

This crate is a work in progress! Contributions very welcome


(If your HAL already implements FMC, you can skip this)

See the docs



The FMC peripheral supports up to 2 external SDRAM devices. This crate currently only supports 1, although it may be on either bank 1 or 2.

External memories are defined by SdramChip implementations. There are several examples in the devices folder, or you can make your own.

To pass pins to a constructor, create a tuple with the following ordering:

let pins = (
    // A0-A12
    pa0, ...
    // BA0-BA1
    // D0-D31
    // NBL0 - NBL3
    // SDCKE
    // SDCLK
    // SDNCAS
    // SDNE
    // SDRAS
    // SDNWE

You can leave out address/data pins not used by your memory.


If you are using a HAL, see the HAL documentation.

Otherwise you can implement FmcPeripheral yourself then use Sdram::new / Sdram::new_unchecked directly.


Once you have an Sdram type, you can:

  • Initialise it by calling init. This returns a raw pointer
  • Convert the raw pointer to a sized slice using from_raw_parts_mut
let ram = unsafe {
    // Initialise controller and SDRAM
    let ram_ptr: *mut u32 = sdram.init(&mut delay);

    // 32 MByte = 256Mbit SDRAM = 8M u32 words
    slice::from_raw_parts_mut(ram_ptr, 8 * 1024 * 1024)



NAND Flash


Implementing a new device

If you end up depending on a fork or a newer version of this crate than the HAL crate for your device, you can override the version pulled in by the external crate using a [patch] section in your Cargo.toml, as described in the Cargo Book.


  • Update Cargo.toml
  • Update CHANGELOG.md
git commit -am 'v0.2.0'
git push origin
git tag -a 'v0.2.0' -m 'v0.2.0'
git push origin v0.2.0
cargo publish


Licensed under either of

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.