From 65a82d02d17fc491246eae219f416e565719c0ac Mon Sep 17 00:00:00 2001 From: Grant Miller Date: Sun, 3 Jul 2022 16:16:10 -0500 Subject: [PATCH] WIP: Make unborrow safe to use --- embassy-hal-common/src/lib.rs | 2 +- embassy-hal-common/src/macros.rs | 16 +++- embassy-hal-common/src/unborrow.rs | 79 +++++++++++++--- .../src/macros/cortex_m_interrupt_declare.rs | 7 +- embassy-nrf/src/buffered_uarte.rs | 9 +- embassy-nrf/src/gpio.rs | 32 +++++-- embassy-nrf/src/ppi/mod.rs | 6 +- embassy-nrf/src/ppi/ppi.rs | 17 +--- embassy-nrf/src/pwm.rs | 92 ++++++++----------- embassy-nrf/src/qdec.rs | 16 ++-- embassy-nrf/src/qspi.rs | 14 +-- embassy-nrf/src/rng.rs | 11 +-- embassy-nrf/src/saadc.rs | 16 +--- embassy-nrf/src/spim.rs | 27 ++---- embassy-nrf/src/temp.rs | 11 +-- embassy-nrf/src/uarte.rs | 87 +++++++----------- 16 files changed, 221 insertions(+), 221 deletions(-) diff --git a/embassy-hal-common/src/lib.rs b/embassy-hal-common/src/lib.rs index c8cf1c4c..da7ae991 100644 --- a/embassy-hal-common/src/lib.rs +++ b/embassy-hal-common/src/lib.rs @@ -9,7 +9,7 @@ mod macros; pub mod ratio; pub mod ring_buffer; mod unborrow; -pub use unborrow::Unborrow; +pub use unborrow::{Unborrow, Unborrowed}; /// Low power blocking wait loop using WFE/SEV. pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { diff --git a/embassy-hal-common/src/macros.rs b/embassy-hal-common/src/macros.rs index ffa5e4fb..d693308b 100644 --- a/embassy-hal-common/src/macros.rs +++ b/embassy-hal-common/src/macros.rs @@ -24,8 +24,11 @@ macro_rules! peripherals { unsafe impl $crate::Unborrow for $name { type Target = $name; #[inline] - unsafe fn unborrow(self) -> $name { - self + fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target> + where + Self: 'a, + { + $crate::Unborrowed::new(self) } } )* @@ -80,7 +83,7 @@ macro_rules! peripherals { macro_rules! unborrow { ($($name:ident),*) => { $( - let mut $name = unsafe { $name.unborrow() }; + let mut $name = $name.unborrow(); )* } } @@ -91,8 +94,11 @@ macro_rules! unsafe_impl_unborrow { unsafe impl $crate::Unborrow for $type { type Target = $type; #[inline] - unsafe fn unborrow(self) -> Self::Target { - self + fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target> + where + Self: 'a, + { + $crate::Unborrowed::new(self) } } }; diff --git a/embassy-hal-common/src/unborrow.rs b/embassy-hal-common/src/unborrow.rs index dacfa3d4..c05a070c 100644 --- a/embassy-hal-common/src/unborrow.rs +++ b/embassy-hal-common/src/unborrow.rs @@ -1,7 +1,45 @@ +use core::marker::PhantomData; +use core::ops::{Deref, DerefMut}; + +/// This is essentially a `&mut T`, but it is the size of `T` not the size +/// of a pointer. This is useful if T is a zero sized type. +pub struct Unborrowed<'a, T> { + inner: T, + _lifetime: PhantomData<&'a mut T>, +} + +impl<'a, T> Unborrowed<'a, T> { + pub fn new(inner: T) -> Self { + Self { + inner, + _lifetime: PhantomData, + } + } + + pub unsafe fn into_inner(self) -> T { + self.inner + } +} + +impl<'a, T> Deref for Unborrowed<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl<'a, T> DerefMut for Unborrowed<'a, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + /// Unsafely unborrow an owned singleton out of a `&mut`. /// /// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`. -/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T. +/// Unborrowing an owned `T` yields an `Unborrowed<'static, T>`. +/// Unborrowing a `&'a mut T` yields an `Unborrowed<'a, T>`. /// /// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have /// to store pointers in the borrowed case. @@ -15,17 +53,33 @@ pub unsafe trait Unborrow { type Target; /// Unborrow a value. - /// - /// Safety: This returns a copy of a singleton that's normally not - /// copiable. The returned copy must ONLY be used while the lifetime of `self` is - /// valid, as if it were accessed through `self` every time. - unsafe fn unborrow(self) -> Self::Target; + fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target> + where + Self: 'a; } -unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T { +unsafe impl<'b, T: Unborrow> Unborrow for &'b mut T { type Target = T::Target; - unsafe fn unborrow(self) -> Self::Target { - T::unborrow(core::ptr::read(self)) + + fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target> + where + Self: 'a, + { + // Safety: This returns a copy of a singleton that's normally not + // copiable. The returned copy must ONLY be used while the lifetime of `self` is + // valid, as if it were accessed through `self` every time. + T::unborrow(unsafe { core::ptr::read(self) }) + } +} + +unsafe impl<'b, T> Unborrow for Unborrowed<'b, T> { + type Target = T; + + fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target> + where + Self: 'a, + { + self } } @@ -38,8 +92,11 @@ macro_rules! unsafe_impl_unborrow_tuples { ),+ { type Target = ($($t),+); - unsafe fn unborrow(self) -> Self::Target { - self + fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target> + where + Self: 'a + { + Unborrowed::new(self) } } diff --git a/embassy-macros/src/macros/cortex_m_interrupt_declare.rs b/embassy-macros/src/macros/cortex_m_interrupt_declare.rs index eeed5d48..9d1e4af5 100644 --- a/embassy-macros/src/macros/cortex_m_interrupt_declare.rs +++ b/embassy-macros/src/macros/cortex_m_interrupt_declare.rs @@ -27,8 +27,11 @@ pub fn run(name: syn::Ident) -> Result { unsafe impl ::embassy_hal_common::Unborrow for #name_interrupt { type Target = #name_interrupt; - unsafe fn unborrow(self) -> #name_interrupt { - self + fn unborrow<'a>(self) -> ::embassy_hal_common::Unborrowed<'a, #name_interrupt> + where + Self: 'a + { + ::embassy_hal_common::Unborrowed::new(self) } } }; diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 4fc78b95..d251ce34 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -147,7 +147,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { timer.cc(0).short_compare_stop(); let mut ppi_ch1 = Ppi::new_one_to_two( - ppi_ch1.degrade(), + //TODO: Avoid into_inner? + unsafe { ppi_ch1.into_inner() }.degrade(), Event::from_reg(&r.events_rxdrdy), timer.task_clear(), timer.task_start(), @@ -155,14 +156,16 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { ppi_ch1.enable(); let mut ppi_ch2 = Ppi::new_one_to_one( - ppi_ch2.degrade(), + //TODO: Avoid into_inner? + unsafe { ppi_ch2.into_inner() }.degrade(), timer.cc(0).event_compare(), Task::from_reg(&r.tasks_stoprx), ); ppi_ch2.enable(); Self { - inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner { + //TODO: Avoid into_inner? + inner: PeripheralMutex::new(unsafe { irq.into_inner() }, &mut state.0, move || StateInner { phantom: PhantomData, timer, _ppi_ch1: ppi_ch1, diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index fd4ae2ec..e5764f8a 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs @@ -2,10 +2,9 @@ use core::convert::Infallible; use core::hint::unreachable_unchecked; -use core::marker::PhantomData; use cfg_if::cfg_if; -use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; +use embassy_hal_common::{unborrow, unsafe_impl_unborrow, Unborrowed}; use self::sealed::Pin as _; use crate::pac::p0 as gpio; @@ -194,8 +193,7 @@ fn convert_pull(pull: Pull) -> PULL_A { /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output /// mode. pub struct Flex<'d, T: Pin> { - pub(crate) pin: T, - phantom: PhantomData<&'d mut T>, + pub(crate) pin: Unborrowed<'d, T>, } impl<'d, T: Pin> Flex<'d, T> { @@ -207,10 +205,7 @@ impl<'d, T: Pin> Flex<'d, T> { pub fn new(pin: impl Unborrow + 'd) -> Self { unborrow!(pin); // Pin will be in disconnected state. - Self { - pin, - phantom: PhantomData, - } + Self { pin } } /// Put the pin into input mode. @@ -421,6 +416,20 @@ impl AnyPin { pub unsafe fn steal(pin_port: u8) -> Self { Self { pin_port } } + + pub fn unborrow_and_degrade<'a>(pin: impl Unborrow + 'a) -> Unborrowed<'a, Self> { + Unborrowed::new(AnyPin { + pin_port: pin.unborrow().pin_port(), + }) + } +} + +macro_rules! unborrow_and_degrade { + ($($name:ident),*) => { + $( + let $name = $crate::gpio::AnyPin::unborrow_and_degrade($name); + )* + }; } unsafe_impl_unborrow!(AnyPin); @@ -438,10 +447,13 @@ pub(crate) trait PselBits { fn psel_bits(&self) -> u32; } -impl PselBits for Option { +impl<'a, P: Pin> PselBits for Option> { #[inline] fn psel_bits(&self) -> u32 { - self.as_ref().map_or(1u32 << 31, Pin::psel_bits) + match self { + Some(pin) => pin.psel_bits(), + None => 1u32 << 31, + } } } diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index 660db641..fd5bb5f7 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs @@ -15,10 +15,9 @@ //! many tasks and events, but any single task or event can only be coupled with one channel. //! -use core::marker::PhantomData; use core::ptr::NonNull; -use embassy_hal_common::unsafe_impl_unborrow; +use embassy_hal_common::{unsafe_impl_unborrow, Unborrowed}; use crate::{peripherals, Unborrow}; @@ -28,12 +27,11 @@ mod dppi; mod ppi; pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { - ch: C, + ch: Unborrowed<'d, C>, #[cfg(feature = "_dppi")] events: [Event; EVENT_COUNT], #[cfg(feature = "_dppi")] tasks: [Task; TASK_COUNT], - phantom: PhantomData<&'d mut C>, } const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::(); diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index e5c86d44..3b8f44da 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs @@ -1,5 +1,3 @@ -use core::marker::PhantomData; - use embassy_hal_common::unborrow; use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task}; @@ -29,10 +27,7 @@ impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> { let n = ch.number(); r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); - Self { - ch, - phantom: PhantomData, - } + Self { ch } } } @@ -45,10 +40,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) }); r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); - Self { - ch, - phantom: PhantomData, - } + Self { ch } } } @@ -63,10 +55,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) }); r.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) }); - Self { - ch, - phantom: PhantomData, - } + Self { ch } } } diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 9a78ff1f..050461ea 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs @@ -3,7 +3,7 @@ use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; -use embassy_hal_common::unborrow; +use embassy_hal_common::Unborrowed; use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; @@ -17,20 +17,20 @@ use crate::{pac, Unborrow}; pub struct SimplePwm<'d, T: Instance> { phantom: PhantomData<&'d mut T>, duty: [u16; 4], - ch0: Option, - ch1: Option, - ch2: Option, - ch3: Option, + ch0: Option>, + ch1: Option>, + ch2: Option>, + ch3: Option>, } /// 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>, - ch0: Option, - ch1: Option, - ch2: Option, - ch3: Option, + ch0: Option>, + ch1: Option>, + ch2: Option>, + ch3: Option>, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -55,8 +55,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> { ch0: impl Unborrow + 'd, config: Config, ) -> Result { - unborrow!(ch0); - Self::new_inner(pwm, Some(ch0.degrade()), None, None, None, config) + unborrow_and_degrade!(ch0); + Self::new_inner(pwm, Some(ch0), None, None, None, config) } /// Create a new 2-channel PWM @@ -67,8 +67,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> { ch1: impl Unborrow + 'd, config: Config, ) -> Result { - unborrow!(ch0, ch1); - Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None, config) + unborrow_and_degrade!(ch0, ch1); + Self::new_inner(pwm, Some(ch0), Some(ch1), None, None, config) } /// Create a new 3-channel PWM @@ -80,15 +80,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> { ch2: impl Unborrow + 'd, config: Config, ) -> Result { - unborrow!(ch0, ch1, ch2); - Self::new_inner( - pwm, - Some(ch0.degrade()), - Some(ch1.degrade()), - Some(ch2.degrade()), - None, - config, - ) + unborrow_and_degrade!(ch0, ch1, ch2); + Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), None, config) } /// Create a new 4-channel PWM @@ -101,23 +94,16 @@ impl<'d, T: Instance> SequencePwm<'d, T> { ch3: impl Unborrow + 'd, config: Config, ) -> Result { - unborrow!(ch0, ch1, ch2, ch3); - Self::new_inner( - pwm, - Some(ch0.degrade()), - Some(ch1.degrade()), - Some(ch2.degrade()), - Some(ch3.degrade()), - config, - ) + unborrow_and_degrade!(ch0, ch1, ch2, ch3); + Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), Some(ch3), config) } fn new_inner( _pwm: impl Unborrow + 'd, - ch0: Option, - ch1: Option, - ch2: Option, - ch3: Option, + ch0: Option>, + ch1: Option>, + ch2: Option>, + ch3: Option>, config: Config, ) -> Result { let r = T::regs(); @@ -574,8 +560,10 @@ impl<'d, T: Instance> SimplePwm<'d, T> { /// Create a new 1-channel PWM #[allow(unused_unsafe)] pub fn new_1ch(pwm: impl Unborrow + 'd, ch0: impl Unborrow + 'd) -> Self { - unborrow!(ch0); - Self::new_inner(pwm, Some(ch0.degrade()), None, None, None) + unsafe { + unborrow_and_degrade!(ch0); + Self::new_inner(pwm, Some(ch0), None, None, None) + } } /// Create a new 2-channel PWM @@ -585,8 +573,8 @@ impl<'d, T: Instance> SimplePwm<'d, T> { ch0: impl Unborrow + 'd, ch1: impl Unborrow + 'd, ) -> Self { - unborrow!(ch0, ch1); - Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None) + unborrow_and_degrade!(ch0, ch1); + Self::new_inner(pwm, Some(ch0), Some(ch1), None, None) } /// Create a new 3-channel PWM @@ -597,8 +585,10 @@ impl<'d, T: Instance> SimplePwm<'d, T> { ch1: impl Unborrow + 'd, ch2: impl Unborrow + 'd, ) -> Self { - unborrow!(ch0, ch1, ch2); - Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), Some(ch2.degrade()), None) + unsafe { + unborrow_and_degrade!(ch0, ch1, ch2); + Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), None) + } } /// Create a new 4-channel PWM @@ -610,22 +600,18 @@ impl<'d, T: Instance> SimplePwm<'d, T> { ch2: impl Unborrow + 'd, ch3: impl Unborrow + 'd, ) -> Self { - unborrow!(ch0, ch1, ch2, ch3); - Self::new_inner( - pwm, - Some(ch0.degrade()), - Some(ch1.degrade()), - Some(ch2.degrade()), - Some(ch3.degrade()), - ) + unsafe { + unborrow_and_degrade!(ch0, ch1, ch2, ch3); + Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), Some(ch3)) + } } fn new_inner( _pwm: impl Unborrow + 'd, - ch0: Option, - ch1: Option, - ch2: Option, - ch3: Option, + ch0: Option>, + ch1: Option>, + ch2: Option>, + ch3: Option>, ) -> Self { let r = T::regs(); diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs index e254328a..da4f1260 100644 --- a/embassy-nrf/src/qdec.rs +++ b/embassy-nrf/src/qdec.rs @@ -4,7 +4,7 @@ use core::marker::PhantomData; use core::task::Poll; use embassy::waitqueue::AtomicWaker; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use futures::future::poll_fn; use crate::gpio::sealed::Pin as _; @@ -49,8 +49,8 @@ impl<'d> Qdec<'d> { b: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(a, b); - Self::new_inner(qdec, irq, a.degrade(), b.degrade(), None, config) + unborrow_and_degrade!(a, b); + Self::new_inner(qdec, irq, a, b, None, config) } pub fn new_with_led( @@ -61,16 +61,16 @@ impl<'d> Qdec<'d> { led: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(a, b, led); - Self::new_inner(qdec, irq, a.degrade(), b.degrade(), Some(led.degrade()), config) + unborrow_and_degrade!(a, b, led); + Self::new_inner(qdec, irq, a, b, Some(led), config) } fn new_inner( _t: impl Unborrow + 'd, irq: impl Unborrow + 'd, - a: AnyPin, - b: AnyPin, - led: Option, + a: Unborrowed<'d, AnyPin>, + b: Unborrowed<'d, AnyPin>, + led: Option>, config: Config, ) -> Self { unborrow!(irq); diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs index 92fa79b8..2b987b46 100644 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.rs @@ -1,11 +1,10 @@ #![macro_use] -use core::marker::PhantomData; use core::ptr; use core::task::Poll; use embassy_hal_common::drop::DropBomb; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use futures::future::poll_fn; use crate::gpio::sealed::Pin as _; @@ -63,9 +62,8 @@ pub enum Error { } pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> { - irq: T::Interrupt, + irq: Unborrowed<'d, T::Interrupt>, dpm_enabled: bool, - phantom: PhantomData<&'d mut T>, } impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> { @@ -84,12 +82,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> { let r = T::regs(); - let sck = sck.degrade(); - let csn = csn.degrade(); - let io0 = io0.degrade(); - let io1 = io1.degrade(); - let io2 = io2.degrade(); - let io3 = io3.degrade(); + unborrow_and_degrade!(sck, csn, io0, io1, io2, io3); for pin in [&sck, &csn, &io0, &io1, &io2, &io3] { pin.set_high(); @@ -143,7 +136,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> { let mut res = Self { dpm_enabled: config.deep_power_down.is_some(), irq, - phantom: PhantomData, }; r.events_ready.reset(); diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs index e68ed912..111a5424 100644 --- a/embassy-nrf/src/rng.rs +++ b/embassy-nrf/src/rng.rs @@ -1,11 +1,10 @@ -use core::marker::PhantomData; use core::ptr; use core::sync::atomic::{AtomicPtr, Ordering}; use core::task::Poll; use embassy::waitqueue::AtomicWaker; use embassy_hal_common::drop::OnDrop; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use futures::future::poll_fn; use crate::interrupt::InterruptExt; @@ -34,8 +33,7 @@ struct State { /// /// It has a non-blocking API, and a blocking api through `rand`. pub struct Rng<'d> { - irq: interrupt::RNG, - phantom: PhantomData<(&'d mut RNG, &'d mut interrupt::RNG)>, + irq: Unborrowed<'d, interrupt::RNG>, } impl<'d> Rng<'d> { @@ -48,10 +46,7 @@ impl<'d> Rng<'d> { pub fn new(_rng: impl Unborrow + 'd, irq: impl Unborrow + 'd) -> Self { unborrow!(irq); - let this = Self { - irq, - phantom: PhantomData, - }; + let this = Self { irq }; this.stop(); this.disable_irq(); diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index af1aa881..d7d59b62 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -5,7 +5,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy::waitqueue::AtomicWaker; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; use futures::future::poll_fn; use pac::{saadc, SAADC}; use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; @@ -77,12 +77,7 @@ pub struct ChannelConfig<'d> { /// internal voltage. pub struct VddInput; -unsafe impl Unborrow for VddInput { - type Target = VddInput; - unsafe fn unborrow(self) -> Self::Target { - self - } -} +unsafe_impl_unborrow!(VddInput); impl sealed::Input for VddInput { #[cfg(not(feature = "_nrf9160"))] @@ -102,12 +97,7 @@ impl Input for VddInput {} pub struct VddhDiv5Input; #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] -unsafe impl Unborrow for VddhDiv5Input { - type Target = VddhDiv5Input; - unsafe fn unborrow(self) -> Self::Target { - self - } -} +unsafe_impl_unborrow!(VddhDiv5Input); #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] impl sealed::Input for VddhDiv5Input { diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index d34d9a0c..889d04dc 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -5,7 +5,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_embedded_hal::SetConfig; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; use futures::future::poll_fn; pub use pac::spim0::frequency::FREQUENCY_A as Frequency; @@ -60,15 +60,8 @@ impl<'d, T: Instance> Spim<'d, T> { mosi: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(sck, miso, mosi); - Self::new_inner( - spim, - irq, - sck.degrade(), - Some(miso.degrade()), - Some(mosi.degrade()), - config, - ) + unborrow_and_degrade!(sck, miso, mosi); + Self::new_inner(spim, irq, sck, Some(miso), Some(mosi), config) } pub fn new_txonly( @@ -78,8 +71,8 @@ impl<'d, T: Instance> Spim<'d, T> { mosi: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(sck, mosi); - Self::new_inner(spim, irq, sck.degrade(), None, Some(mosi.degrade()), config) + unborrow_and_degrade!(sck, mosi); + Self::new_inner(spim, irq, sck, None, Some(mosi), config) } pub fn new_rxonly( @@ -89,16 +82,16 @@ impl<'d, T: Instance> Spim<'d, T> { miso: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(sck, miso); - Self::new_inner(spim, irq, sck.degrade(), Some(miso.degrade()), None, config) + unborrow_and_degrade!(sck, miso); + Self::new_inner(spim, irq, sck, Some(miso), None, config) } fn new_inner( _spim: impl Unborrow + 'd, irq: impl Unborrow + 'd, - sck: AnyPin, - miso: Option, - mosi: Option, + sck: Unborrowed<'d, AnyPin>, + miso: Option>, + mosi: Option>, config: Config, ) -> Self { unborrow!(irq); diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs index 43ba3e04..0bb82a49 100644 --- a/embassy-nrf/src/temp.rs +++ b/embassy-nrf/src/temp.rs @@ -1,11 +1,10 @@ //! Temperature sensor interface. -use core::marker::PhantomData; use core::task::Poll; use embassy::waitqueue::AtomicWaker; use embassy_hal_common::drop::OnDrop; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use fixed::types::I30F2; use futures::future::poll_fn; @@ -15,8 +14,7 @@ use crate::{interrupt, pac, Unborrow}; /// Integrated temperature sensor. pub struct Temp<'d> { - _temp: PhantomData<&'d TEMP>, - _irq: interrupt::TEMP, + _irq: Unborrowed<'d, interrupt::TEMP>, } static WAKER: AtomicWaker = AtomicWaker::new(); @@ -33,10 +31,7 @@ impl<'d> Temp<'d> { WAKER.wake(); }); irq.enable(); - Self { - _temp: PhantomData, - _irq: irq, - } + Self { _irq: irq } } /// Perform an asynchronous temperature measurement. The returned future diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 459c56c8..d5ffb315 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -18,7 +18,7 @@ use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy_hal_common::drop::OnDrop; -use embassy_hal_common::unborrow; +use embassy_hal_common::{unborrow, Unborrowed}; use futures::future::poll_fn; use pac::uarte0::RegisterBlock; // Re-export SVD variants to allow user to directly set values. @@ -89,8 +89,8 @@ impl<'d, T: Instance> Uarte<'d, T> { txd: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(rxd, txd); - Self::new_inner(uarte, irq, rxd.degrade(), txd.degrade(), None, None, config) + unborrow_and_degrade!(rxd, txd); + Self::new_inner(uarte, irq, rxd, txd, None, None, config) } /// Create a new UARTE with hardware flow control (RTS/CTS) @@ -103,25 +103,17 @@ impl<'d, T: Instance> Uarte<'d, T> { rts: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(rxd, txd, cts, rts); - Self::new_inner( - uarte, - irq, - rxd.degrade(), - txd.degrade(), - Some(cts.degrade()), - Some(rts.degrade()), - config, - ) + unborrow_and_degrade!(rxd, txd, cts, rts); + Self::new_inner(uarte, irq, rxd, txd, Some(cts), Some(rts), config) } fn new_inner( _uarte: impl Unborrow + 'd, irq: impl Unborrow + 'd, - rxd: AnyPin, - txd: AnyPin, - cts: Option, - rts: Option, + rxd: Unborrowed<'d, AnyPin>, + txd: Unborrowed<'d, AnyPin>, + cts: Option>, + rts: Option>, config: Config, ) -> Self { unborrow!(irq); @@ -250,8 +242,8 @@ impl<'d, T: Instance> UarteTx<'d, T> { txd: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(txd); - Self::new_inner(uarte, irq, txd.degrade(), None, config) + unborrow_and_degrade!(txd); + Self::new_inner(uarte, irq, txd, None, config) } /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) @@ -262,15 +254,15 @@ impl<'d, T: Instance> UarteTx<'d, T> { cts: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(txd, cts); - Self::new_inner(uarte, irq, txd.degrade(), Some(cts.degrade()), config) + unborrow_and_degrade!(txd, cts); + Self::new_inner(uarte, irq, txd, Some(cts), config) } fn new_inner( _uarte: impl Unborrow + 'd, irq: impl Unborrow + 'd, - txd: AnyPin, - cts: Option, + txd: Unborrowed<'d, AnyPin>, + cts: Option>, config: Config, ) -> Self { unborrow!(irq); @@ -442,8 +434,8 @@ impl<'d, T: Instance> UarteRx<'d, T> { rxd: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(rxd); - Self::new_inner(uarte, irq, rxd.degrade(), None, config) + unborrow_and_degrade!(rxd); + Self::new_inner(uarte, irq, rxd, None, config) } /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) @@ -454,15 +446,15 @@ impl<'d, T: Instance> UarteRx<'d, T> { rts: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(rxd, rts); - Self::new_inner(uarte, irq, rxd.degrade(), Some(rts.degrade()), config) + unborrow_and_degrade!(rxd, rts); + Self::new_inner(uarte, irq, rxd, Some(rts), config) } fn new_inner( _uarte: impl Unborrow + 'd, irq: impl Unborrow + 'd, - rxd: AnyPin, - rts: Option, + rxd: Unborrowed<'d, AnyPin>, + rts: Option>, config: Config, ) -> Self { unborrow!(irq); @@ -685,19 +677,8 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { txd: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(rxd, txd); - Self::new_inner( - uarte, - timer, - ppi_ch1, - ppi_ch2, - irq, - rxd.degrade(), - txd.degrade(), - None, - None, - config, - ) + unborrow_and_degrade!(rxd, txd); + Self::new_inner(uarte, timer, ppi_ch1, ppi_ch2, irq, rxd, txd, None, None, config) } /// Create a new UARTE with hardware flow control (RTS/CTS) @@ -713,17 +694,17 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { rts: impl Unborrow + 'd, config: Config, ) -> Self { - unborrow!(rxd, txd, cts, rts); + unborrow_and_degrade!(rxd, txd, cts, rts); Self::new_inner( uarte, timer, ppi_ch1, ppi_ch2, irq, - rxd.degrade(), - txd.degrade(), - Some(cts.degrade()), - Some(rts.degrade()), + rxd, + txd, + Some(cts), + Some(rts), config, ) } @@ -734,10 +715,10 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { ppi_ch1: impl Unborrow + 'd, ppi_ch2: impl Unborrow + 'd, irq: impl Unborrow + 'd, - rxd: AnyPin, - txd: AnyPin, - cts: Option, - rts: Option, + rxd: Unborrowed<'d, AnyPin>, + txd: Unborrowed<'d, AnyPin>, + cts: Option>, + rts: Option>, config: Config, ) -> Self { let baudrate = config.baudrate; @@ -763,7 +744,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { timer.cc(0).short_compare_stop(); let mut ppi_ch1 = Ppi::new_one_to_two( - ppi_ch1.degrade(), + unsafe { ppi_ch1.into_inner() }.degrade(), Event::from_reg(&r.events_rxdrdy), timer.task_clear(), timer.task_start(), @@ -771,7 +752,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { ppi_ch1.enable(); let mut ppi_ch2 = Ppi::new_one_to_one( - ppi_ch2.degrade(), + unsafe { ppi_ch2.into_inner() }.degrade(), timer.cc(0).event_compare(), Task::from_reg(&r.tasks_stoprx), );