diff --git a/embassy-extras/src/macros.rs b/embassy-extras/src/macros.rs index 151f410a..478549ac 100644 --- a/embassy-extras/src/macros.rs +++ b/embassy-extras/src/macros.rs @@ -1,41 +1,71 @@ #[macro_export] macro_rules! peripherals { ($($(#[$cfg:meta])? $name:ident: $type:ident),*$(,)?) => { - $( - $(#[$cfg])? - #[allow(non_camel_case_types)] - pub struct $type { _private: () } + pub mod peripherals { + $( + $(#[$cfg])? + #[allow(non_camel_case_types)] + pub struct $type { _private: () } - $(#[$cfg])? - impl embassy::util::PeripheralBorrow for $type { - type Target = $type; - unsafe fn unborrow(self) -> $type { - self + impl embassy::util::Steal for $type { + #[inline] + unsafe fn steal() -> Self { + Self{ _private: ()} + } } - } - $(#[$cfg])? - impl embassy::util::PeripheralBorrow for &mut $type { - type Target = $type; - unsafe fn unborrow(self) -> $type { - ::core::ptr::read(self) + $(#[$cfg])? + impl embassy::util::PeripheralBorrow for $type { + type Target = $type; + #[inline] + unsafe fn unborrow(self) -> $type { + self + } } - } - )* + + $(#[$cfg])? + impl embassy::util::PeripheralBorrow for &mut $type { + type Target = $type; + #[inline] + unsafe fn unborrow(self) -> $type { + ::core::ptr::read(self) + } + } + )* + } pub struct Peripherals { $( $(#[$cfg])? - pub $name: $type, + pub $name: peripherals::$type, )* } impl Peripherals { - pub unsafe fn steal() -> Self { + ///Returns all the peripherals *once* + #[inline] + pub fn take() -> Option { + + #[no_mangle] + static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false; + + cortex_m::interrupt::free(|_| { + if unsafe { _EMBASSY_DEVICE_PERIPHERALS } { + None + } else { + Some(unsafe { ::steal() }) + } + }) + } + } + + impl embassy::util::Steal for Peripherals { + #[inline] + unsafe fn steal() -> Self { Self { $( $(#[$cfg])? - $name: $type { _private: () }, + $name: ::steal(), )* } } diff --git a/embassy-nrf-examples/src/bin/gpiote_port.rs b/embassy-nrf-examples/src/bin/gpiote_port.rs index 0ec9e5d3..593261ae 100644 --- a/embassy-nrf-examples/src/bin/gpiote_port.rs +++ b/embassy-nrf-examples/src/bin/gpiote_port.rs @@ -6,18 +6,18 @@ #[path = "../example_common.rs"] mod example_common; -use example_common::*; use core::pin::Pin; use cortex_m_rt::entry; use defmt::panic; - use embassy::executor::{task, Executor}; use embassy::traits::gpio::{WaitForHigh, WaitForLow}; use embassy::util::Forever; use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull}; use embassy_nrf::gpiote::{self, PortInput}; use embassy_nrf::interrupt; +use embassy_nrf::Peripherals; +use example_common::*; async fn button(n: usize, mut pin: PortInput) { loop { @@ -30,7 +30,7 @@ async fn button(n: usize, mut pin: PortInput) { #[task] async fn run() { - let p = unsafe { embassy_nrf::peripherals::Peripherals::steal() }; + let p = Peripherals::take().unwrap(); let g = gpiote::initialize(p.gpiote, interrupt::take!(GPIOTE)); diff --git a/embassy-nrf-examples/src/bin/qspi.rs b/embassy-nrf-examples/src/bin/qspi.rs index a0896988..1637b397 100644 --- a/embassy-nrf-examples/src/bin/qspi.rs +++ b/embassy-nrf-examples/src/bin/qspi.rs @@ -6,17 +6,16 @@ #[path = "../example_common.rs"] mod example_common; -use embassy_nrf::peripherals::Peripherals; -use example_common::*; use cortex_m_rt::entry; use defmt::{assert_eq, panic}; -use futures::pin_mut; - use embassy::executor::{task, Executor}; use embassy::traits::flash::Flash; use embassy::util::Forever; +use embassy_nrf::Peripherals; use embassy_nrf::{interrupt, qspi}; +use example_common::*; +use futures::pin_mut; const PAGE_SIZE: usize = 4096; @@ -27,7 +26,7 @@ struct AlignedBuf([u8; 4096]); #[task] async fn run() { - let p = unsafe { Peripherals::steal() }; + let p = Peripherals::take().unwrap(); let csn = p.p0_17; let sck = p.p0_19; diff --git a/embassy-nrf-examples/src/bin/spim.rs b/embassy-nrf-examples/src/bin/spim.rs index b7436332..f4fb22ba 100644 --- a/embassy-nrf-examples/src/bin/spim.rs +++ b/embassy-nrf-examples/src/bin/spim.rs @@ -6,26 +6,25 @@ #[path = "../example_common.rs"] mod example_common; -use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_nrf::peripherals::Peripherals; -use embassy_traits::spi::FullDuplex; -use example_common::*; use cortex_m_rt::entry; use defmt::panic; use embassy::executor::{task, Executor}; use embassy::util::Forever; +use embassy_nrf::gpio::{Level, Output, OutputDrive}; +use embassy_nrf::Peripherals; +use embassy_nrf::{interrupt, pac, rtc, spim}; +use embassy_traits::spi::FullDuplex; use embedded_hal::digital::v2::*; +use example_common::*; use futures::pin_mut; use nrf52840_hal::clocks; -use embassy_nrf::{interrupt, pac, rtc, spim}; - #[task] async fn run() { info!("running!"); - let mut p = unsafe { Peripherals::steal() }; + let p = Peripherals::take().unwrap(); let config = spim::Config { frequency: spim::Frequency::M16, @@ -33,7 +32,7 @@ async fn run() { orc: 0x00, }; - let mut irq = interrupt::take!(SPIM3); + let irq = interrupt::take!(SPIM3); let spim = spim::Spim::new(p.spim3, irq, p.p0_29, p.p0_28, p.p0_30, config); pin_mut!(spim); diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 07759996..22c71e7f 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -97,9 +97,115 @@ pub mod buffered_uarte; pub mod gpio; pub mod gpiote; pub mod interrupt; -pub mod peripherals; #[cfg(feature = "52840")] pub mod qspi; pub mod rtc; pub mod spim; pub mod uarte; + +embassy_extras::peripherals! { + // RTC + rtc0: RTC0, + rtc1: RTC1, + #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] + rtc2: RTC2, + + // QSPI + #[cfg(feature = "52840")] + qspi: QSPI, + + // UARTE + uarte0: UARTE0, + #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] + uarte1: UARTE1, + + // SPIM + // TODO this is actually shared with SPI, SPIM, SPIS, TWI, TWIS, TWIS. + // When they're all implemented, they should be only one peripheral here. + spim0: SPIM0, + #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] + spim1: SPIM1, + #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] + spim2: SPIM2, + #[cfg(any(feature = "52833", feature = "52840"))] + spim3: SPIM3, + + // GPIOTE + gpiote: GPIOTE, + gpiote_ch_0: GPIOTE_CH0, + gpiote_ch_1: GPIOTE_CH1, + gpiote_ch_2: GPIOTE_CH2, + gpiote_ch_3: GPIOTE_CH3, + gpiote_ch_4: GPIOTE_CH4, + gpiote_ch_5: GPIOTE_CH5, + gpiote_ch_6: GPIOTE_CH6, + gpiote_ch_7: GPIOTE_CH7, + + // GPIO port 0 + p0_00: P0_00, + p0_01: P0_01, + p0_02: P0_02, + p0_03: P0_03, + p0_04: P0_04, + p0_05: P0_05, + p0_06: P0_06, + p0_07: P0_07, + p0_08: P0_08, + p0_09: P0_09, + p0_10: P0_10, + p0_11: P0_11, + p0_12: P0_12, + p0_13: P0_13, + p0_14: P0_14, + p0_15: P0_15, + p0_16: P0_16, + p0_17: P0_17, + p0_18: P0_18, + p0_19: P0_19, + p0_20: P0_20, + p0_21: P0_21, + p0_22: P0_22, + p0_23: P0_23, + p0_24: P0_24, + p0_25: P0_25, + p0_26: P0_26, + p0_27: P0_27, + p0_28: P0_28, + p0_29: P0_29, + p0_30: P0_30, + p0_31: P0_31, + + // GPIO port 1 + #[cfg(any(feature = "52833", feature = "52840"))] + p1_00: P1_00, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_01: P1_01, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_02: P1_02, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_03: P1_03, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_04: P1_04, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_05: P1_05, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_06: P1_06, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_07: P1_07, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_08: P1_08, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_09: P1_09, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_10: P1_10, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_11: P1_11, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_12: P1_12, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_13: P1_13, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_14: P1_14, + #[cfg(any(feature = "52833", feature = "52840"))] + p1_15: P1_15, +} diff --git a/embassy-nrf/src/peripherals.rs b/embassy-nrf/src/peripherals.rs deleted file mode 100644 index ea76c809..00000000 --- a/embassy-nrf/src/peripherals.rs +++ /dev/null @@ -1,106 +0,0 @@ -embassy_extras::peripherals! { - // RTC - rtc0: RTC0, - rtc1: RTC1, - #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] - rtc2: RTC2, - - // QSPI - #[cfg(feature = "52840")] - qspi: QSPI, - - // UARTE - uarte0: UARTE0, - #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] - uarte1: UARTE1, - - // SPIM - // TODO this is actually shared with SPI, SPIM, SPIS, TWI, TWIS, TWIS. - // When they're all implemented, they should be only one peripheral here. - spim0: SPIM0, - #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] - spim1: SPIM1, - #[cfg(any(feature = "52832", feature = "52833", feature = "52840"))] - spim2: SPIM2, - #[cfg(any(feature = "52833", feature = "52840"))] - spim3: SPIM3, - - // GPIOTE - gpiote: GPIOTE, - gpiote_ch_0: GPIOTE_CH0, - gpiote_ch_1: GPIOTE_CH1, - gpiote_ch_2: GPIOTE_CH2, - gpiote_ch_3: GPIOTE_CH3, - gpiote_ch_4: GPIOTE_CH4, - gpiote_ch_5: GPIOTE_CH5, - gpiote_ch_6: GPIOTE_CH6, - gpiote_ch_7: GPIOTE_CH7, - - // GPIO port 0 - p0_00: P0_00, - p0_01: P0_01, - p0_02: P0_02, - p0_03: P0_03, - p0_04: P0_04, - p0_05: P0_05, - p0_06: P0_06, - p0_07: P0_07, - p0_08: P0_08, - p0_09: P0_09, - p0_10: P0_10, - p0_11: P0_11, - p0_12: P0_12, - p0_13: P0_13, - p0_14: P0_14, - p0_15: P0_15, - p0_16: P0_16, - p0_17: P0_17, - p0_18: P0_18, - p0_19: P0_19, - p0_20: P0_20, - p0_21: P0_21, - p0_22: P0_22, - p0_23: P0_23, - p0_24: P0_24, - p0_25: P0_25, - p0_26: P0_26, - p0_27: P0_27, - p0_28: P0_28, - p0_29: P0_29, - p0_30: P0_30, - p0_31: P0_31, - - // GPIO port 1 - #[cfg(any(feature = "52833", feature = "52840"))] - p1_00: P1_00, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_01: P1_01, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_02: P1_02, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_03: P1_03, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_04: P1_04, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_05: P1_05, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_06: P1_06, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_07: P1_07, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_08: P1_08, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_09: P1_09, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_10: P1_10, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_11: P1_11, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_12: P1_12, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_13: P1_13, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_14: P1_14, - #[cfg(any(feature = "52833", feature = "52840"))] - p1_15: P1_15, -} diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs index 18b61246..3166c65d 100644 --- a/embassy/src/util/mod.rs +++ b/embassy/src/util/mod.rs @@ -19,3 +19,7 @@ pub trait PeripheralBorrow { type Target; unsafe fn unborrow(self) -> Self::Target; } + +pub trait Steal { + unsafe fn steal() -> Self; +}