diff --git a/embassy-stm32/src/flash/asynch.rs b/embassy-stm32/src/flash/asynch.rs index 3564bbff..017fb17f 100644 --- a/embassy-stm32/src/flash/asynch.rs +++ b/embassy-stm32/src/flash/asynch.rs @@ -12,15 +12,18 @@ pub(super) static REGION_ACCESS: Mutex = Mutex::new impl<'d> Flash<'d> { pub fn into_regions(self) -> FlashLayout<'d, Async> { + assert!(!self.blocking_only); family::set_default_layout(); FlashLayout::new(self.inner) } pub async fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { + assert!(!self.blocking_only); unsafe { write_chunked(FLASH_BASE as u32, FLASH_SIZE as u32, offset, bytes).await } } pub async fn erase(&mut self, from: u32, to: u32) -> Result<(), Error> { + assert!(!self.blocking_only); unsafe { erase_sectored(FLASH_BASE as u32, from, to).await } } } diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs index 8b38745c..0a1ee516 100644 --- a/embassy-stm32/src/flash/common.rs +++ b/embassy-stm32/src/flash/common.rs @@ -1,5 +1,5 @@ use atomic_polyfill::{fence, Ordering}; -use embassy_cortex_m::interrupt::InterruptExt; +use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; use embassy_hal_common::drop::OnDrop; use embassy_hal_common::{into_ref, PeripheralRef}; use stm32_metapac::FLASH_BASE; @@ -9,21 +9,37 @@ use super::{ WRITE_SIZE, }; use crate::peripherals::FLASH; -use crate::Peripheral; +use crate::{interrupt, Peripheral}; pub struct Flash<'d> { pub(crate) inner: PeripheralRef<'d, FLASH>, + pub(crate) blocking_only: bool, } impl<'d> Flash<'d> { - pub fn new(p: impl Peripheral

+ 'd, irq: impl Peripheral

+ 'd) -> Self { - into_ref!(p, irq); + pub fn new( + p: impl Peripheral

+ 'd, + _irq: impl interrupt::Binding + 'd, + ) -> Self { + into_ref!(p); - irq.set_handler(family::on_interrupt); - irq.unpend(); - irq.enable(); + let flash_irq = unsafe { crate::interrupt::FLASH::steal() }; + flash_irq.unpend(); + flash_irq.enable(); - Self { inner: p } + Self { + inner: p, + blocking_only: false, + } + } + + pub fn new_blocking_only(p: impl Peripheral

+ 'd) -> Self { + into_ref!(p); + + Self { + inner: p, + blocking_only: true, + } } pub fn into_blocking_regions(self) -> FlashLayout<'d, Blocking> { @@ -52,6 +68,15 @@ impl<'d> Flash<'d> { } } +/// Interrupt handler +pub struct InterruptHandler; + +impl interrupt::Handler for InterruptHandler { + unsafe fn on_interrupt() { + family::on_interrupt(); + } +} + pub(super) fn read_blocking(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { if offset + bytes.len() as u32 > size { return Err(Error::Size); diff --git a/embassy-stm32/src/flash/f0.rs b/embassy-stm32/src/flash/f0.rs index ecf3a698..cd17486e 100644 --- a/embassy-stm32/src/flash/f0.rs +++ b/embassy-stm32/src/flash/f0.rs @@ -13,7 +13,7 @@ pub const fn get_flash_regions() -> &'static [&'static FlashRegion] { &FLASH_REGIONS } -pub(crate) unsafe fn on_interrupt(_: *mut ()) { +pub(crate) unsafe fn on_interrupt() { unimplemented!(); } diff --git a/embassy-stm32/src/flash/f3.rs b/embassy-stm32/src/flash/f3.rs index fd778f2b..4ce39128 100644 --- a/embassy-stm32/src/flash/f3.rs +++ b/embassy-stm32/src/flash/f3.rs @@ -13,7 +13,7 @@ pub const fn get_flash_regions() -> &'static [&'static FlashRegion] { &FLASH_REGIONS } -pub(crate) unsafe fn on_interrupt(_: *mut ()) { +pub(crate) unsafe fn on_interrupt() { unimplemented!(); } diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 50ab446b..2b047264 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -210,7 +210,7 @@ pub const fn get_flash_regions() -> &'static [&'static FlashRegion] { &FLASH_REGIONS } -pub(crate) unsafe fn on_interrupt(_: *mut ()) { +pub(crate) unsafe fn on_interrupt() { // Clear IRQ flags pac::FLASH.sr().write(|w| { w.set_operr(true); diff --git a/embassy-stm32/src/flash/f7.rs b/embassy-stm32/src/flash/f7.rs index a0593b14..ab518bf8 100644 --- a/embassy-stm32/src/flash/f7.rs +++ b/embassy-stm32/src/flash/f7.rs @@ -12,7 +12,7 @@ pub const fn get_flash_regions() -> &'static [&'static FlashRegion] { &FLASH_REGIONS } -pub(crate) unsafe fn on_interrupt(_: *mut ()) { +pub(crate) unsafe fn on_interrupt() { unimplemented!(); } diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs index 865f1328..d6818d59 100644 --- a/embassy-stm32/src/flash/h7.rs +++ b/embassy-stm32/src/flash/h7.rs @@ -17,7 +17,7 @@ pub fn get_flash_regions() -> &'static [&'static FlashRegion] { &FLASH_REGIONS } -pub(crate) unsafe fn on_interrupt(_: *mut ()) { +pub(crate) unsafe fn on_interrupt() { unimplemented!(); } diff --git a/embassy-stm32/src/flash/l.rs b/embassy-stm32/src/flash/l.rs index f8a0dac4..c2394e0c 100644 --- a/embassy-stm32/src/flash/l.rs +++ b/embassy-stm32/src/flash/l.rs @@ -12,7 +12,7 @@ pub const fn get_flash_regions() -> &'static [&'static FlashRegion] { &FLASH_REGIONS } -pub(crate) unsafe fn on_interrupt(_: *mut ()) { +pub(crate) unsafe fn on_interrupt() { unimplemented!(); } diff --git a/embassy-stm32/src/flash/other.rs b/embassy-stm32/src/flash/other.rs index e21b0b24..e569951f 100644 --- a/embassy-stm32/src/flash/other.rs +++ b/embassy-stm32/src/flash/other.rs @@ -8,7 +8,7 @@ pub const fn get_flash_regions() -> &'static [&'static FlashRegion] { &FLASH_REGIONS } -pub(crate) unsafe fn on_interrupt(_: *mut ()) { +pub(crate) unsafe fn on_interrupt() { unimplemented!(); } diff --git a/examples/boot/application/rp/src/bin/a.rs b/examples/boot/application/rp/src/bin/a.rs index e3ac634c..2b84ec61 100644 --- a/examples/boot/application/rp/src/bin/a.rs +++ b/examples/boot/application/rp/src/bin/a.rs @@ -26,7 +26,7 @@ async fn main(_s: Spawner) { let mut watchdog = Watchdog::new(p.WATCHDOG); watchdog.start(Duration::from_secs(8)); - let mut flash: Flash<_, FLASH_SIZE> = Flash::new(p.FLASH); + let mut flash: Flash<_, FLASH_SIZE> = Flash::new_blocking_only(p.FLASH); let mut updater = FirmwareUpdater::default(); diff --git a/examples/boot/application/stm32f3/src/bin/a.rs b/examples/boot/application/stm32f3/src/bin/a.rs index d92d59b2..a69b6327 100644 --- a/examples/boot/application/stm32f3/src/bin/a.rs +++ b/examples/boot/application/stm32f3/src/bin/a.rs @@ -17,7 +17,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let flash = Flash::new(p.FLASH); + let flash = Flash::new_blocking_only(p.FLASH); let mut flash = BlockingAsync::new(flash); let button = Input::new(p.PC13, Pull::Up); diff --git a/examples/boot/application/stm32f7/src/bin/a.rs b/examples/boot/application/stm32f7/src/bin/a.rs index 79ab80e0..1f55db93 100644 --- a/examples/boot/application/stm32f7/src/bin/a.rs +++ b/examples/boot/application/stm32f7/src/bin/a.rs @@ -16,7 +16,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let mut flash = Flash::new(p.FLASH); + let mut flash = Flash::new_blocking_only(p.FLASH); let button = Input::new(p.PC13, Pull::Down); let mut button = ExtiInput::new(button, p.EXTI13); diff --git a/examples/boot/application/stm32h7/src/bin/a.rs b/examples/boot/application/stm32h7/src/bin/a.rs index 8b452be3..b8617c3b 100644 --- a/examples/boot/application/stm32h7/src/bin/a.rs +++ b/examples/boot/application/stm32h7/src/bin/a.rs @@ -16,7 +16,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let mut flash = Flash::new(p.FLASH); + let mut flash = Flash::new_blocking_only(p.FLASH); let button = Input::new(p.PC13, Pull::Down); let mut button = ExtiInput::new(button, p.EXTI13); diff --git a/examples/boot/application/stm32l0/src/bin/a.rs b/examples/boot/application/stm32l0/src/bin/a.rs index 59ca3438..c6663563 100644 --- a/examples/boot/application/stm32l0/src/bin/a.rs +++ b/examples/boot/application/stm32l0/src/bin/a.rs @@ -18,7 +18,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let flash = Flash::new(p.FLASH); + let flash = Flash::new_blocking_only(p.FLASH); let mut flash = BlockingAsync::new(flash); let button = Input::new(p.PB2, Pull::Up); diff --git a/examples/boot/application/stm32l1/src/bin/a.rs b/examples/boot/application/stm32l1/src/bin/a.rs index 59ca3438..c6663563 100644 --- a/examples/boot/application/stm32l1/src/bin/a.rs +++ b/examples/boot/application/stm32l1/src/bin/a.rs @@ -18,7 +18,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let flash = Flash::new(p.FLASH); + let flash = Flash::new_blocking_only(p.FLASH); let mut flash = BlockingAsync::new(flash); let button = Input::new(p.PB2, Pull::Up); diff --git a/examples/boot/application/stm32l4/src/bin/a.rs b/examples/boot/application/stm32l4/src/bin/a.rs index 6cddc6cc..86936222 100644 --- a/examples/boot/application/stm32l4/src/bin/a.rs +++ b/examples/boot/application/stm32l4/src/bin/a.rs @@ -17,7 +17,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let flash = Flash::new(p.FLASH); + let flash = Flash::new_blocking_only(p.FLASH); let mut flash = BlockingAsync::new(flash); let button = Input::new(p.PC13, Pull::Up); diff --git a/examples/boot/application/stm32wl/src/bin/a.rs b/examples/boot/application/stm32wl/src/bin/a.rs index 1ff47edd..2982e8df 100644 --- a/examples/boot/application/stm32wl/src/bin/a.rs +++ b/examples/boot/application/stm32wl/src/bin/a.rs @@ -17,7 +17,7 @@ static APP_B: &[u8] = include_bytes!("../../b.bin"); #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); - let flash = Flash::new(p.FLASH); + let flash = Flash::new_blocking_only(p.FLASH); let mut flash = BlockingAsync::new(flash); let button = Input::new(p.PA0, Pull::Up); diff --git a/examples/boot/bootloader/stm32/src/main.rs b/examples/boot/bootloader/stm32/src/main.rs index 49c21920..5e8a4f2b 100644 --- a/examples/boot/bootloader/stm32/src/main.rs +++ b/examples/boot/bootloader/stm32/src/main.rs @@ -20,8 +20,7 @@ fn main() -> ! { */ let mut bl: BootLoader<2048> = BootLoader::default(); - let flash = Flash::new(p.FLASH); - let layout = flash.into_regions(); + let layout = Flash::new_blocking_only(p.FLASH).into_blocking_regions(); let mut flash = BootFlash::new(layout.bank1_region); let start = bl.prepare(&mut SingleFlashConfig::new(&mut flash)); core::mem::drop(flash); diff --git a/examples/stm32f3/src/bin/flash.rs b/examples/stm32f3/src/bin/flash.rs index befae0a1..9a31b548 100644 --- a/examples/stm32f3/src/bin/flash.rs +++ b/examples/stm32f3/src/bin/flash.rs @@ -4,7 +4,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_stm32::{flash::Flash, interrupt}; +use embassy_stm32::flash::Flash; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { const ADDR: u32 = 0x26000; - let mut f = Flash::new(p.FLASH, interrupt::take!(FLASH)).into_blocking_regions().bank1_region; + let mut f = Flash::new_blocking_only(p.FLASH).into_blocking_regions().bank1_region; info!("Reading..."); let mut buf = [0u8; 8]; diff --git a/examples/stm32f4/src/bin/flash.rs b/examples/stm32f4/src/bin/flash.rs index de4ecdb8..455af930 100644 --- a/examples/stm32f4/src/bin/flash.rs +++ b/examples/stm32f4/src/bin/flash.rs @@ -4,7 +4,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_stm32::{flash::Flash, interrupt}; +use embassy_stm32::flash::Flash; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { // Once can also call `into_regions()` to get access to NorFlash implementations // for each of the unique characteristics. - let mut f = Flash::new(p.FLASH, interrupt::take!(FLASH)); + let mut f = Flash::new_blocking_only(p.FLASH); // Sector 5 test_flash(&mut f, 128 * 1024, 128 * 1024); diff --git a/examples/stm32f4/src/bin/flash_async.rs b/examples/stm32f4/src/bin/flash_async.rs index c9d9df34..67533708 100644 --- a/examples/stm32f4/src/bin/flash_async.rs +++ b/examples/stm32f4/src/bin/flash_async.rs @@ -5,17 +5,21 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; use embassy_time::{Timer, Duration}; -use embassy_stm32::flash::Flash; +use embassy_stm32::flash::{Flash, InterruptHandler}; use embassy_stm32::gpio::{AnyPin, Level, Output, Pin, Speed}; -use embassy_stm32::{interrupt}; +use embassy_stm32::bind_interrupts; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + FLASH => InterruptHandler; +}); + #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello Flash!"); - let mut f = Flash::new(p.FLASH, interrupt::take!(FLASH)); + let mut f = Flash::new(p.FLASH, Irqs); // Led should blink uninterrupted during ~2sec erase operation spawner.spawn(blinky(p.PB7.degrade())).unwrap(); diff --git a/examples/stm32h7/src/bin/flash.rs b/examples/stm32h7/src/bin/flash.rs index fe6dad24..c0c332c3 100644 --- a/examples/stm32h7/src/bin/flash.rs +++ b/examples/stm32h7/src/bin/flash.rs @@ -4,7 +4,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_stm32::{flash::Flash, interrupt}; +use embassy_stm32::flash::Flash; use embassy_time::{Duration, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) { // wait a bit before accessing the flash Timer::after(Duration::from_millis(300)).await; - let mut f = Flash::new(p.FLASH, interrupt::take!(FLASH)).into_blocking_regions().bank2_region; + let mut f = Flash::new_blocking_only(p.FLASH).into_blocking_regions().bank2_region; info!("Reading..."); let mut buf = [0u8; 32]; diff --git a/examples/stm32l0/src/bin/flash.rs b/examples/stm32l0/src/bin/flash.rs index 4182c87b..57ccf7f5 100644 --- a/examples/stm32l0/src/bin/flash.rs +++ b/examples/stm32l0/src/bin/flash.rs @@ -4,7 +4,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_stm32::{flash::Flash, interrupt}; +use embassy_stm32::flash::Flash; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { const ADDR: u32 = 0x26000; - let mut f = Flash::new(p.FLASH, interrupt::take!(FLASH)).into_blocking_regions().bank1_region; + let mut f = Flash::new_blocking_only(p.FLASH).into_blocking_regions().bank1_region; info!("Reading..."); let mut buf = [0u8; 8]; diff --git a/examples/stm32l1/src/bin/flash.rs b/examples/stm32l1/src/bin/flash.rs index 53052e7c..71174bfb 100644 --- a/examples/stm32l1/src/bin/flash.rs +++ b/examples/stm32l1/src/bin/flash.rs @@ -4,7 +4,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_stm32::{flash::Flash, interrupt}; +use embassy_stm32::flash::Flash; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { const ADDR: u32 = 0x26000; - let mut f = Flash::new(p.FLASH, interrupt::take!(FLASH)).into_blocking_regions().bank1_region; + let mut f = Flash::new_blocking_only(p.FLASH).into_blocking_regions().bank1_region; info!("Reading..."); let mut buf = [0u8; 8]; diff --git a/examples/stm32wl/src/bin/flash.rs b/examples/stm32wl/src/bin/flash.rs index e03b69b8..51bd0db4 100644 --- a/examples/stm32wl/src/bin/flash.rs +++ b/examples/stm32wl/src/bin/flash.rs @@ -4,7 +4,7 @@ use defmt::{info, unwrap}; use embassy_executor::Spawner; -use embassy_stm32::{flash::Flash, interrupt}; +use embassy_stm32::flash::Flash; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { const ADDR: u32 = 0x36000; - let mut f = Flash::new(p.FLASH, interrupt::take!(FLASH)).into_blocking_regions().bank1_region; + let mut f = Flash::new_blocking_only(p.FLASH).into_blocking_regions().bank1_region; info!("Reading..."); let mut buf = [0u8; 8];