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
instance, 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)
};
The FMC peripheral supports once external parallel NAND flash device.
External memories are defined by
NandChip
implementations. There are 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 = (
// A17/ALE
// A16/CLE
pa0, ...
// D0-D7
// NCE/#CE
// NOE/#RE
// NWE/#WE
// NWAIT/R/#B
);
If you are using a HAL, see the HAL documentation.
Otherwise you can implement
FmcPeripheral
yourself then use
Nand::new
/
Nand::new_unchecked
directly.
Once you have an
Nand
instance
you should initialise it by calling
init
. This
returns a
NandDevice
instance.
let mut nand_device = nand.init(&mut delay);
// Read device identifier
let id = nand_device.read_id();
TODO
The library automatically does some trace-level logging either via log
or via defmt
.
To enable such logging, enable either the log
or defmt
feature in your Cargo.toml
.
For debugging the SDRAM register contents, the library provides additional feature trace-register-values
, which when enabled causes the init function to log the register contents to the trace level.
This is useful for example when you want to compare the register values between stm32-fmc
and CubeMX code.
Note that one of the logging features (log
/defmt
) must be enabled for this to work.
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 --set-upstream origin v0.2.0
Create a PR and check CI passes
git push --set-upstream origin v0.2.0:master
git tag -a 'v0.2.0' -m 'v0.2.0'
git push origin refs/tags/v0.2.0
cargo publish
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
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.