Skip to content

STM32: Configurable bank support #4125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ cargo test --manifest-path ./embassy-nrf/Cargo.toml --no-default-features --feat
cargo test --manifest-path ./embassy-rp/Cargo.toml --no-default-features --features time-driver,rp2040,_test
cargo test --manifest-path ./embassy-rp/Cargo.toml --no-default-features --features time-driver,rp235xa,_test

cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f429vg,exti,time-driver-any,exti
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f732ze,exti,time-driver-any,exti
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f769ni,exti,time-driver-any,exti
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f429vg,time-driver-any,exti,single-bank
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f429vg,time-driver-any,exti,dual-bank
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f732ze,time-driver-any,exti
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f769ni,time-driver-any,exti,single-bank
cargo test --manifest-path ./embassy-stm32/Cargo.toml --no-default-features --features stm32f769ni,time-driver-any,exti,dual-bank

cargo test --manifest-path ./embassy-net-adin1110/Cargo.toml
25 changes: 13 additions & 12 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,17 @@ cargo batch \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv8m.main-none-eabihf --features time-driver,defmt,rp235xa \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv8m.main-none-eabihf --features time-driver,log,rp235xa \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv8m.main-none-eabihf --features time-driver,rp235xa,binary-info \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,exti,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,exti,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,exti \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,single-bank,defmt \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32f038f6,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32f030c6,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32f058t8,defmt,exti,time-driver-any,time \
Expand Down Expand Up @@ -153,10 +154,10 @@ cargo batch \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f378cc,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32g0c1ve,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,low-power,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,dual-bank,defmt,exti,time-driver-any,low-power,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32wl54jc-cm0p,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wle5jb,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g474pe,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g474pe,dual-bank,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f107vc,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f103re,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f100c4,defmt,exti,time-driver-any,time \
Expand Down
1 change: 1 addition & 0 deletions embassy-stm32/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased
- Modify BufferedUart initialization to take pins before interrupts ([#3983](https://github.com/embassy-rs/embassy/pull/3983))
- Added a 'single-bank' and a 'dual-bank' feature so chips with configurable flash bank setups are be supported in embassy ([#4125](https://github.com/embassy-rs/embassy/pull/4125))

## 0.2.0 - 2025-01-10

Expand Down
9 changes: 7 additions & 2 deletions embassy-stm32/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ rand_core = "0.6.3"
sdio-host = "0.9.0"
critical-section = "1.1"
#stm32-metapac = { version = "16" }
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-a821bf5dd8d283c1e8de88fc7699235777a07e78" }
# stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-380f03cb71f43a242adc45e83607a380ffe0447b" }
stm32-metapac = { git="https://ci.embassy.dev/jobs/3de13111608a/artifacts/generated.git" }

vcell = "0.1.3"
nb = "1.0.0"
Expand Down Expand Up @@ -102,7 +103,8 @@ proc-macro2 = "1.0.36"
quote = "1.0.15"

#stm32-metapac = { version = "16", default-features = false, features = ["metadata"]}
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-a821bf5dd8d283c1e8de88fc7699235777a07e78", default-features = false, features = ["metadata"] }
# stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-380f03cb71f43a242adc45e83607a380ffe0447b", default-features = false, features = ["metadata"] }
stm32-metapac = { git="https://ci.embassy.dev/jobs/3de13111608a/artifacts/generated.git", default-features = false, features = ["metadata"] }

[features]
default = ["rt"]
Expand Down Expand Up @@ -197,6 +199,9 @@ split-pc2 = ["_split-pins-enabled"]
## Split PC3
split-pc3 = ["_split-pins-enabled"]

dual-bank = []
single-bank = []

## internal use only
_split-pins-enabled = []

Expand Down
63 changes: 47 additions & 16 deletions embassy-stm32/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,44 @@ fn main() {
}
}

// ========
// Select the memory variant to use
let memory = {
let single_bank_selected = env::var("CARGO_FEATURE_SINGLE_BANK").is_ok();
let dual_bank_selected = env::var("CARGO_FEATURE_DUAL_BANK").is_ok();

let single_bank_memory = METADATA.memory.iter().find(|mem| {
mem.iter().any(|region| region.name.contains("BANK_1"))
&& !mem.iter().any(|region| region.name.contains("BANK_2"))
});

let dual_bank_memory = METADATA.memory.iter().find(|mem| {
mem.iter().any(|region| region.name.contains("BANK_1"))
&& mem.iter().any(|region| region.name.contains("BANK_2"))
});

cfgs.set(
"bank_setup_configurable",
single_bank_memory.is_some() && dual_bank_memory.is_some(),
);

match (single_bank_selected, dual_bank_selected) {
(true, true) => panic!("Both 'single-bank' and 'dual-bank' features enabled"),
(true, false) => {
single_bank_memory.expect("The 'single-bank' feature is not supported on this dual bank chip")
}
(false, true) => {
dual_bank_memory.expect("The 'dual-bank' feature is not supported on this single bank chip")
}
(false, false) => {
if METADATA.memory.len() != 1 {
panic!("Chip supports single and dual bank configuration. No Cargo feature to select one is enabled. Use the 'single-bank' or 'dual-bank' feature to make your selection")
}
METADATA.memory[0]
}
}
};

// ========
// Generate singletons

Expand Down Expand Up @@ -290,8 +328,7 @@ fn main() {
// ========
// Generate FLASH regions
let mut flash_regions = TokenStream::new();
let flash_memory_regions: Vec<_> = METADATA
.memory
let flash_memory_regions: Vec<_> = memory
.iter()
.filter(|x| x.kind == MemoryRegionKind::Flash && x.settings.is_some())
.collect();
Expand Down Expand Up @@ -1621,8 +1658,7 @@ fn main() {
let mut pins_table: Vec<Vec<String>> = Vec::new();
let mut adc_table: Vec<Vec<String>> = Vec::new();

for m in METADATA
.memory
for m in memory
.iter()
.filter(|m| m.kind == MemoryRegionKind::Flash && m.settings.is_some())
{
Expand Down Expand Up @@ -1860,8 +1896,7 @@ fn main() {
// ========
// Generate flash constants

let flash_regions: Vec<&MemoryRegion> = METADATA
.memory
let flash_regions: Vec<&MemoryRegion> = memory
.iter()
.filter(|x| x.kind == MemoryRegionKind::Flash && x.name.starts_with("BANK_"))
.collect();
Expand Down Expand Up @@ -1986,7 +2021,7 @@ fn main() {
println!("cargo:rerun-if-changed=build.rs");

if cfg!(feature = "memory-x") {
gen_memory_x(out_dir);
gen_memory_x(memory, out_dir);
println!("cargo:rustc-link-search={}", out_dir.display());
}
}
Expand Down Expand Up @@ -2075,11 +2110,11 @@ fn rustfmt(path: impl AsRef<Path>) {
}
}

fn gen_memory_x(out_dir: &Path) {
fn gen_memory_x(memory: &[MemoryRegion], out_dir: &Path) {
let mut memory_x = String::new();

let flash = get_memory_range(MemoryRegionKind::Flash);
let ram = get_memory_range(MemoryRegionKind::Ram);
let flash = get_memory_range(memory, MemoryRegionKind::Flash);
let ram = get_memory_range(memory, MemoryRegionKind::Ram);

write!(memory_x, "MEMORY\n{{\n").unwrap();
writeln!(
Expand All @@ -2103,12 +2138,8 @@ fn gen_memory_x(out_dir: &Path) {
std::fs::write(out_dir.join("memory.x"), memory_x.as_bytes()).unwrap();
}

fn get_memory_range(kind: MemoryRegionKind) -> (u32, u32, String) {
let mut mems: Vec<_> = METADATA
.memory
.iter()
.filter(|m| m.kind == kind && m.size != 0)
.collect();
fn get_memory_range(memory: &[MemoryRegion], kind: MemoryRegionKind) -> (u32, u32, String) {
let mut mems: Vec<_> = memory.iter().filter(|m| m.kind == kind && m.size != 0).collect();
mems.sort_by_key(|m| m.address);

let mut start = u32::MAX;
Expand Down
7 changes: 3 additions & 4 deletions embassy-stm32/src/flash/asynch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::mutex::Mutex;

use super::{
blocking_read, ensure_sector_aligned, family, get_sector, Async, Error, Flash, FlashLayout, FLASH_BASE, FLASH_SIZE,
WRITE_SIZE,
blocking_read, ensure_sector_aligned, family, get_flash_regions, get_sector, Async, Error, Flash, FlashLayout,
FLASH_BASE, FLASH_SIZE, WRITE_SIZE,
};
use crate::interrupt::InterruptExt;
use crate::peripherals::FLASH;
Expand All @@ -34,7 +34,6 @@ impl<'d> Flash<'d, Async> {
///
/// See module-level documentation for details on how memory regions work.
pub fn into_regions(self) -> FlashLayout<'d, Async> {
assert!(family::is_default_layout());
FlashLayout::new(self.inner)
}

Expand Down Expand Up @@ -123,7 +122,7 @@ pub(super) async unsafe fn write_chunked(base: u32, size: u32, offset: u32, byte
pub(super) async unsafe fn erase_sectored(base: u32, from: u32, to: u32) -> Result<(), Error> {
let start_address = base + from;
let end_address = base + to;
let regions = family::get_flash_regions();
let regions = get_flash_regions();

ensure_sector_aligned(start_address, end_address, regions)?;

Expand Down
11 changes: 7 additions & 4 deletions embassy-stm32/src/flash/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use core::sync::atomic::{fence, Ordering};
use embassy_hal_internal::drop::OnDrop;

use super::{
family, Async, Blocking, Error, FlashBank, FlashLayout, FlashRegion, FlashSector, FLASH_SIZE, MAX_ERASE_SIZE,
READ_SIZE, WRITE_SIZE,
family, get_flash_regions, Async, Blocking, Error, FlashBank, FlashLayout, FlashRegion, FlashSector, FLASH_SIZE,
MAX_ERASE_SIZE, READ_SIZE, WRITE_SIZE,
};
use crate::Peri;
use crate::_generated::FLASH_BASE;
Expand All @@ -20,6 +20,10 @@ pub struct Flash<'d, MODE = Async> {
impl<'d> Flash<'d, Blocking> {
/// Create a new flash driver, usable in blocking mode.
pub fn new_blocking(p: Peri<'d, FLASH>) -> Self {
#[cfg(bank_setup_configurable)]
// Check if the configuration matches the embassy setup
super::check_bank_setup();

Self {
inner: p,
_mode: PhantomData,
Expand All @@ -32,7 +36,6 @@ impl<'d, MODE> Flash<'d, MODE> {
///
/// See module-level documentation for details on how memory regions work.
pub fn into_blocking_regions(self) -> FlashLayout<'d, Blocking> {
assert!(family::is_default_layout());
FlashLayout::new(self.inner)
}

Expand Down Expand Up @@ -137,7 +140,7 @@ pub(super) unsafe fn blocking_erase(
) -> Result<(), Error> {
let start_address = base + from;
let end_address = base + to;
let regions = family::get_flash_regions();
let regions = get_flash_regions();

ensure_sector_aligned(start_address, end_address, regions)?;

Expand Down
10 changes: 1 addition & 9 deletions embassy-stm32/src/flash/f0.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
use core::ptr::write_volatile;
use core::sync::atomic::{fence, Ordering};

use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
use super::{FlashSector, WRITE_SIZE};
use crate::flash::Error;
use crate::pac;

pub(crate) const fn is_default_layout() -> bool {
true
}

pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
&FLASH_REGIONS
}

pub(crate) unsafe fn lock() {
pac::FLASH.cr().modify(|w| w.set_lock(true));
}
Expand Down
10 changes: 1 addition & 9 deletions embassy-stm32/src/flash/f1f3.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
use core::ptr::write_volatile;
use core::sync::atomic::{fence, Ordering};

use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
use super::{FlashSector, WRITE_SIZE};
use crate::flash::Error;
use crate::pac;

pub(crate) const fn is_default_layout() -> bool {
true
}

pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
&FLASH_REGIONS
}

pub(crate) unsafe fn lock() {
pac::FLASH.cr().modify(|w| w.set_lock(true));
}
Expand Down
10 changes: 1 addition & 9 deletions embassy-stm32/src/flash/f2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::sync::atomic::{fence, AtomicBool, Ordering};

use pac::flash::regs::Sr;

use super::{FlashBank, FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
use super::{get_flash_regions, FlashBank, FlashSector, WRITE_SIZE};
use crate::flash::Error;
use crate::pac;

Expand All @@ -15,14 +15,6 @@ impl FlashSector {
}
}

pub(crate) const fn is_default_layout() -> bool {
true
}

pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
&FLASH_REGIONS
}

pub(crate) unsafe fn lock() {
pac::FLASH.cr().modify(|w| w.set_lock(true));
}
Expand Down
Loading