diff --git a/embassy-hal-common/src/lib.rs b/embassy-hal-common/src/lib.rs index 1b253719..b2a35cd3 100644 --- a/embassy-hal-common/src/lib.rs +++ b/embassy-hal-common/src/lib.rs @@ -10,5 +10,4 @@ mod macros; mod peripheral; pub mod ratio; pub mod ring_buffer; -pub mod stm32; pub use peripheral::{Peripheral, PeripheralRef}; diff --git a/embassy-hal-common/src/stm32/flash/f4.rs b/embassy-hal-common/src/stm32/flash/f4.rs deleted file mode 100644 index a8069ddd..00000000 --- a/embassy-hal-common/src/stm32/flash/f4.rs +++ /dev/null @@ -1,119 +0,0 @@ -const FLASH_BASE: u32 = 0x0800_0000; -pub(crate) const SMALL_SECTOR_SIZE: u32 = 16 * 1024; -pub(crate) const MEDIUM_SECTOR_SIZE: u32 = 64 * 1024; -pub(crate) const LARGE_SECTOR_SIZE: u32 = 128 * 1024; -pub const SECOND_BANK_SECTOR_OFFSET: u8 = 12; - -#[derive(Debug, PartialEq)] -pub struct FlashSector { - pub index: u8, - pub start: u32, - pub size: u32, -} - -pub fn get_sector(address: u32, dual_bank: bool, flash_size: u32) -> FlashSector { - let offset = address - FLASH_BASE; - if !dual_bank { - get_single_bank_sector(offset) - } else { - let bank_size = flash_size / 2; - if offset < bank_size { - get_single_bank_sector(offset) - } else { - let sector = get_single_bank_sector(offset - bank_size); - FlashSector { - index: SECOND_BANK_SECTOR_OFFSET + sector.index, - start: sector.start + bank_size, - size: sector.size, - } - } - } -} - -fn get_single_bank_sector(offset: u32) -> FlashSector { - // First 4 sectors are 16KB, then one 64KB, and rest are 128KB - match offset / LARGE_SECTOR_SIZE { - 0 => { - if offset < 4 * SMALL_SECTOR_SIZE { - let small_sector_index = offset / SMALL_SECTOR_SIZE; - FlashSector { - index: small_sector_index as u8, - start: FLASH_BASE + small_sector_index * SMALL_SECTOR_SIZE, - size: SMALL_SECTOR_SIZE, - } - } else { - FlashSector { - index: 4, - start: FLASH_BASE + 4 * SMALL_SECTOR_SIZE, - size: MEDIUM_SECTOR_SIZE, - } - } - } - i => { - let large_sector_index = i - 1; - FlashSector { - index: (5 + large_sector_index) as u8, - start: FLASH_BASE + 4 * SMALL_SECTOR_SIZE + MEDIUM_SECTOR_SIZE + large_sector_index * LARGE_SECTOR_SIZE, - size: LARGE_SECTOR_SIZE, - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[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_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000); - assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_3FFF); - assert_sector(3, 0x0800_C000, SMALL_SECTOR_SIZE, 0x0800_C000); - assert_sector(3, 0x0800_C000, SMALL_SECTOR_SIZE, 0x0800_FFFF); - - assert_sector(4, 0x0801_0000, MEDIUM_SECTOR_SIZE, 0x0801_0000); - assert_sector(4, 0x0801_0000, MEDIUM_SECTOR_SIZE, 0x0801_FFFF); - - assert_sector(5, 0x0802_0000, LARGE_SECTOR_SIZE, 0x0802_0000); - assert_sector(5, 0x0802_0000, LARGE_SECTOR_SIZE, 0x0803_FFFF); - assert_sector(11, 0x080E_0000, LARGE_SECTOR_SIZE, 0x080E_0000); - assert_sector(11, 0x080E_0000, LARGE_SECTOR_SIZE, 0x080F_FFFF); - } - - #[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_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000); - assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_3FFF); - assert_sector(3, 0x0800_C000, SMALL_SECTOR_SIZE, 0x0800_C000); - assert_sector(3, 0x0800_C000, SMALL_SECTOR_SIZE, 0x0800_FFFF); - - assert_sector(4, 0x0801_0000, MEDIUM_SECTOR_SIZE, 0x0801_0000); - assert_sector(4, 0x0801_0000, MEDIUM_SECTOR_SIZE, 0x0801_FFFF); - - assert_sector(5, 0x0802_0000, LARGE_SECTOR_SIZE, 0x0802_0000); - assert_sector(5, 0x0802_0000, LARGE_SECTOR_SIZE, 0x0803_FFFF); - assert_sector(7, 0x0806_0000, LARGE_SECTOR_SIZE, 0x0806_0000); - assert_sector(7, 0x0806_0000, LARGE_SECTOR_SIZE, 0x0807_FFFF); - - assert_sector(12, 0x0808_0000, SMALL_SECTOR_SIZE, 0x0808_0000); - assert_sector(12, 0x0808_0000, SMALL_SECTOR_SIZE, 0x0808_3FFF); - assert_sector(15, 0x0808_C000, SMALL_SECTOR_SIZE, 0x0808_C000); - assert_sector(15, 0x0808_C000, SMALL_SECTOR_SIZE, 0x0808_FFFF); - - assert_sector(16, 0x0809_0000, MEDIUM_SECTOR_SIZE, 0x0809_0000); - assert_sector(16, 0x0809_0000, MEDIUM_SECTOR_SIZE, 0x0809_FFFF); - - assert_sector(17, 0x080A_0000, LARGE_SECTOR_SIZE, 0x080A_0000); - assert_sector(17, 0x080A_0000, LARGE_SECTOR_SIZE, 0x080B_FFFF); - assert_sector(19, 0x080E_0000, LARGE_SECTOR_SIZE, 0x080E_0000); - assert_sector(19, 0x080E_0000, LARGE_SECTOR_SIZE, 0x080F_FFFF); - } -} diff --git a/embassy-hal-common/src/stm32/flash/f7.rs b/embassy-hal-common/src/stm32/flash/f7.rs deleted file mode 100644 index 2f586ade..00000000 --- a/embassy-hal-common/src/stm32/flash/f7.rs +++ /dev/null @@ -1,67 +0,0 @@ -const FLASH_BASE: u32 = 0x0800_0000; -pub(crate) const SMALL_SECTOR_SIZE: u32 = 32 * 1024; -pub(crate) const MEDIUM_SECTOR_SIZE: u32 = 128 * 1024; -pub(crate) const LARGE_SECTOR_SIZE: u32 = 256 * 1024; - -#[derive(Debug, PartialEq)] -pub struct FlashSector { - pub index: u8, - pub start: u32, - pub size: u32, -} - -pub fn get_sector(address: u32) -> FlashSector { - // First 4 sectors are 32KB, then one 128KB, and rest are 256KB - let offset = address - FLASH_BASE; - match offset / LARGE_SECTOR_SIZE { - 0 => { - if offset < 4 * SMALL_SECTOR_SIZE { - let small_sector_index = offset / SMALL_SECTOR_SIZE; - FlashSector { - index: small_sector_index as u8, - start: FLASH_BASE + small_sector_index * SMALL_SECTOR_SIZE, - size: SMALL_SECTOR_SIZE, - } - } else { - FlashSector { - index: 4, - start: FLASH_BASE + 4 * SMALL_SECTOR_SIZE, - size: MEDIUM_SECTOR_SIZE, - } - } - } - i => { - let large_sector_index = i - 1; - FlashSector { - index: (5 + large_sector_index) as u8, - start: FLASH_BASE + 4 * SMALL_SECTOR_SIZE + MEDIUM_SECTOR_SIZE + large_sector_index * LARGE_SECTOR_SIZE, - size: LARGE_SECTOR_SIZE, - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn can_get_sector() { - let assert_sector = |index: u8, start: u32, size: u32, addr: u32| { - assert_eq!(FlashSector { index, start, size }, get_sector(addr)) - }; - - assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000); - assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_7FFF); - assert_sector(3, 0x0801_8000, SMALL_SECTOR_SIZE, 0x0801_8000); - assert_sector(3, 0x0801_8000, SMALL_SECTOR_SIZE, 0x0801_FFFF); - - assert_sector(4, 0x0802_0000, MEDIUM_SECTOR_SIZE, 0x0802_0000); - assert_sector(4, 0x0802_0000, MEDIUM_SECTOR_SIZE, 0x0803_FFFF); - - assert_sector(5, 0x0804_0000, LARGE_SECTOR_SIZE, 0x0804_0000); - assert_sector(5, 0x0804_0000, LARGE_SECTOR_SIZE, 0x0807_FFFF); - assert_sector(7, 0x080C_0000, LARGE_SECTOR_SIZE, 0x080C_0000); - assert_sector(7, 0x080C_0000, LARGE_SECTOR_SIZE, 0x080F_FFFF); - } -} diff --git a/embassy-hal-common/src/stm32/flash/mod.rs b/embassy-hal-common/src/stm32/flash/mod.rs deleted file mode 100644 index 1452b491..00000000 --- a/embassy-hal-common/src/stm32/flash/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod f4; -pub mod f7; diff --git a/embassy-hal-common/src/stm32/mod.rs b/embassy-hal-common/src/stm32/mod.rs deleted file mode 100644 index 2e50f82b..00000000 --- a/embassy-hal-common/src/stm32/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod flash; diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index b66d724d..1dd6202d 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -60,7 +60,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "46d1b1c2ff13e31e282ec1e352421721694f126a", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { version = "1", features = ["rt"] } +stm32-metapac = "1" vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -69,12 +69,16 @@ seq-macro = "0.3.0" cfg-if = "1.0.0" embedded-io = { version = "0.4.0", features = ["async"], optional = true } +[dev-dependencies] +critical-section = { version = "1.1", features = ["std"] } + [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" stm32-metapac = { version = "1", default-features = false, features = ["metadata"]} [features] +default = ["stm32-metapac/rt"] defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-executor/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"] memory-x = ["stm32-metapac/memory-x"] subghz = [] diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 7428fd57..0fdfecb9 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -2,12 +2,15 @@ use core::convert::TryInto; use core::ptr::write_volatile; use core::sync::atomic::{fence, Ordering}; -use embassy_hal_common::stm32::flash::f4::{get_sector, SECOND_BANK_SECTOR_OFFSET}; - -use super::{FLASH_SIZE, WRITE_SIZE}; +use super::{FlashSector, FLASH_BASE, FLASH_SIZE, WRITE_SIZE}; use crate::flash::Error; use crate::pac; +const SMALL_SECTOR_SIZE: u32 = 16 * 1024; +const MEDIUM_SECTOR_SIZE: u32 = 64 * 1024; +const LARGE_SECTOR_SIZE: u32 = 128 * 1024; +const SECOND_BANK_SECTOR_OFFSET: u8 = 12; + fn is_dual_bank() -> bool { match FLASH_SIZE / 1024 { // 1 MB devices depend on configuration @@ -141,3 +144,110 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> { } } } + +fn get_sector(address: u32, dual_bank: bool, flash_size: u32) -> FlashSector { + let offset = address - FLASH_BASE as u32; + if !dual_bank { + get_single_bank_sector(offset) + } else { + let bank_size = flash_size / 2; + if offset < bank_size { + get_single_bank_sector(offset) + } else { + let sector = get_single_bank_sector(offset - bank_size); + FlashSector { + index: SECOND_BANK_SECTOR_OFFSET + sector.index, + start: sector.start + bank_size, + size: sector.size, + } + } + } +} + +fn get_single_bank_sector(offset: u32) -> FlashSector { + // First 4 sectors are 16KB, then one 64KB, and rest are 128KB + match offset / LARGE_SECTOR_SIZE { + 0 => { + if offset < 4 * SMALL_SECTOR_SIZE { + let small_sector_index = offset / SMALL_SECTOR_SIZE; + FlashSector { + index: small_sector_index as u8, + start: FLASH_BASE as u32 + small_sector_index * SMALL_SECTOR_SIZE, + size: SMALL_SECTOR_SIZE, + } + } else { + FlashSector { + index: 4, + start: FLASH_BASE as u32 + 4 * SMALL_SECTOR_SIZE, + size: MEDIUM_SECTOR_SIZE, + } + } + } + i => { + 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, + size: LARGE_SECTOR_SIZE, + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[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_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000); + assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_3FFF); + assert_sector(3, 0x0800_C000, SMALL_SECTOR_SIZE, 0x0800_C000); + assert_sector(3, 0x0800_C000, SMALL_SECTOR_SIZE, 0x0800_FFFF); + + assert_sector(4, 0x0801_0000, MEDIUM_SECTOR_SIZE, 0x0801_0000); + assert_sector(4, 0x0801_0000, MEDIUM_SECTOR_SIZE, 0x0801_FFFF); + + assert_sector(5, 0x0802_0000, LARGE_SECTOR_SIZE, 0x0802_0000); + assert_sector(5, 0x0802_0000, LARGE_SECTOR_SIZE, 0x0803_FFFF); + assert_sector(11, 0x080E_0000, LARGE_SECTOR_SIZE, 0x080E_0000); + assert_sector(11, 0x080E_0000, LARGE_SECTOR_SIZE, 0x080F_FFFF); + } + + #[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_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000); + assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_3FFF); + assert_sector(3, 0x0800_C000, SMALL_SECTOR_SIZE, 0x0800_C000); + assert_sector(3, 0x0800_C000, SMALL_SECTOR_SIZE, 0x0800_FFFF); + + assert_sector(4, 0x0801_0000, MEDIUM_SECTOR_SIZE, 0x0801_0000); + assert_sector(4, 0x0801_0000, MEDIUM_SECTOR_SIZE, 0x0801_FFFF); + + assert_sector(5, 0x0802_0000, LARGE_SECTOR_SIZE, 0x0802_0000); + assert_sector(5, 0x0802_0000, LARGE_SECTOR_SIZE, 0x0803_FFFF); + assert_sector(7, 0x0806_0000, LARGE_SECTOR_SIZE, 0x0806_0000); + assert_sector(7, 0x0806_0000, LARGE_SECTOR_SIZE, 0x0807_FFFF); + + assert_sector(12, 0x0808_0000, SMALL_SECTOR_SIZE, 0x0808_0000); + assert_sector(12, 0x0808_0000, SMALL_SECTOR_SIZE, 0x0808_3FFF); + assert_sector(15, 0x0808_C000, SMALL_SECTOR_SIZE, 0x0808_C000); + assert_sector(15, 0x0808_C000, SMALL_SECTOR_SIZE, 0x0808_FFFF); + + assert_sector(16, 0x0809_0000, MEDIUM_SECTOR_SIZE, 0x0809_0000); + assert_sector(16, 0x0809_0000, MEDIUM_SECTOR_SIZE, 0x0809_FFFF); + + assert_sector(17, 0x080A_0000, LARGE_SECTOR_SIZE, 0x080A_0000); + assert_sector(17, 0x080A_0000, LARGE_SECTOR_SIZE, 0x080B_FFFF); + assert_sector(19, 0x080E_0000, LARGE_SECTOR_SIZE, 0x080E_0000); + assert_sector(19, 0x080E_0000, LARGE_SECTOR_SIZE, 0x080F_FFFF); + } +} diff --git a/embassy-stm32/src/flash/f7.rs b/embassy-stm32/src/flash/f7.rs index 16b68458..0d3b738c 100644 --- a/embassy-stm32/src/flash/f7.rs +++ b/embassy-stm32/src/flash/f7.rs @@ -2,12 +2,14 @@ use core::convert::TryInto; use core::ptr::write_volatile; use core::sync::atomic::{fence, Ordering}; -use embassy_hal_common::stm32::flash::f7::get_sector; - -use super::WRITE_SIZE; +use super::{FlashSector, FLASH_BASE, WRITE_SIZE}; use crate::flash::Error; use crate::pac; +const SMALL_SECTOR_SIZE: u32 = 32 * 1024; +const MEDIUM_SECTOR_SIZE: u32 = 128 * 1024; +const LARGE_SECTOR_SIZE: u32 = 256 * 1024; + pub(crate) unsafe fn lock() { pac::FLASH.cr().modify(|w| w.set_lock(true)); } @@ -129,3 +131,59 @@ unsafe fn blocking_wait_ready() -> Result<(), Error> { } } } + +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 { + 0 => { + if offset < 4 * SMALL_SECTOR_SIZE { + let small_sector_index = offset / SMALL_SECTOR_SIZE; + FlashSector { + index: small_sector_index as u8, + start: FLASH_BASE as u32 + small_sector_index * SMALL_SECTOR_SIZE, + size: SMALL_SECTOR_SIZE, + } + } else { + FlashSector { + index: 4, + start: FLASH_BASE as u32 + 4 * SMALL_SECTOR_SIZE, + size: MEDIUM_SECTOR_SIZE, + } + } + } + i => { + 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, + size: LARGE_SECTOR_SIZE, + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_get_sector() { + let assert_sector = |index: u8, start: u32, size: u32, addr: u32| { + assert_eq!(FlashSector { index, start, size }, get_sector(addr)) + }; + + assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_0000); + assert_sector(0, 0x0800_0000, SMALL_SECTOR_SIZE, 0x0800_7FFF); + assert_sector(3, 0x0801_8000, SMALL_SECTOR_SIZE, 0x0801_8000); + assert_sector(3, 0x0801_8000, SMALL_SECTOR_SIZE, 0x0801_FFFF); + + assert_sector(4, 0x0802_0000, MEDIUM_SECTOR_SIZE, 0x0802_0000); + assert_sector(4, 0x0802_0000, MEDIUM_SECTOR_SIZE, 0x0803_FFFF); + + assert_sector(5, 0x0804_0000, LARGE_SECTOR_SIZE, 0x0804_0000); + assert_sector(5, 0x0804_0000, LARGE_SECTOR_SIZE, 0x0807_FFFF); + assert_sector(7, 0x080C_0000, LARGE_SECTOR_SIZE, 0x080C_0000); + assert_sector(7, 0x080C_0000, LARGE_SECTOR_SIZE, 0x080F_FFFF); + } +} diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs index 1294ace4..6906bd09 100644 --- a/embassy-stm32/src/flash/mod.rs +++ b/embassy-stm32/src/flash/mod.rs @@ -19,6 +19,13 @@ pub struct Flash<'d> { _inner: PeripheralRef<'d, FLASH>, } +#[derive(Debug, PartialEq)] +pub struct FlashSector { + pub index: u8, + pub start: u32, + pub size: u32, +} + static REGION_LOCK: Mutex = Mutex::new(()); impl<'d> Flash<'d> {