diff --git a/embassy-hal-common/src/peripheral.rs b/embassy-hal-common/src/peripheral.rs index 99df4b894..038cebb5e 100644 --- a/embassy-hal-common/src/peripheral.rs +++ b/embassy-hal-common/src/peripheral.rs @@ -27,6 +27,36 @@ impl<'a, T> PeripheralRef<'a, T> { } } + /// Unsafely clone (duplicate) a peripheral singleton. + /// + /// # Safety + /// + /// This returns an owned clone of the peripheral. You must manually ensure + /// only one copy of the peripheral is in use at a time. For example, don't + /// create two SPI drivers on `SPI1`, because they will "fight" each other. + /// + /// You should strongly prefer using `reborrow()` instead. It returns a + /// `PeripheralRef` that borrows `self`, which allows the borrow checker + /// to enforce this at compile time. + pub unsafe fn clone_unchecked(&mut self) -> PeripheralRef<'a, T> + where + T: Peripheral

, + { + PeripheralRef::new(self.inner.clone_unchecked()) + } + + /// Reborrow into a "child" PeripheralRef. + /// + /// `self` will stay borrowed until the child PeripheralRef is dropped. + pub fn reborrow(&mut self) -> PeripheralRef<'_, T> + where + T: Peripheral

, + { + // safety: we're returning the clone inside a new PeripheralRef that borrows + // self, so user code can't use both at the same time. + PeripheralRef::new(unsafe { self.inner.clone_unchecked() }) + } + /// Map the inner peripheral using `Into`. /// /// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 036af3804..89c1ba908 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -15,14 +15,13 @@ use core::cmp::min; use core::future::Future; -use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy::waitqueue::WakerRegistration; use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; use embassy_hal_common::ring_buffer::RingBuffer; -use embassy_hal_common::{into_ref, low_power_wait_until}; +use embassy_hal_common::{into_ref, low_power_wait_until, PeripheralRef}; use futures::future::poll_fn; // Re-export SVD variants to allow user to directly set values pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; @@ -54,7 +53,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> { } struct StateInner<'d, U: UarteInstance, T: TimerInstance> { - phantom: PhantomData<&'d mut U>, + _peri: PeripheralRef<'d, U>, timer: Timer<'d, T>, _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, @@ -78,7 +77,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> { impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { pub fn new( state: &'d mut State<'d, U, T>, - _uarte: impl Peripheral

+ 'd, + peri: impl Peripheral

+ 'd, timer: impl Peripheral

+ 'd, ppi_ch1: impl Peripheral

+ 'd, ppi_ch2: impl Peripheral

+ 'd, @@ -91,7 +90,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { rx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8], ) -> Self { - into_ref!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); + into_ref!(peri, ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); let r = U::regs(); @@ -163,7 +162,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { Self { inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner { - phantom: PhantomData, + _peri: peri, timer, _ppi_ch1: ppi_ch1, _ppi_ch2: ppi_ch2, diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index e89d01685..cef80ae0a 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs @@ -1,10 +1,9 @@ use core::convert::Infallible; use core::future::Future; -use core::marker::PhantomData; use core::task::{Context, Poll}; use embassy::waitqueue::AtomicWaker; -use embassy_hal_common::impl_peripheral; +use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef}; use futures::future::poll_fn; use crate::gpio::sealed::Pin as _; @@ -301,16 +300,22 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> { // ======================= pub(crate) struct PortInputFuture<'a> { - pin_port: u8, - phantom: PhantomData<&'a mut AnyPin>, + pin: PeripheralRef<'a, AnyPin>, +} + +impl<'a> PortInputFuture<'a> { + fn new(pin: impl Peripheral

+ 'a) -> Self { + Self { + pin: pin.into_ref().map_into(), + } + } } impl<'a> Unpin for PortInputFuture<'a> {} impl<'a> Drop for PortInputFuture<'a> { fn drop(&mut self) { - let pin = unsafe { AnyPin::steal(self.pin_port) }; - pin.conf().modify(|_, w| w.sense().disabled()); + self.pin.conf().modify(|_, w| w.sense().disabled()); } } @@ -318,10 +323,9 @@ impl<'a> Future for PortInputFuture<'a> { type Output = (); fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - PORT_WAKERS[self.pin_port as usize].register(cx.waker()); + PORT_WAKERS[self.pin.pin_port() as usize].register(cx.waker()); - let pin = unsafe { AnyPin::steal(self.pin_port) }; - if pin.conf().read().sense().is_disabled() { + if self.pin.conf().read().sense().is_disabled() { Poll::Ready(()) } else { Poll::Pending @@ -354,22 +358,12 @@ impl<'d, T: GpioPin> Input<'d, T> { impl<'d, T: GpioPin> Flex<'d, T> { pub async fn wait_for_high(&mut self) { self.pin.conf().modify(|_, w| w.sense().high()); - - PortInputFuture { - pin_port: self.pin.pin_port(), - phantom: PhantomData, - } - .await + PortInputFuture::new(&mut self.pin).await } pub async fn wait_for_low(&mut self) { self.pin.conf().modify(|_, w| w.sense().low()); - - PortInputFuture { - pin_port: self.pin.pin_port(), - phantom: PhantomData, - } - .await + PortInputFuture::new(&mut self.pin).await } pub async fn wait_for_rising_edge(&mut self) { @@ -388,11 +382,7 @@ impl<'d, T: GpioPin> Flex<'d, T> { } else { self.pin.conf().modify(|_, w| w.sense().high()); } - PortInputFuture { - pin_port: self.pin.pin_port(), - phantom: PhantomData, - } - .await + PortInputFuture::new(&mut self.pin).await } } diff --git a/embassy-nrf/src/nvmc.rs b/embassy-nrf/src/nvmc.rs index 731def46a..cd6100339 100644 --- a/embassy-nrf/src/nvmc.rs +++ b/embassy-nrf/src/nvmc.rs @@ -1,9 +1,8 @@ //! Nvmcerature sensor interface. -use core::marker::PhantomData; use core::{ptr, slice}; -use embassy_hal_common::into_ref; +use embassy_hal_common::{into_ref, PeripheralRef}; use embedded_storage::nor_flash::{ ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, }; @@ -31,14 +30,13 @@ impl NorFlashError for Error { } pub struct Nvmc<'d> { - _p: PhantomData<&'d NVMC>, + _p: PeripheralRef<'d, NVMC>, } impl<'d> Nvmc<'d> { pub fn new(_p: impl Peripheral

+ 'd) -> Self { into_ref!(_p); - - Self { _p: PhantomData } + Self { _p } } fn regs() -> &'static pac::nvmc::RegisterBlock { diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index ecc674ce0..5f750a91e 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -1,6 +1,5 @@ #![macro_use] -use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use embassy_hal_common::{into_ref, PeripheralRef}; @@ -15,7 +14,7 @@ use crate::{pac, Peripheral}; /// SimplePwm is the traditional pwm interface you're probably used to, allowing /// to simply set a duty cycle across up to four channels. pub struct SimplePwm<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, + _peri: PeripheralRef<'d, T>, duty: [u16; 4], ch0: Option>, ch1: Option>, @@ -26,7 +25,7 @@ pub struct SimplePwm<'d, T: Instance> { /// SequencePwm allows you to offload the updating of a sequence of duty cycles /// to up to four channels, as well as repeat that sequence n times. pub struct SequencePwm<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, + _peri: PeripheralRef<'d, T>, ch0: Option>, ch1: Option>, ch2: Option>, @@ -120,6 +119,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> { ch3: Option>, config: Config, ) -> Result { + into_ref!(_pwm); + let r = T::regs(); if let Some(pin) = &ch0 { @@ -168,7 +169,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { r.countertop.write(|w| unsafe { w.countertop().bits(config.max_duty) }); Ok(Self { - phantom: PhantomData, + _peri: _pwm, ch0, ch1, ch2, @@ -639,6 +640,8 @@ impl<'d, T: Instance> SimplePwm<'d, T> { ch2: Option>, ch3: Option>, ) -> Self { + into_ref!(_pwm); + let r = T::regs(); if let Some(pin) = &ch0 { @@ -666,7 +669,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) }); let pwm = Self { - phantom: PhantomData, + _peri: _pwm, ch0, ch1, ch2, diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs index d5dc14466..f6daec252 100644 --- a/embassy-nrf/src/qdec.rs +++ b/embassy-nrf/src/qdec.rs @@ -1,6 +1,5 @@ //! Quadrature decoder interface -use core::marker::PhantomData; use core::task::Poll; use embassy::waitqueue::AtomicWaker; @@ -15,7 +14,7 @@ use crate::{interrupt, pac, Peripheral}; /// Quadrature decoder pub struct Qdec<'d> { - phantom: PhantomData<&'d QDEC>, + _p: PeripheralRef<'d, QDEC>, } #[non_exhaustive] @@ -66,14 +65,14 @@ impl<'d> Qdec<'d> { } fn new_inner( - _t: impl Peripheral

+ 'd, + p: impl Peripheral

+ 'd, irq: impl Peripheral

+ 'd, a: PeripheralRef<'d, AnyPin>, b: PeripheralRef<'d, AnyPin>, led: Option>, config: Config, ) -> Self { - into_ref!(irq); + into_ref!(p, irq); let r = Self::regs(); // Select pins. @@ -131,7 +130,7 @@ impl<'d> Qdec<'d> { }); irq.enable(); - Self { phantom: PhantomData } + Self { _p: p } } /// Perform an asynchronous read of the decoder. diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index 644ffa1f0..6ddc70e52 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -1,11 +1,10 @@ #![macro_use] -use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy::waitqueue::AtomicWaker; -use embassy_hal_common::{impl_peripheral, into_ref}; +use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; use futures::future::poll_fn; use pac::{saadc, SAADC}; use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; @@ -14,6 +13,7 @@ pub(crate) use saadc::ch::pselp::PSELP_A as InputChannel; use saadc::oversample::OVERSAMPLE_A; use saadc::resolution::VAL_A; +use self::sealed::Input as _; use crate::interrupt::InterruptExt; use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; use crate::timer::{Frequency, Instance as TimerInstance, Timer}; @@ -26,7 +26,7 @@ pub enum Error {} /// One-shot and continuous SAADC. pub struct Saadc<'d, const N: usize> { - phantom: PhantomData<&'d mut peripherals::SAADC>, + _p: PeripheralRef<'d, peripherals::SAADC>, } static WAKER: AtomicWaker = AtomicWaker::new(); @@ -66,63 +66,11 @@ pub struct ChannelConfig<'d> { /// Acquisition time in microseconds. pub time: Time, /// Positive channel to sample - p_channel: InputChannel, + p_channel: PeripheralRef<'d, AnyInput>, /// An optional negative channel to sample - n_channel: Option, - - phantom: PhantomData<&'d ()>, + n_channel: Option>, } -/// A dummy `Input` pin implementation for SAADC peripheral sampling from the -/// internal voltage. -pub struct VddInput; - -impl_peripheral!(VddInput); - -impl sealed::Input for VddInput { - #[cfg(not(feature = "_nrf9160"))] - fn channel(&self) -> InputChannel { - InputChannel::VDD - } - #[cfg(feature = "_nrf9160")] - fn channel(&self) -> InputChannel { - InputChannel::VDDGPIO - } -} -impl Input for VddInput {} - -/// A dummy `Input` pin implementation for SAADC peripheral sampling from the -/// VDDH / 5 voltage. -#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] -pub struct VddhDiv5Input; - -#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] -impl_peripheral!(VddhDiv5Input); - -#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] -impl sealed::Input for VddhDiv5Input { - fn channel(&self) -> InputChannel { - InputChannel::VDDHDIV5 - } -} - -#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] -impl Input for VddhDiv5Input {} - -pub struct AnyInput { - channel: InputChannel, -} - -impl_peripheral!(AnyInput); - -impl sealed::Input for AnyInput { - fn channel(&self) -> InputChannel { - self.channel - } -} - -impl Input for AnyInput {} - impl<'d> ChannelConfig<'d> { /// Default configuration for single ended channel sampling. pub fn single_ended(input: impl Peripheral

+ 'd) -> Self { @@ -132,9 +80,8 @@ impl<'d> ChannelConfig<'d> { gain: Gain::GAIN1_6, resistor: Resistor::BYPASS, time: Time::_10US, - p_channel: input.channel(), + p_channel: input.map_into(), n_channel: None, - phantom: PhantomData, } } /// Default configuration for differential channel sampling. @@ -148,9 +95,8 @@ impl<'d> ChannelConfig<'d> { gain: Gain::GAIN1_6, resistor: Resistor::BYPASS, time: Time::_10US, - p_channel: p_input.channel(), - n_channel: Some(n_input.channel()), - phantom: PhantomData, + p_channel: p_input.map_into(), + n_channel: Some(n_input.map_into()), } } } @@ -167,12 +113,12 @@ pub enum SamplerState { impl<'d, const N: usize> Saadc<'d, N> { pub fn new( - _saadc: impl Peripheral

+ 'd, + saadc: impl Peripheral

+ 'd, irq: impl Peripheral

+ 'd, config: Config, channel_configs: [ChannelConfig; N], ) -> Self { - into_ref!(irq); + into_ref!(saadc, irq); let r = unsafe { &*SAADC::ptr() }; @@ -184,9 +130,11 @@ impl<'d, const N: usize> Saadc<'d, N> { r.oversample.write(|w| w.oversample().variant(oversample.into())); for (i, cc) in channel_configs.iter().enumerate() { - r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel)); - if let Some(n_channel) = cc.n_channel { - r.ch[i].pseln.write(|w| unsafe { w.pseln().bits(n_channel as u8) }); + r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel.channel())); + if let Some(n_channel) = &cc.n_channel { + r.ch[i] + .pseln + .write(|w| unsafe { w.pseln().bits(n_channel.channel() as u8) }); } r.ch[i].config.write(|w| { w.refsel().variant(cc.reference.into()); @@ -215,7 +163,7 @@ impl<'d, const N: usize> Saadc<'d, N> { irq.unpend(); irq.enable(); - Self { phantom: PhantomData } + Self { _p: saadc } } fn on_interrupt(_ctx: *mut ()) { @@ -674,7 +622,7 @@ pub(crate) mod sealed { } /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. -pub trait Input: sealed::Input + Peripheral

+ Sized { +pub trait Input: sealed::Input + Into + Peripheral

+ Sized + 'static { fn degrade_saadc(self) -> AnyInput { AnyInput { channel: self.channel(), @@ -682,13 +630,57 @@ pub trait Input: sealed::Input + Peripheral

+ Sized { } } +pub struct AnyInput { + channel: InputChannel, +} + +impl_peripheral!(AnyInput); + +impl sealed::Input for AnyInput { + fn channel(&self) -> InputChannel { + self.channel + } +} + +impl Input for AnyInput {} + macro_rules! impl_saadc_input { ($pin:ident, $ch:ident) => { - impl crate::saadc::sealed::Input for crate::peripherals::$pin { + impl_saadc_input!(@local, crate::peripherals::$pin, $ch); + }; + (@local, $pin:ty, $ch:ident) => { + impl crate::saadc::sealed::Input for $pin { fn channel(&self) -> crate::saadc::InputChannel { crate::saadc::InputChannel::$ch } } - impl crate::saadc::Input for crate::peripherals::$pin {} + impl crate::saadc::Input for $pin {} + + impl From<$pin> for crate::saadc::AnyInput { + fn from(val: $pin) -> Self { + crate::saadc::Input::degrade_saadc(val) + } + } }; } + +/// A dummy `Input` pin implementation for SAADC peripheral sampling from the +/// internal voltage. +pub struct VddInput; + +impl_peripheral!(VddInput); +#[cfg(not(feature = "_nrf9160"))] +impl_saadc_input!(@local, VddInput, VDD); +#[cfg(feature = "_nrf9160")] +impl_saadc_input!(@local, VddInput, VDDGPIO); + +/// A dummy `Input` pin implementation for SAADC peripheral sampling from the +/// VDDH / 5 voltage. +#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] +pub struct VddhDiv5Input; + +#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] +impl_peripheral!(VddhDiv5Input); + +#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] +impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5); diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index a6b0be076..a512b4813 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -1,6 +1,5 @@ #![macro_use] -use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; @@ -31,7 +30,7 @@ pub enum Error { /// /// For more details about EasyDMA, consult the module documentation. pub struct Spim<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, + _p: PeripheralRef<'d, T>, } #[non_exhaustive] @@ -94,14 +93,14 @@ impl<'d, T: Instance> Spim<'d, T> { } fn new_inner( - _spim: impl Peripheral

+ 'd, + spim: impl Peripheral

+ 'd, irq: impl Peripheral

+ 'd, sck: PeripheralRef<'d, AnyPin>, miso: Option>, mosi: Option>, config: Config, ) -> Self { - into_ref!(irq); + into_ref!(spim, irq); let r = T::regs(); @@ -181,7 +180,7 @@ impl<'d, T: Instance> Spim<'d, T> { irq.unpend(); irq.enable(); - Self { phantom: PhantomData } + Self { _p: spim } } fn on_interrupt(_: *mut ()) { diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index d7a7c4d70..8deecdc03 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs @@ -5,7 +5,7 @@ use core::task::Poll; use embassy::waitqueue::AtomicWaker; use embassy_hal_common::drop::OnDrop; -use embassy_hal_common::into_ref; +use embassy_hal_common::{into_ref, PeripheralRef}; use futures::future::poll_fn; use crate::interrupt::{Interrupt, InterruptExt}; @@ -95,7 +95,8 @@ impl TimerType for Awaitable {} impl TimerType for NotAwaitable {} pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> { - phantom: PhantomData<(&'d mut T, I)>, + _p: PeripheralRef<'d, T>, + _i: PhantomData, } impl<'d, T: Instance> Timer<'d, T, Awaitable> { @@ -123,10 +124,15 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. /// /// This is used by the public constructors. - fn new_irqless(_timer: impl Peripheral

+ 'd) -> Self { + fn new_irqless(timer: impl Peripheral

+ 'd) -> Self { + into_ref!(timer); + let regs = T::regs(); - let mut this = Self { phantom: PhantomData }; + let mut this = Self { + _p: timer, + _i: PhantomData, + }; // Stop the timer before doing anything else, // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. @@ -230,7 +236,8 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { } Cc { n, - phantom: PhantomData, + _p: self._p.reborrow(), + _i: PhantomData, } } } @@ -242,12 +249,13 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> { /// /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register -pub struct Cc<'a, T: Instance, I: TimerType = NotAwaitable> { +pub struct Cc<'d, T: Instance, I: TimerType = NotAwaitable> { n: usize, - phantom: PhantomData<(&'a mut T, I)>, + _p: PeripheralRef<'d, T>, + _i: PhantomData, } -impl<'a, T: Instance> Cc<'a, T, Awaitable> { +impl<'d, T: Instance> Cc<'d, T, Awaitable> { /// Wait until the timer's counter reaches the value stored in this register. /// /// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`. @@ -281,9 +289,9 @@ impl<'a, T: Instance> Cc<'a, T, Awaitable> { on_drop.defuse(); } } -impl<'a, T: Instance> Cc<'a, T, NotAwaitable> {} +impl<'d, T: Instance> Cc<'d, T, NotAwaitable> {} -impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { +impl<'d, T: Instance, I: TimerType> Cc<'d, T, I> { /// Get the current value stored in the register. pub fn read(&self) -> u32 { T::regs().cc[self.n].read().cc().bits() diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 7699d2a71..6d6eb84e7 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -7,7 +7,6 @@ //! - nRF52832: Section 33 //! - nRF52840: Section 6.31 use core::future::Future; -use core::marker::PhantomData; use core::sync::atomic::compiler_fence; use core::sync::atomic::Ordering::SeqCst; use core::task::Poll; @@ -16,7 +15,7 @@ use core::task::Poll; use embassy::time::{Duration, Instant}; use embassy::waitqueue::AtomicWaker; use embassy_embedded_hal::SetConfig; -use embassy_hal_common::into_ref; +use embassy_hal_common::{into_ref, PeripheralRef}; use futures::future::poll_fn; use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; @@ -75,18 +74,18 @@ pub enum Error { /// /// For more details about EasyDMA, consult the module documentation. pub struct Twim<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, + _p: PeripheralRef<'d, T>, } impl<'d, T: Instance> Twim<'d, T> { pub fn new( - _twim: impl Peripheral

+ 'd, + twim: impl Peripheral

+ 'd, irq: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, config: Config, ) -> Self { - into_ref!(irq, sda, scl); + into_ref!(twim, irq, sda, scl); let r = T::regs(); @@ -136,7 +135,7 @@ impl<'d, T: Instance> Twim<'d, T> { irq.unpend(); irq.enable(); - Self { phantom: PhantomData } + Self { _p: twim } } fn on_interrupt(_: *mut ()) { diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index e23525563..792b8ecca 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -13,7 +13,6 @@ //! memory may be used given that buffers are passed in directly to its read and write //! methods. -use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; @@ -63,7 +62,6 @@ pub enum Error { /// /// For more details about EasyDMA, consult the module documentation. pub struct Uarte<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, tx: UarteTx<'d, T>, rx: UarteRx<'d, T>, } @@ -71,13 +69,13 @@ pub struct Uarte<'d, T: Instance> { /// Transmitter interface to the UARTE peripheral obtained /// via [Uarte]::split. pub struct UarteTx<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, + _p: PeripheralRef<'d, T>, } /// Receiver interface to the UARTE peripheral obtained /// via [Uarte]::split. pub struct UarteRx<'d, T: Instance> { - phantom: PhantomData<&'d mut T>, + _p: PeripheralRef<'d, T>, } impl<'d, T: Instance> Uarte<'d, T> { @@ -116,7 +114,7 @@ impl<'d, T: Instance> Uarte<'d, T> { } fn new_inner( - _uarte: impl Peripheral

+ 'd, + uarte: impl Peripheral

+ 'd, irq: impl Peripheral

+ 'd, rxd: PeripheralRef<'d, AnyPin>, txd: PeripheralRef<'d, AnyPin>, @@ -124,7 +122,7 @@ impl<'d, T: Instance> Uarte<'d, T> { rts: Option>, config: Config, ) -> Self { - into_ref!(irq); + into_ref!(uarte, irq); let r = T::regs(); @@ -161,9 +159,10 @@ impl<'d, T: Instance> Uarte<'d, T> { s.tx_rx_refcount.store(2, Ordering::Relaxed); Self { - phantom: PhantomData, - tx: UarteTx { phantom: PhantomData }, - rx: UarteRx { phantom: PhantomData }, + tx: UarteTx { + _p: unsafe { uarte.clone_unchecked() }, + }, + rx: UarteRx { _p: uarte }, } } @@ -267,13 +266,13 @@ impl<'d, T: Instance> UarteTx<'d, T> { } fn new_inner( - _uarte: impl Peripheral

+ 'd, + uarte: impl Peripheral

+ 'd, irq: impl Peripheral

+ 'd, txd: PeripheralRef<'d, AnyPin>, cts: Option>, config: Config, ) -> Self { - into_ref!(irq); + into_ref!(uarte, irq); let r = T::regs(); @@ -299,7 +298,7 @@ impl<'d, T: Instance> UarteTx<'d, T> { let s = T::state(); s.tx_rx_refcount.store(1, Ordering::Relaxed); - Self { phantom: PhantomData } + Self { _p: uarte } } pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { @@ -459,13 +458,13 @@ impl<'d, T: Instance> UarteRx<'d, T> { } fn new_inner( - _uarte: impl Peripheral

+ 'd, + uarte: impl Peripheral

+ 'd, irq: impl Peripheral

+ 'd, rxd: PeripheralRef<'d, AnyPin>, rts: Option>, config: Config, ) -> Self { - into_ref!(irq); + into_ref!(uarte, irq); let r = T::regs(); @@ -491,7 +490,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { let s = T::state(); s.tx_rx_refcount.store(1, Ordering::Relaxed); - Self { phantom: PhantomData } + Self { _p: uarte } } pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs index eaecda570..378492859 100644 --- a/embassy-nrf/src/usb.rs +++ b/embassy-nrf/src/usb.rs @@ -7,7 +7,7 @@ use core::task::Poll; use cortex_m::peripheral::NVIC; use embassy::waitqueue::AtomicWaker; -use embassy_hal_common::into_ref; +use embassy_hal_common::{into_ref, PeripheralRef}; pub use embassy_usb; use embassy_usb::driver::{self, EndpointError, Event, Unsupported}; use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; @@ -38,7 +38,7 @@ pub trait UsbSupply { } pub struct Driver<'d, T: Instance, P: UsbSupply> { - phantom: PhantomData<&'d mut T>, + _p: PeripheralRef<'d, T>, alloc_in: Allocator, alloc_out: Allocator, usb_supply: P, @@ -166,14 +166,14 @@ impl UsbSupply for SignalledSupply { } impl<'d, T: Instance, P: UsbSupply> Driver<'d, T, P> { - pub fn new(_usb: impl Peripheral

+ 'd, irq: impl Peripheral

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

+ 'd, irq: impl Peripheral

+ 'd, usb_supply: P) -> Self { + into_ref!(usb, irq); irq.set_handler(Self::on_interrupt); irq.unpend(); irq.enable(); Self { - phantom: PhantomData, + _p: usb, alloc_in: Allocator::new(), alloc_out: Allocator::new(), usb_supply, @@ -269,15 +269,15 @@ impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P> })) } - fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { + fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { ( Bus { - phantom: PhantomData, + _p: unsafe { self._p.clone_unchecked() }, power_available: false, usb_supply: self.usb_supply, }, ControlPipe { - _phantom: PhantomData, + _p: self._p, max_packet_size: control_max_packet_size, }, ) @@ -285,7 +285,7 @@ impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P> } pub struct Bus<'d, T: Instance, P: UsbSupply> { - phantom: PhantomData<&'d mut T>, + _p: PeripheralRef<'d, T>, power_available: bool, usb_supply: P, } @@ -746,7 +746,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { } pub struct ControlPipe<'d, T: Instance> { - _phantom: PhantomData<&'d mut T>, + _p: PeripheralRef<'d, T>, max_packet_size: u16, }