diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 33583d22..a2c5da2b 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -58,7 +58,6 @@ rand_core = "0.6.3" sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" -atomic-polyfill = "1.0.1" stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c" } vcell = "0.1.3" bxcan = "0.7.0" diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 810da37e..fa10b7f7 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -8,6 +8,32 @@ use quote::{format_ident, quote}; use stm32_metapac::metadata::{MemoryRegionKind, METADATA}; fn main() { + let target = env::var("TARGET").unwrap(); + + if target.starts_with("thumbv6m-") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv6m"); + } else if target.starts_with("thumbv7m-") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv7m"); + } else if target.starts_with("thumbv7em-") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv7m"); + println!("cargo:rustc-cfg=armv7em"); // (not currently used) + } else if target.starts_with("thumbv8m.base") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv8m"); + println!("cargo:rustc-cfg=armv8m_base"); + } else if target.starts_with("thumbv8m.main") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv8m"); + println!("cargo:rustc-cfg=armv8m_main"); + } + + if target.ends_with("-eabihf") { + println!("cargo:rustc-cfg=has_fpu"); + } + let chip_name = match env::vars() .map(|(a, _)| a) .filter(|x| x.starts_with("CARGO_FEATURE_STM32")) @@ -434,20 +460,20 @@ fn main() { unsafe { crate::rcc::get_freqs().#clk } } fn enable() { - critical_section::with(|_| { + critical_section::with(|_cs| { #before_enable #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_add(); + crate::rcc::clock_refcount_add(_cs); crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); #after_enable }) } fn disable() { - critical_section::with(|_| { + critical_section::with(|_cs| { #before_disable crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); #[cfg(feature = "low-power")] - crate::rcc::clock_refcount_sub(); + crate::rcc::clock_refcount_sub(_cs); }) } fn reset() { diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 20ff29be..62eb65b1 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -2,10 +2,9 @@ use core::future::Future; use core::pin::Pin; -use core::sync::atomic::{fence, Ordering}; +use core::sync::atomic::{fence, AtomicUsize, Ordering}; use core::task::{Context, Poll, Waker}; -use atomic_polyfill::AtomicUsize; use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; @@ -127,7 +126,13 @@ pub(crate) unsafe fn on_irq_inner(dma: pac::bdma::Dma, channel_num: usize, index } else if isr.tcif(channel_num) && cr.read().tcie() { // Acknowledge transfer complete interrupt dma.ifcr().write(|w| w.set_tcif(channel_num, true)); + #[cfg(not(armv6m))] STATE.complete_count[index].fetch_add(1, Ordering::Release); + #[cfg(armv6m)] + critical_section::with(|_| { + let x = STATE.complete_count[index].load(Ordering::Relaxed); + STATE.complete_count[index].store(x + 1, Ordering::Release); + }) } else { return; } @@ -391,7 +396,14 @@ impl<'a, C: Channel> DmaCtrl for DmaCtrlImpl<'a, C> { } fn reset_complete_count(&mut self) -> usize { - STATE.complete_count[self.0.index()].swap(0, Ordering::AcqRel) + #[cfg(not(armv6m))] + return STATE.complete_count[self.0.index()].swap(0, Ordering::AcqRel); + #[cfg(armv6m)] + return critical_section::with(|_| { + let x = STATE.complete_count[self.0.index()].load(Ordering::Acquire); + STATE.complete_count[self.0.index()].store(0, Ordering::Release); + x + }); } fn set_waker(&mut self, waker: &Waker) { diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index e883678b..37c94f82 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -225,7 +225,9 @@ pub fn init(config: Config) -> Peripherals { #[cfg(feature = "low-power")] while !crate::rcc::low_power_ready() { - crate::rcc::clock_refcount_sub(); + critical_section::with(|cs| { + crate::rcc::clock_refcount_sub(cs); + }); } } diff --git a/embassy-stm32/src/low_power.rs b/embassy-stm32/src/low_power.rs index bb714b8c..861a59d7 100644 --- a/embassy-stm32/src/low_power.rs +++ b/embassy-stm32/src/low_power.rs @@ -1,7 +1,7 @@ use core::arch::asm; use core::marker::PhantomData; +use core::sync::atomic::{compiler_fence, Ordering}; -use atomic_polyfill::{compiler_fence, Ordering}; use cortex_m::peripheral::SCB; use embassy_executor::*; diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index a9e53d42..abb53fd1 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -27,9 +27,10 @@ pub use mco::*; #[cfg_attr(rcc_wba, path = "wba.rs")] #[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] mod _version; -pub use _version::*; #[cfg(feature = "low-power")] -use atomic_polyfill::{AtomicU32, Ordering}; +use core::sync::atomic::{AtomicU32, Ordering}; + +pub use _version::*; // Model Clock Configuration // @@ -145,14 +146,17 @@ pub fn low_power_ready() -> bool { } #[cfg(feature = "low-power")] -pub(crate) fn clock_refcount_add() { +pub(crate) fn clock_refcount_add(_cs: critical_section::CriticalSection) { // We don't check for overflow because constructing more than u32 peripherals is unlikely - CLOCK_REFCOUNT.fetch_add(1, Ordering::Relaxed); + let n = CLOCK_REFCOUNT.load(Ordering::Relaxed); + CLOCK_REFCOUNT.store(n + 1, Ordering::Relaxed); } #[cfg(feature = "low-power")] -pub(crate) fn clock_refcount_sub() { - assert!(CLOCK_REFCOUNT.fetch_sub(1, Ordering::Relaxed) != 0); +pub(crate) fn clock_refcount_sub(_cs: critical_section::CriticalSection) { + let n = CLOCK_REFCOUNT.load(Ordering::Relaxed); + assert!(n != 0); + CLOCK_REFCOUNT.store(n - 1, Ordering::Relaxed); } /// Frozen clock frequencies diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 91750241..e88198e6 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -1,9 +1,8 @@ use core::cell::Cell; use core::convert::TryInto; -use core::sync::atomic::{compiler_fence, Ordering}; +use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; use core::{mem, ptr}; -use atomic_polyfill::{AtomicU32, AtomicU8}; use critical_section::CriticalSection; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::Mutex; @@ -229,7 +228,9 @@ impl RtcDriver { fn next_period(&self) { let r = T::regs_gp16(); - let period = self.period.fetch_add(1, Ordering::Relaxed) + 1; + // We only modify the period from the timer interrupt, so we know this can't race. + let period = self.period.load(Ordering::Relaxed) + 1; + self.period.store(period, Ordering::Relaxed); let t = (period as u64) << 15; critical_section::with(move |cs| { @@ -403,18 +404,15 @@ impl Driver for RtcDriver { } unsafe fn allocate_alarm(&self) -> Option { - let id = self.alarm_count.fetch_update(Ordering::AcqRel, Ordering::Acquire, |x| { - if x < ALARM_COUNT as u8 { - Some(x + 1) + critical_section::with(|_| { + let id = self.alarm_count.load(Ordering::Relaxed); + if id < ALARM_COUNT as u8 { + self.alarm_count.store(id + 1, Ordering::Relaxed); + Some(AlarmHandle::new(id)) } else { None } - }); - - match id { - Ok(id) => Some(AlarmHandle::new(id)), - Err(_) => None, - } + }) } fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) { diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml index 8f034a9d..e4b88d78 100644 --- a/embassy-time/Cargo.toml +++ b/embassy-time/Cargo.toml @@ -218,7 +218,6 @@ embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = embedded-hal-async = { version = "=1.0.0-rc.1", optional = true} futures-util = { version = "0.3.17", default-features = false } -atomic-polyfill = "1.0.1" critical-section = "1.1" cfg-if = "1.0.0" heapless = "0.7"