diff --git a/embassy-stm32/src/flash/f3.rs b/embassy-stm32/src/flash/f3.rs
index 99ac1a153..3da3962e8 100644
--- a/embassy-stm32/src/flash/f3.rs
+++ b/embassy-stm32/src/flash/f3.rs
@@ -3,11 +3,11 @@ use core::ptr::write_volatile;
 
 use atomic_polyfill::{fence, Ordering};
 
-use super::{FlashRegion, BANK1, WRITE_SIZE};
+use super::{FlashRegion, FlashSector, BANK1, WRITE_SIZE};
 use crate::flash::Error;
 use crate::pac;
 
-const ERASE_SIZE: usize = BANK1::ERASE_SIZE;
+const ERASE_SIZE: usize = BANK1::SETTINGS.erase_size;
 
 pub(crate) unsafe fn lock() {
     pac::FLASH.cr().modify(|w| w.set_lock(true));
@@ -41,10 +41,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE])
     blocking_wait_ready()
 }
 
-pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool {
-    start_address % ERASE_SIZE as u32 == 0 && end_address % ERASE_SIZE as u32 == 0
-}
-
 pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> {
     for page in (start_address..end_address).step_by(ERASE_SIZE) {
         pac::FLASH.cr().modify(|w| {
@@ -107,3 +103,13 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> {
         }
     }
 }
+
+pub(crate) fn get_sector(address: u32) -> FlashSector {
+    let sector_size = BANK1::SETTINGS.erase_size as u32;
+    let index = address / sector_size;
+    FlashSector {
+        index: index as u8,
+        start: BANK1::SETTINGS.base as u32 + index * sector_size,
+        size: sector_size,
+    }
+}
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index 0fdfecb96..306359be1 100644
--- a/embassy-stm32/src/flash/f4.rs
+++ b/embassy-stm32/src/flash/f4.rs
@@ -63,24 +63,10 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE])
     blocking_wait_ready()
 }
 
-pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool {
-    let dual_bank = is_dual_bank();
-    let mut address = start_address;
-    while address < end_address {
-        let sector = get_sector(address, dual_bank, FLASH_SIZE as u32);
-        if sector.start != address {
-            return false;
-        }
-        address += sector.size;
-    }
-    address == end_address
-}
-
 pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> {
-    let dual_bank = is_dual_bank();
     let mut address = start_address;
     while address < end_address {
-        let sector = get_sector(address, dual_bank, FLASH_SIZE as u32);
+        let sector = get_sector(address);
         erase_sector(sector.index)?;
         address += sector.size;
     }
@@ -145,7 +131,11 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> {
     }
 }
 
-fn get_sector(address: u32, dual_bank: bool, flash_size: u32) -> FlashSector {
+pub(crate) fn get_sector(address: u32) -> FlashSector {
+    get_sector_inner(address, is_dual_bank(), FLASH_SIZE)
+}
+
+fn get_sector_inner(address: u32, dual_bank: bool, flash_size: u32) -> FlashSector {
     let offset = address - FLASH_BASE as u32;
     if !dual_bank {
         get_single_bank_sector(offset)
@@ -187,7 +177,10 @@ fn get_single_bank_sector(offset: u32) -> FlashSector {
             let large_sector_index = i - 1;
             FlashSector {
                 index: (5 + large_sector_index) as u8,
-                start: FLASH_BASE as u32 + 4 * SMALL_SECTOR_SIZE + MEDIUM_SECTOR_SIZE + large_sector_index * LARGE_SECTOR_SIZE,
+                start: FLASH_BASE as u32
+                    + 4 * SMALL_SECTOR_SIZE
+                    + MEDIUM_SECTOR_SIZE
+                    + large_sector_index * LARGE_SECTOR_SIZE,
                 size: LARGE_SECTOR_SIZE,
             }
         }
@@ -201,7 +194,10 @@ mod tests {
     #[test]
     fn can_get_sector_single_bank() {
         let assert_sector = |index: u8, start: u32, size: u32, addr: u32| {
-            assert_eq!(FlashSector { index, start, size }, get_sector(addr, false, 1024 * 1024))
+            assert_eq!(
+                FlashSector { index, start, size },
+                get_sector_inner(addr, false, 1024 * 1024)
+            )
         };
 
         assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000);
@@ -221,7 +217,10 @@ mod tests {
     #[test]
     fn can_get_sector_dual_bank() {
         let assert_sector = |index: u8, start: u32, size: u32, addr: u32| {
-            assert_eq!(FlashSector { index, start, size }, get_sector(addr, true, 1024 * 1024))
+            assert_eq!(
+                FlashSector { index, start, size },
+                get_sector_inner(addr, true, 1024 * 1024)
+            )
         };
 
         assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000);
diff --git a/embassy-stm32/src/flash/f7.rs b/embassy-stm32/src/flash/f7.rs
index 0d3b738c6..588fc7a59 100644
--- a/embassy-stm32/src/flash/f7.rs
+++ b/embassy-stm32/src/flash/f7.rs
@@ -45,18 +45,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE])
     blocking_wait_ready()
 }
 
-pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool {
-    let mut address = start_address;
-    while address < end_address {
-        let sector = get_sector(address);
-        if sector.start != address {
-            return false;
-        }
-        address += sector.size;
-    }
-    address == end_address
-}
-
 pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> {
     let mut address = start_address;
     while address < end_address {
@@ -132,7 +120,7 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> {
     }
 }
 
-fn get_sector(address: u32) -> FlashSector {
+pub(crate) fn get_sector(address: u32) -> FlashSector {
     // First 4 sectors are 32KB, then one 128KB, and rest are 256KB
     let offset = address - FLASH_BASE as u32;
     match offset / LARGE_SECTOR_SIZE {
@@ -156,7 +144,10 @@ fn get_sector(address: u32) -> FlashSector {
             let large_sector_index = i - 1;
             FlashSector {
                 index: (5 + large_sector_index) as u8,
-                start: FLASH_BASE as u32 + 4 * SMALL_SECTOR_SIZE + MEDIUM_SECTOR_SIZE + large_sector_index * LARGE_SECTOR_SIZE,
+                start: FLASH_BASE as u32
+                    + 4 * SMALL_SECTOR_SIZE
+                    + MEDIUM_SECTOR_SIZE
+                    + large_sector_index * LARGE_SECTOR_SIZE,
                 size: LARGE_SECTOR_SIZE,
             }
         }
diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs
index 21a9e45df..732af8539 100644
--- a/embassy-stm32/src/flash/h7.rs
+++ b/embassy-stm32/src/flash/h7.rs
@@ -3,11 +3,11 @@ use core::ptr::write_volatile;
 
 use atomic_polyfill::{fence, Ordering};
 
-use super::{FlashRegion, FLASH_SIZE, WRITE_SIZE};
+use super::{FlashRegion, FlashSector, BANK1, FLASH_SIZE, WRITE_SIZE};
 use crate::flash::Error;
 use crate::pac;
 
-const ERASE_SIZE: usize = super::BANK1::ERASE_SIZE;
+const ERASE_SIZE: usize = BANK1::SETTINGS.erase_size;
 const SECOND_BANK_OFFSET: usize = 0x0010_0000;
 
 const fn is_dual_bank() -> bool {
@@ -78,10 +78,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE])
     res.unwrap()
 }
 
-pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool {
-    start_address % ERASE_SIZE as u32 == 0 && end_address % ERASE_SIZE as u32 == 0
-}
-
 pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> {
     let start_sector = (start_address - super::FLASH_BASE as u32) / ERASE_SIZE as u32;
     let end_sector = (end_address - super::FLASH_BASE as u32) / ERASE_SIZE as u32;
@@ -194,3 +190,13 @@ unsafe fn blocking_wait_ready(bank: pac::flash::Bank) -> Result<(), Error> {
         }
     }
 }
+
+pub(crate) fn get_sector(address: u32) -> FlashSector {
+    let sector_size = BANK1::SETTINGS.erase_size as u32;
+    let index = address / sector_size;
+    FlashSector {
+        index: index as u8,
+        start: BANK1::SETTINGS.base as u32 + index * sector_size,
+        size: sector_size,
+    }
+}
diff --git a/embassy-stm32/src/flash/l.rs b/embassy-stm32/src/flash/l.rs
index 57989625c..56a21885e 100644
--- a/embassy-stm32/src/flash/l.rs
+++ b/embassy-stm32/src/flash/l.rs
@@ -2,11 +2,11 @@ use core::ptr::write_volatile;
 
 use atomic_polyfill::{fence, Ordering};
 
-use super::{FlashRegion, WRITE_SIZE};
+use super::{FlashRegion, FlashSector, BANK1, WRITE_SIZE};
 use crate::flash::Error;
 use crate::pac;
 
-const ERASE_SIZE: usize = super::BANK1::ERASE_SIZE;
+const ERASE_SIZE: usize = BANK1::SETTINGS.erase_size;
 
 pub(crate) unsafe fn lock() {
     #[cfg(any(flash_wl, flash_wb, flash_l4))]
@@ -62,10 +62,6 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE])
     blocking_wait_ready()
 }
 
-pub(crate) fn is_eraseable_range(start_address: u32, end_address: u32) -> bool {
-    start_address % ERASE_SIZE as u32 == 0 && end_address % ERASE_SIZE as u32 == 0
-}
-
 pub(crate) unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> {
     for page in (start_address..end_address).step_by(ERASE_SIZE) {
         #[cfg(any(flash_l0, flash_l1))]
@@ -191,3 +187,13 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> {
         }
     }
 }
+
+pub(crate) fn get_sector(address: u32) -> FlashSector {
+    let sector_size = BANK1::SETTINGS.erase_size as u32;
+    let index = address / sector_size;
+    FlashSector {
+        index: index as u8,
+        start: BANK1::SETTINGS.base as u32 + index * sector_size,
+        size: sector_size,
+    }
+}
diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs
index 1d1f034aa..29cf3cc51 100644
--- a/embassy-stm32/src/flash/mod.rs
+++ b/embassy-stm32/src/flash/mod.rs
@@ -104,7 +104,7 @@ impl<'d> Flash<'d> {
 
         let start_address = FLASH_BASE as u32 + from;
         let end_address = FLASH_BASE as u32 + to;
-        if !family::is_eraseable_range(start_address, end_address) {
+        if !is_eraseable_range(start_address, end_address) {
             return Err(Error::Unaligned);
         }
         trace!("Erasing from 0x{:x} to 0x{:x}", start_address, end_address);
@@ -193,6 +193,18 @@ pub trait FlashRegion {
     }
 }
 
+fn is_eraseable_range(start_address: u32, end_address: u32) -> bool {
+    let mut address = start_address;
+    while address < end_address {
+        let sector = family::get_sector(address);
+        if sector.start != address {
+            return false;
+        }
+        address += sector.size;
+    }
+    address == end_address
+}
+
 fn take_lock_spin() -> MutexGuard<'static, CriticalSectionRawMutex, ()> {
     loop {
         if let Ok(guard) = REGION_LOCK.try_lock() {
diff --git a/embassy-stm32/src/flash/other.rs b/embassy-stm32/src/flash/other.rs
index c9836d095..4ffb4cc35 100644
--- a/embassy-stm32/src/flash/other.rs
+++ b/embassy-stm32/src/flash/other.rs
@@ -1,7 +1,11 @@
 pub trait FlashRegion {
-    const BASE: usize;
-    const SIZE: usize;
-    const ERASE_SIZE: usize;
-    const WRITE_SIZE: usize;
-    const ERASE_VALUE: u8;
+    const SETTINGS: FlashRegionSettings;
+}
+
+pub struct FlashRegionSettings {
+    pub base: usize,
+    pub size: usize,
+    pub erase_size: usize,
+    pub write_size: usize,
+    pub erase_value: u8,
 }