aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Miller <[email protected]>2022-07-03 16:16:10 -0500
committerDario Nieuwenhuis <[email protected]>2022-07-23 01:33:22 +0200
commit65a82d02d17fc491246eae219f416e565719c0ac (patch)
tree1d4842d73031529f018d6b96a84c090e0fb3eb82
parentffbd9363f2a52fd27c81bbfbbe8e0e605a1ece86 (diff)
WIP: Make unborrow safe to use
-rw-r--r--embassy-hal-common/src/lib.rs2
-rw-r--r--embassy-hal-common/src/macros.rs16
-rw-r--r--embassy-hal-common/src/unborrow.rs79
-rw-r--r--embassy-macros/src/macros/cortex_m_interrupt_declare.rs7
-rw-r--r--embassy-nrf/src/buffered_uarte.rs9
-rw-r--r--embassy-nrf/src/gpio.rs32
-rw-r--r--embassy-nrf/src/ppi/mod.rs6
-rw-r--r--embassy-nrf/src/ppi/ppi.rs17
-rw-r--r--embassy-nrf/src/pwm.rs92
-rw-r--r--embassy-nrf/src/qdec.rs16
-rw-r--r--embassy-nrf/src/qspi.rs14
-rw-r--r--embassy-nrf/src/rng.rs11
-rw-r--r--embassy-nrf/src/saadc.rs16
-rw-r--r--embassy-nrf/src/spim.rs27
-rw-r--r--embassy-nrf/src/temp.rs11
-rw-r--r--embassy-nrf/src/uarte.rs87
16 files changed, 221 insertions, 221 deletions
diff --git a/embassy-hal-common/src/lib.rs b/embassy-hal-common/src/lib.rs
index c8cf1c4cd..da7ae9919 100644
--- a/embassy-hal-common/src/lib.rs
+++ b/embassy-hal-common/src/lib.rs
@@ -9,7 +9,7 @@ mod macros;
9pub mod ratio; 9pub mod ratio;
10pub mod ring_buffer; 10pub mod ring_buffer;
11mod unborrow; 11mod unborrow;
12pub use unborrow::Unborrow; 12pub use unborrow::{Unborrow, Unborrowed};
13 13
14/// Low power blocking wait loop using WFE/SEV. 14/// Low power blocking wait loop using WFE/SEV.
15pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { 15pub 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 ffa5e4fb6..d693308be 100644
--- a/embassy-hal-common/src/macros.rs
+++ b/embassy-hal-common/src/macros.rs
@@ -24,8 +24,11 @@ macro_rules! peripherals {
24 unsafe impl $crate::Unborrow for $name { 24 unsafe impl $crate::Unborrow for $name {
25 type Target = $name; 25 type Target = $name;
26 #[inline] 26 #[inline]
27 unsafe fn unborrow(self) -> $name { 27 fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target>
28 self 28 where
29 Self: 'a,
30 {
31 $crate::Unborrowed::new(self)
29 } 32 }
30 } 33 }
31 )* 34 )*
@@ -80,7 +83,7 @@ macro_rules! peripherals {
80macro_rules! unborrow { 83macro_rules! unborrow {
81 ($($name:ident),*) => { 84 ($($name:ident),*) => {
82 $( 85 $(
83 let mut $name = unsafe { $name.unborrow() }; 86 let mut $name = $name.unborrow();
84 )* 87 )*
85 } 88 }
86} 89}
@@ -91,8 +94,11 @@ macro_rules! unsafe_impl_unborrow {
91 unsafe impl $crate::Unborrow for $type { 94 unsafe impl $crate::Unborrow for $type {
92 type Target = $type; 95 type Target = $type;
93 #[inline] 96 #[inline]
94 unsafe fn unborrow(self) -> Self::Target { 97 fn unborrow<'a>(self) -> $crate::Unborrowed<'a, Self::Target>
95 self 98 where
99 Self: 'a,
100 {
101 $crate::Unborrowed::new(self)
96 } 102 }
97 } 103 }
98 }; 104 };
diff --git a/embassy-hal-common/src/unborrow.rs b/embassy-hal-common/src/unborrow.rs
index dacfa3d42..c05a070c9 100644
--- a/embassy-hal-common/src/unborrow.rs
+++ b/embassy-hal-common/src/unborrow.rs
@@ -1,7 +1,45 @@
1use core::marker::PhantomData;
2use core::ops::{Deref, DerefMut};
3
4/// This is essentially a `&mut T`, but it is the size of `T` not the size
5/// of a pointer. This is useful if T is a zero sized type.
6pub struct Unborrowed<'a, T> {
7 inner: T,
8 _lifetime: PhantomData<&'a mut T>,
9}
10
11impl<'a, T> Unborrowed<'a, T> {
12 pub fn new(inner: T) -> Self {
13 Self {
14 inner,
15 _lifetime: PhantomData,
16 }
17 }
18
19 pub unsafe fn into_inner(self) -> T {
20 self.inner
21 }
22}
23
24impl<'a, T> Deref for Unborrowed<'a, T> {
25 type Target = T;
26
27 fn deref(&self) -> &Self::Target {
28 &self.inner
29 }
30}
31
32impl<'a, T> DerefMut for Unborrowed<'a, T> {
33 fn deref_mut(&mut self) -> &mut Self::Target {
34 &mut self.inner
35 }
36}
37
1/// Unsafely unborrow an owned singleton out of a `&mut`. 38/// Unsafely unborrow an owned singleton out of a `&mut`.
2/// 39///
3/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`. 40/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
4/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T. 41/// Unborrowing an owned `T` yields an `Unborrowed<'static, T>`.
42/// Unborrowing a `&'a mut T` yields an `Unborrowed<'a, T>`.
5/// 43///
6/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have 44/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
7/// to store pointers in the borrowed case. 45/// to store pointers in the borrowed case.
@@ -15,17 +53,33 @@ pub unsafe trait Unborrow {
15 type Target; 53 type Target;
16 54
17 /// Unborrow a value. 55 /// Unborrow a value.
18 /// 56 fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
19 /// Safety: This returns a copy of a singleton that's normally not 57 where
20 /// copiable. The returned copy must ONLY be used while the lifetime of `self` is 58 Self: 'a;
21 /// valid, as if it were accessed through `self` every time.
22 unsafe fn unborrow(self) -> Self::Target;
23} 59}
24 60
25unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T { 61unsafe impl<'b, T: Unborrow> Unborrow for &'b mut T {
26 type Target = T::Target; 62 type Target = T::Target;
27 unsafe fn unborrow(self) -> Self::Target { 63
28 T::unborrow(core::ptr::read(self)) 64 fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
65 where
66 Self: 'a,
67 {
68 // Safety: This returns a copy of a singleton that's normally not
69 // copiable. The returned copy must ONLY be used while the lifetime of `self` is
70 // valid, as if it were accessed through `self` every time.
71 T::unborrow(unsafe { core::ptr::read(self) })
72 }
73}
74
75unsafe impl<'b, T> Unborrow for Unborrowed<'b, T> {
76 type Target = T;
77
78 fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
79 where
80 Self: 'a,
81 {
82 self
29 } 83 }
30} 84}
31 85
@@ -38,8 +92,11 @@ macro_rules! unsafe_impl_unborrow_tuples {
38 ),+ 92 ),+
39 { 93 {
40 type Target = ($($t),+); 94 type Target = ($($t),+);
41 unsafe fn unborrow(self) -> Self::Target { 95 fn unborrow<'a>(self) -> Unborrowed<'a, Self::Target>
42 self 96 where
97 Self: 'a
98 {
99 Unborrowed::new(self)
43 } 100 }
44 } 101 }
45 102
diff --git a/embassy-macros/src/macros/cortex_m_interrupt_declare.rs b/embassy-macros/src/macros/cortex_m_interrupt_declare.rs
index eeed5d483..9d1e4af54 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<TokenStream, TokenStream> {
27 27
28 unsafe impl ::embassy_hal_common::Unborrow for #name_interrupt { 28 unsafe impl ::embassy_hal_common::Unborrow for #name_interrupt {
29 type Target = #name_interrupt; 29 type Target = #name_interrupt;
30 unsafe fn unborrow(self) -> #name_interrupt { 30 fn unborrow<'a>(self) -> ::embassy_hal_common::Unborrowed<'a, #name_interrupt>
31 self 31 where
32 Self: 'a
33 {
34 ::embassy_hal_common::Unborrowed::new(self)
32 } 35 }
33 } 36 }
34 }; 37 };
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 4fc78b95d..d251ce347 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> {
147 timer.cc(0).short_compare_stop(); 147 timer.cc(0).short_compare_stop();
148 148
149 let mut ppi_ch1 = Ppi::new_one_to_two( 149 let mut ppi_ch1 = Ppi::new_one_to_two(
150 ppi_ch1.degrade(), 150 //TODO: Avoid into_inner?
151 unsafe { ppi_ch1.into_inner() }.degrade(),
151 Event::from_reg(&r.events_rxdrdy), 152 Event::from_reg(&r.events_rxdrdy),
152 timer.task_clear(), 153 timer.task_clear(),
153 timer.task_start(), 154 timer.task_start(),
@@ -155,14 +156,16 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
155 ppi_ch1.enable(); 156 ppi_ch1.enable();
156 157
157 let mut ppi_ch2 = Ppi::new_one_to_one( 158 let mut ppi_ch2 = Ppi::new_one_to_one(
158 ppi_ch2.degrade(), 159 //TODO: Avoid into_inner?
160 unsafe { ppi_ch2.into_inner() }.degrade(),
159 timer.cc(0).event_compare(), 161 timer.cc(0).event_compare(),
160 Task::from_reg(&r.tasks_stoprx), 162 Task::from_reg(&r.tasks_stoprx),
161 ); 163 );
162 ppi_ch2.enable(); 164 ppi_ch2.enable();
163 165
164 Self { 166 Self {
165 inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner { 167 //TODO: Avoid into_inner?
168 inner: PeripheralMutex::new(unsafe { irq.into_inner() }, &mut state.0, move || StateInner {
166 phantom: PhantomData, 169 phantom: PhantomData,
167 timer, 170 timer,
168 _ppi_ch1: ppi_ch1, 171 _ppi_ch1: ppi_ch1,
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index fd4ae2ec3..e5764f8a0 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -2,10 +2,9 @@
2 2
3use core::convert::Infallible; 3use core::convert::Infallible;
4use core::hint::unreachable_unchecked; 4use core::hint::unreachable_unchecked;
5use core::marker::PhantomData;
6 5
7use cfg_if::cfg_if; 6use cfg_if::cfg_if;
8use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; 7use embassy_hal_common::{unborrow, unsafe_impl_unborrow, Unborrowed};
9 8
10use self::sealed::Pin as _; 9use self::sealed::Pin as _;
11use crate::pac::p0 as gpio; 10use crate::pac::p0 as gpio;
@@ -194,8 +193,7 @@ fn convert_pull(pull: Pull) -> PULL_A {
194/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output 193/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
195/// mode. 194/// mode.
196pub struct Flex<'d, T: Pin> { 195pub struct Flex<'d, T: Pin> {
197 pub(crate) pin: T, 196 pub(crate) pin: Unborrowed<'d, T>,
198 phantom: PhantomData<&'d mut T>,
199} 197}
200 198
201impl<'d, T: Pin> Flex<'d, T> { 199impl<'d, T: Pin> Flex<'d, T> {
@@ -207,10 +205,7 @@ impl<'d, T: Pin> Flex<'d, T> {
207 pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self { 205 pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self {
208 unborrow!(pin); 206 unborrow!(pin);
209 // Pin will be in disconnected state. 207 // Pin will be in disconnected state.
210 Self { 208 Self { pin }
211 pin,
212 phantom: PhantomData,
213 }
214 } 209 }
215 210
216 /// Put the pin into input mode. 211 /// Put the pin into input mode.
@@ -421,6 +416,20 @@ impl AnyPin {
421 pub unsafe fn steal(pin_port: u8) -> Self { 416 pub unsafe fn steal(pin_port: u8) -> Self {
422 Self { pin_port } 417 Self { pin_port }
423 } 418 }
419
420 pub fn unborrow_and_degrade<'a>(pin: impl Unborrow<Target = impl Pin + 'a> + 'a) -> Unborrowed<'a, Self> {
421 Unborrowed::new(AnyPin {
422 pin_port: pin.unborrow().pin_port(),
423 })
424 }
425}
426
427macro_rules! unborrow_and_degrade {
428 ($($name:ident),*) => {
429 $(
430 let $name = $crate::gpio::AnyPin::unborrow_and_degrade($name);
431 )*
432 };
424} 433}
425 434
426unsafe_impl_unborrow!(AnyPin); 435unsafe_impl_unborrow!(AnyPin);
@@ -438,10 +447,13 @@ pub(crate) trait PselBits {
438 fn psel_bits(&self) -> u32; 447 fn psel_bits(&self) -> u32;
439} 448}
440 449
441impl PselBits for Option<AnyPin> { 450impl<'a, P: Pin> PselBits for Option<Unborrowed<'a, P>> {
442 #[inline] 451 #[inline]
443 fn psel_bits(&self) -> u32 { 452 fn psel_bits(&self) -> u32 {
444 self.as_ref().map_or(1u32 << 31, Pin::psel_bits) 453 match self {
454 Some(pin) => pin.psel_bits(),
455 None => 1u32 << 31,
456 }
445 } 457 }
446} 458}
447 459
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs
index 660db6410..fd5bb5f77 100644
--- a/embassy-nrf/src/ppi/mod.rs
+++ b/embassy-nrf/src/ppi/mod.rs
@@ -15,10 +15,9 @@
15//! many tasks and events, but any single task or event can only be coupled with one channel. 15//! many tasks and events, but any single task or event can only be coupled with one channel.
16//! 16//!
17 17
18use core::marker::PhantomData;
19use core::ptr::NonNull; 18use core::ptr::NonNull;
20 19
21use embassy_hal_common::unsafe_impl_unborrow; 20use embassy_hal_common::{unsafe_impl_unborrow, Unborrowed};
22 21
23use crate::{peripherals, Unborrow}; 22use crate::{peripherals, Unborrow};
24 23
@@ -28,12 +27,11 @@ mod dppi;
28mod ppi; 27mod ppi;
29 28
30pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> { 29pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
31 ch: C, 30 ch: Unborrowed<'d, C>,
32 #[cfg(feature = "_dppi")] 31 #[cfg(feature = "_dppi")]
33 events: [Event; EVENT_COUNT], 32 events: [Event; EVENT_COUNT],
34 #[cfg(feature = "_dppi")] 33 #[cfg(feature = "_dppi")]
35 tasks: [Task; TASK_COUNT], 34 tasks: [Task; TASK_COUNT],
36 phantom: PhantomData<&'d mut C>,
37} 35}
38 36
39const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>(); 37const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>();
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs
index e5c86d444..3b8f44da8 100644
--- a/embassy-nrf/src/ppi/ppi.rs
+++ b/embassy-nrf/src/ppi/ppi.rs
@@ -1,5 +1,3 @@
1use core::marker::PhantomData;
2
3use embassy_hal_common::unborrow; 1use embassy_hal_common::unborrow;
4 2
5use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task}; 3use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};
@@ -29,10 +27,7 @@ impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
29 let n = ch.number(); 27 let n = ch.number();
30 r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); 28 r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
31 29
32 Self { 30 Self { ch }
33 ch,
34 phantom: PhantomData,
35 }
36 } 31 }
37} 32}
38 33
@@ -45,10 +40,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
45 r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) }); 40 r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) });
46 r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); 41 r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) });
47 42
48 Self { 43 Self { ch }
49 ch,
50 phantom: PhantomData,
51 }
52 } 44 }
53} 45}
54 46
@@ -63,10 +55,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
63 r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) }); 55 r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) });
64 r.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) }); 56 r.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) });
65 57
66 Self { 58 Self { ch }
67 ch,
68 phantom: PhantomData,
69 }
70 } 59 }
71} 60}
72 61
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs
index 9a78ff1f1..050461ea5 100644
--- a/embassy-nrf/src/pwm.rs
+++ b/embassy-nrf/src/pwm.rs
@@ -3,7 +3,7 @@
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
5 5
6use embassy_hal_common::unborrow; 6use embassy_hal_common::Unborrowed;
7 7
8use crate::gpio::sealed::Pin as _; 8use crate::gpio::sealed::Pin as _;
9use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; 9use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
@@ -17,20 +17,20 @@ use crate::{pac, Unborrow};
17pub struct SimplePwm<'d, T: Instance> { 17pub struct SimplePwm<'d, T: Instance> {
18 phantom: PhantomData<&'d mut T>, 18 phantom: PhantomData<&'d mut T>,
19 duty: [u16; 4], 19 duty: [u16; 4],
20 ch0: Option<AnyPin>, 20 ch0: Option<Unborrowed<'d, AnyPin>>,
21 ch1: Option<AnyPin>, 21 ch1: Option<Unborrowed<'d, AnyPin>>,
22 ch2: Option<AnyPin>, 22 ch2: Option<Unborrowed<'d, AnyPin>>,
23 ch3: Option<AnyPin>, 23 ch3: Option<Unborrowed<'d, AnyPin>>,
24} 24}
25 25
26/// SequencePwm allows you to offload the updating of a sequence of duty cycles 26/// SequencePwm allows you to offload the updating of a sequence of duty cycles
27/// to up to four channels, as well as repeat that sequence n times. 27/// to up to four channels, as well as repeat that sequence n times.
28pub struct SequencePwm<'d, T: Instance> { 28pub struct SequencePwm<'d, T: Instance> {
29 phantom: PhantomData<&'d mut T>, 29 phantom: PhantomData<&'d mut T>,
30 ch0: Option<AnyPin>, 30 ch0: Option<Unborrowed<'d, AnyPin>>,
31 ch1: Option<AnyPin>, 31 ch1: Option<Unborrowed<'d, AnyPin>>,
32 ch2: Option<AnyPin>, 32 ch2: Option<Unborrowed<'d, AnyPin>>,
33 ch3: Option<AnyPin>, 33 ch3: Option<Unborrowed<'d, AnyPin>>,
34} 34}
35 35
36#[derive(Debug, Clone, Copy, PartialEq, Eq)] 36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -55,8 +55,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
55 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 55 ch0: impl Unborrow<Target = impl GpioPin> + 'd,
56 config: Config, 56 config: Config,
57 ) -> Result<Self, Error> { 57 ) -> Result<Self, Error> {
58 unborrow!(ch0); 58 unborrow_and_degrade!(ch0);
59 Self::new_inner(pwm, Some(ch0.degrade()), None, None, None, config) 59 Self::new_inner(pwm, Some(ch0), None, None, None, config)
60 } 60 }
61 61
62 /// Create a new 2-channel PWM 62 /// Create a new 2-channel PWM
@@ -67,8 +67,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
67 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 67 ch1: impl Unborrow<Target = impl GpioPin> + 'd,
68 config: Config, 68 config: Config,
69 ) -> Result<Self, Error> { 69 ) -> Result<Self, Error> {
70 unborrow!(ch0, ch1); 70 unborrow_and_degrade!(ch0, ch1);
71 Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None, config) 71 Self::new_inner(pwm, Some(ch0), Some(ch1), None, None, config)
72 } 72 }
73 73
74 /// Create a new 3-channel PWM 74 /// Create a new 3-channel PWM
@@ -80,15 +80,8 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
80 ch2: impl Unborrow<Target = impl GpioPin> + 'd, 80 ch2: impl Unborrow<Target = impl GpioPin> + 'd,
81 config: Config, 81 config: Config,
82 ) -> Result<Self, Error> { 82 ) -> Result<Self, Error> {
83 unborrow!(ch0, ch1, ch2); 83 unborrow_and_degrade!(ch0, ch1, ch2);
84 Self::new_inner( 84 Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), None, config)
85 pwm,
86 Some(ch0.degrade()),
87 Some(ch1.degrade()),
88 Some(ch2.degrade()),
89 None,
90 config,
91 )
92 } 85 }
93 86
94 /// Create a new 4-channel PWM 87 /// Create a new 4-channel PWM
@@ -101,23 +94,16 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
101 ch3: impl Unborrow<Target = impl GpioPin> + 'd, 94 ch3: impl Unborrow<Target = impl GpioPin> + 'd,
102 config: Config, 95 config: Config,
103 ) -> Result<Self, Error> { 96 ) -> Result<Self, Error> {
104 unborrow!(ch0, ch1, ch2, ch3); 97 unborrow_and_degrade!(ch0, ch1, ch2, ch3);
105 Self::new_inner( 98 Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), Some(ch3), config)
106 pwm,
107 Some(ch0.degrade()),
108 Some(ch1.degrade()),
109 Some(ch2.degrade()),
110 Some(ch3.degrade()),
111 config,
112 )
113 } 99 }
114 100
115 fn new_inner( 101 fn new_inner(
116 _pwm: impl Unborrow<Target = T> + 'd, 102 _pwm: impl Unborrow<Target = T> + 'd,
117 ch0: Option<AnyPin>, 103 ch0: Option<Unborrowed<'d, AnyPin>>,
118 ch1: Option<AnyPin>, 104 ch1: Option<Unborrowed<'d, AnyPin>>,
119 ch2: Option<AnyPin>, 105 ch2: Option<Unborrowed<'d, AnyPin>>,
120 ch3: Option<AnyPin>, 106 ch3: Option<Unborrowed<'d, AnyPin>>,
121 config: Config, 107 config: Config,
122 ) -> Result<Self, Error> { 108 ) -> Result<Self, Error> {
123 let r = T::regs(); 109 let r = T::regs();
@@ -574,8 +560,10 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
574 /// Create a new 1-channel PWM 560 /// Create a new 1-channel PWM
575 #[allow(unused_unsafe)] 561 #[allow(unused_unsafe)]
576 pub fn new_1ch(pwm: impl Unborrow<Target = T> + 'd, ch0: impl Unborrow<Target = impl GpioPin> + 'd) -> Self { 562 pub fn new_1ch(pwm: impl Unborrow<Target = T> + 'd, ch0: impl Unborrow<Target = impl GpioPin> + 'd) -> Self {
577 unborrow!(ch0); 563 unsafe {
578 Self::new_inner(pwm, Some(ch0.degrade()), None, None, None) 564 unborrow_and_degrade!(ch0);
565 Self::new_inner(pwm, Some(ch0), None, None, None)
566 }
579 } 567 }
580 568
581 /// Create a new 2-channel PWM 569 /// Create a new 2-channel PWM
@@ -585,8 +573,8 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
585 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 573 ch0: impl Unborrow<Target = impl GpioPin> + 'd,
586 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 574 ch1: impl Unborrow<Target = impl GpioPin> + 'd,
587 ) -> Self { 575 ) -> Self {
588 unborrow!(ch0, ch1); 576 unborrow_and_degrade!(ch0, ch1);
589 Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None) 577 Self::new_inner(pwm, Some(ch0), Some(ch1), None, None)
590 } 578 }
591 579
592 /// Create a new 3-channel PWM 580 /// Create a new 3-channel PWM
@@ -597,8 +585,10 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
597 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 585 ch1: impl Unborrow<Target = impl GpioPin> + 'd,
598 ch2: impl Unborrow<Target = impl GpioPin> + 'd, 586 ch2: impl Unborrow<Target = impl GpioPin> + 'd,
599 ) -> Self { 587 ) -> Self {
600 unborrow!(ch0, ch1, ch2); 588 unsafe {
601 Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), Some(ch2.degrade()), None) 589 unborrow_and_degrade!(ch0, ch1, ch2);
590 Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), None)
591 }
602 } 592 }
603 593
604 /// Create a new 4-channel PWM 594 /// Create a new 4-channel PWM
@@ -610,22 +600,18 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
610 ch2: impl Unborrow<Target = impl GpioPin> + 'd, 600 ch2: impl Unborrow<Target = impl GpioPin> + 'd,
611 ch3: impl Unborrow<Target = impl GpioPin> + 'd, 601 ch3: impl Unborrow<Target = impl GpioPin> + 'd,
612 ) -> Self { 602 ) -> Self {
613 unborrow!(ch0, ch1, ch2, ch3); 603 unsafe {
614 Self::new_inner( 604 unborrow_and_degrade!(ch0, ch1, ch2, ch3);
615 pwm, 605 Self::new_inner(pwm, Some(ch0), Some(ch1), Some(ch2), Some(ch3))
616 Some(ch0.degrade()), 606 }
617 Some(ch1.degrade()),
618 Some(ch2.degrade()),
619 Some(ch3.degrade()),
620 )
621 } 607 }
622 608
623 fn new_inner( 609 fn new_inner(
624 _pwm: impl Unborrow<Target = T> + 'd, 610 _pwm: impl Unborrow<Target = T> + 'd,
625 ch0: Option<AnyPin>, 611 ch0: Option<Unborrowed<'d, AnyPin>>,
626 ch1: Option<AnyPin>, 612 ch1: Option<Unborrowed<'d, AnyPin>>,
627 ch2: Option<AnyPin>, 613 ch2: Option<Unborrowed<'d, AnyPin>>,
628 ch3: Option<AnyPin>, 614 ch3: Option<Unborrowed<'d, AnyPin>>,
629 ) -> Self { 615 ) -> Self {
630 let r = T::regs(); 616 let r = T::regs();
631 617
diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs
index e254328a6..da4f12606 100644
--- a/embassy-nrf/src/qdec.rs
+++ b/embassy-nrf/src/qdec.rs
@@ -4,7 +4,7 @@ use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::unborrow; 7use embassy_hal_common::{unborrow, Unborrowed};
8use futures::future::poll_fn; 8use futures::future::poll_fn;
9 9
10use crate::gpio::sealed::Pin as _; 10use crate::gpio::sealed::Pin as _;
@@ -49,8 +49,8 @@ impl<'d> Qdec<'d> {
49 b: impl Unborrow<Target = impl GpioPin> + 'd, 49 b: impl Unborrow<Target = impl GpioPin> + 'd,
50 config: Config, 50 config: Config,
51 ) -> Self { 51 ) -> Self {
52 unborrow!(a, b); 52 unborrow_and_degrade!(a, b);
53 Self::new_inner(qdec, irq, a.degrade(), b.degrade(), None, config) 53 Self::new_inner(qdec, irq, a, b, None, config)
54 } 54 }
55 55
56 pub fn new_with_led( 56 pub fn new_with_led(
@@ -61,16 +61,16 @@ impl<'d> Qdec<'d> {
61 led: impl Unborrow<Target = impl GpioPin> + 'd, 61 led: impl Unborrow<Target = impl GpioPin> + 'd,
62 config: Config, 62 config: Config,
63 ) -> Self { 63 ) -> Self {
64 unborrow!(a, b, led); 64 unborrow_and_degrade!(a, b, led);
65 Self::new_inner(qdec, irq, a.degrade(), b.degrade(), Some(led.degrade()), config) 65 Self::new_inner(qdec, irq, a, b, Some(led), config)
66 } 66 }
67 67
68 fn new_inner( 68 fn new_inner(
69 _t: impl Unborrow<Target = QDEC> + 'd, 69 _t: impl Unborrow<Target = QDEC> + 'd,
70 irq: impl Unborrow<Target = interrupt::QDEC> + 'd, 70 irq: impl Unborrow<Target = interrupt::QDEC> + 'd,
71 a: AnyPin, 71 a: Unborrowed<'d, AnyPin>,
72 b: AnyPin, 72 b: Unborrowed<'d, AnyPin>,
73 led: Option<AnyPin>, 73 led: Option<Unborrowed<'d, AnyPin>>,
74 config: Config, 74 config: Config,
75 ) -> Self { 75 ) -> Self {
76 unborrow!(irq); 76 unborrow!(irq);
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 92fa79b8a..2b987b465 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -1,11 +1,10 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::marker::PhantomData;
4use core::ptr; 3use core::ptr;
5use core::task::Poll; 4use core::task::Poll;
6 5
7use embassy_hal_common::drop::DropBomb; 6use embassy_hal_common::drop::DropBomb;
8use embassy_hal_common::unborrow; 7use embassy_hal_common::{unborrow, Unborrowed};
9use futures::future::poll_fn; 8use futures::future::poll_fn;
10 9
11use crate::gpio::sealed::Pin as _; 10use crate::gpio::sealed::Pin as _;
@@ -63,9 +62,8 @@ pub enum Error {
63} 62}
64 63
65pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> { 64pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> {
66 irq: T::Interrupt, 65 irq: Unborrowed<'d, T::Interrupt>,
67 dpm_enabled: bool, 66 dpm_enabled: bool,
68 phantom: PhantomData<&'d mut T>,
69} 67}
70 68
71impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> { 69impl<'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> {
84 82
85 let r = T::regs(); 83 let r = T::regs();
86 84
87 let sck = sck.degrade(); 85 unborrow_and_degrade!(sck, csn, io0, io1, io2, io3);
88 let csn = csn.degrade();
89 let io0 = io0.degrade();
90 let io1 = io1.degrade();
91 let io2 = io2.degrade();
92 let io3 = io3.degrade();
93 86
94 for pin in [&sck, &csn, &io0, &io1, &io2, &io3] { 87 for pin in [&sck, &csn, &io0, &io1, &io2, &io3] {
95 pin.set_high(); 88 pin.set_high();
@@ -143,7 +136,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
143 let mut res = Self { 136 let mut res = Self {
144 dpm_enabled: config.deep_power_down.is_some(), 137 dpm_enabled: config.deep_power_down.is_some(),
145 irq, 138 irq,
146 phantom: PhantomData,
147 }; 139 };
148 140
149 r.events_ready.reset(); 141 r.events_ready.reset();
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index e68ed912e..111a5424b 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -1,11 +1,10 @@
1use core::marker::PhantomData;
2use core::ptr; 1use core::ptr;
3use core::sync::atomic::{AtomicPtr, Ordering}; 2use core::sync::atomic::{AtomicPtr, Ordering};
4use core::task::Poll; 3use core::task::Poll;
5 4
6use embassy::waitqueue::AtomicWaker; 5use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::drop::OnDrop; 6use embassy_hal_common::drop::OnDrop;
8use embassy_hal_common::unborrow; 7use embassy_hal_common::{unborrow, Unborrowed};
9use futures::future::poll_fn; 8use futures::future::poll_fn;
10 9
11use crate::interrupt::InterruptExt; 10use crate::interrupt::InterruptExt;
@@ -34,8 +33,7 @@ struct State {
34/// 33///
35/// It has a non-blocking API, and a blocking api through `rand`. 34/// It has a non-blocking API, and a blocking api through `rand`.
36pub struct Rng<'d> { 35pub struct Rng<'d> {
37 irq: interrupt::RNG, 36 irq: Unborrowed<'d, interrupt::RNG>,
38 phantom: PhantomData<(&'d mut RNG, &'d mut interrupt::RNG)>,
39} 37}
40 38
41impl<'d> Rng<'d> { 39impl<'d> Rng<'d> {
@@ -48,10 +46,7 @@ impl<'d> Rng<'d> {
48 pub fn new(_rng: impl Unborrow<Target = RNG> + 'd, irq: impl Unborrow<Target = interrupt::RNG> + 'd) -> Self { 46 pub fn new(_rng: impl Unborrow<Target = RNG> + 'd, irq: impl Unborrow<Target = interrupt::RNG> + 'd) -> Self {
49 unborrow!(irq); 47 unborrow!(irq);
50 48
51 let this = Self { 49 let this = Self { irq };
52 irq,
53 phantom: PhantomData,
54 };
55 50
56 this.stop(); 51 this.stop();
57 this.disable_irq(); 52 this.disable_irq();
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index af1aa8812..d7d59b629 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -5,7 +5,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 5use core::task::Poll;
6 6
7use embassy::waitqueue::AtomicWaker; 7use embassy::waitqueue::AtomicWaker;
8use embassy_hal_common::unborrow; 8use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
9use futures::future::poll_fn; 9use futures::future::poll_fn;
10use pac::{saadc, SAADC}; 10use pac::{saadc, SAADC};
11use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; 11use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A};
@@ -77,12 +77,7 @@ pub struct ChannelConfig<'d> {
77/// internal voltage. 77/// internal voltage.
78pub struct VddInput; 78pub struct VddInput;
79 79
80unsafe impl Unborrow for VddInput { 80unsafe_impl_unborrow!(VddInput);
81 type Target = VddInput;
82 unsafe fn unborrow(self) -> Self::Target {
83 self
84 }
85}
86 81
87impl sealed::Input for VddInput { 82impl sealed::Input for VddInput {
88 #[cfg(not(feature = "_nrf9160"))] 83 #[cfg(not(feature = "_nrf9160"))]
@@ -102,12 +97,7 @@ impl Input for VddInput {}
102pub struct VddhDiv5Input; 97pub struct VddhDiv5Input;
103 98
104#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] 99#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
105unsafe impl Unborrow for VddhDiv5Input { 100unsafe_impl_unborrow!(VddhDiv5Input);
106 type Target = VddhDiv5Input;
107 unsafe fn unborrow(self) -> Self::Target {
108 self
109 }
110}
111 101
112#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] 102#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
113impl sealed::Input for VddhDiv5Input { 103impl sealed::Input for VddhDiv5Input {
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index d34d9a0c8..889d04dc0 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -5,7 +5,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 5use core::task::Poll;
6 6
7use embassy_embedded_hal::SetConfig; 7use embassy_embedded_hal::SetConfig;
8use embassy_hal_common::unborrow; 8use embassy_hal_common::{unborrow, Unborrowed};
9pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 9pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
10use futures::future::poll_fn; 10use futures::future::poll_fn;
11pub use pac::spim0::frequency::FREQUENCY_A as Frequency; 11pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
@@ -60,15 +60,8 @@ impl<'d, T: Instance> Spim<'d, T> {
60 mosi: impl Unborrow<Target = impl GpioPin> + 'd, 60 mosi: impl Unborrow<Target = impl GpioPin> + 'd,
61 config: Config, 61 config: Config,
62 ) -> Self { 62 ) -> Self {
63 unborrow!(sck, miso, mosi); 63 unborrow_and_degrade!(sck, miso, mosi);
64 Self::new_inner( 64 Self::new_inner(spim, irq, sck, Some(miso), Some(mosi), config)
65 spim,
66 irq,
67 sck.degrade(),
68 Some(miso.degrade()),
69 Some(mosi.degrade()),
70 config,
71 )
72 } 65 }
73 66
74 pub fn new_txonly( 67 pub fn new_txonly(
@@ -78,8 +71,8 @@ impl<'d, T: Instance> Spim<'d, T> {
78 mosi: impl Unborrow<Target = impl GpioPin> + 'd, 71 mosi: impl Unborrow<Target = impl GpioPin> + 'd,
79 config: Config, 72 config: Config,
80 ) -> Self { 73 ) -> Self {
81 unborrow!(sck, mosi); 74 unborrow_and_degrade!(sck, mosi);
82 Self::new_inner(spim, irq, sck.degrade(), None, Some(mosi.degrade()), config) 75 Self::new_inner(spim, irq, sck, None, Some(mosi), config)
83 } 76 }
84 77
85 pub fn new_rxonly( 78 pub fn new_rxonly(
@@ -89,16 +82,16 @@ impl<'d, T: Instance> Spim<'d, T> {
89 miso: impl Unborrow<Target = impl GpioPin> + 'd, 82 miso: impl Unborrow<Target = impl GpioPin> + 'd,
90 config: Config, 83 config: Config,
91 ) -> Self { 84 ) -> Self {
92 unborrow!(sck, miso); 85 unborrow_and_degrade!(sck, miso);
93 Self::new_inner(spim, irq, sck.degrade(), Some(miso.degrade()), None, config) 86 Self::new_inner(spim, irq, sck, Some(miso), None, config)
94 } 87 }
95 88
96 fn new_inner( 89 fn new_inner(
97 _spim: impl Unborrow<Target = T> + 'd, 90 _spim: impl Unborrow<Target = T> + 'd,
98 irq: impl Unborrow<Target = T::Interrupt> + 'd, 91 irq: impl Unborrow<Target = T::Interrupt> + 'd,
99 sck: AnyPin, 92 sck: Unborrowed<'d, AnyPin>,
100 miso: Option<AnyPin>, 93 miso: Option<Unborrowed<'d, AnyPin>>,
101 mosi: Option<AnyPin>, 94 mosi: Option<Unborrowed<'d, AnyPin>>,
102 config: Config, 95 config: Config,
103 ) -> Self { 96 ) -> Self {
104 unborrow!(irq); 97 unborrow!(irq);
diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs
index 43ba3e042..0bb82a499 100644
--- a/embassy-nrf/src/temp.rs
+++ b/embassy-nrf/src/temp.rs
@@ -1,11 +1,10 @@
1//! Temperature sensor interface. 1//! Temperature sensor interface.
2 2
3use core::marker::PhantomData;
4use core::task::Poll; 3use core::task::Poll;
5 4
6use embassy::waitqueue::AtomicWaker; 5use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::drop::OnDrop; 6use embassy_hal_common::drop::OnDrop;
8use embassy_hal_common::unborrow; 7use embassy_hal_common::{unborrow, Unborrowed};
9use fixed::types::I30F2; 8use fixed::types::I30F2;
10use futures::future::poll_fn; 9use futures::future::poll_fn;
11 10
@@ -15,8 +14,7 @@ use crate::{interrupt, pac, Unborrow};
15 14
16/// Integrated temperature sensor. 15/// Integrated temperature sensor.
17pub struct Temp<'d> { 16pub struct Temp<'d> {
18 _temp: PhantomData<&'d TEMP>, 17 _irq: Unborrowed<'d, interrupt::TEMP>,
19 _irq: interrupt::TEMP,
20} 18}
21 19
22static WAKER: AtomicWaker = AtomicWaker::new(); 20static WAKER: AtomicWaker = AtomicWaker::new();
@@ -33,10 +31,7 @@ impl<'d> Temp<'d> {
33 WAKER.wake(); 31 WAKER.wake();
34 }); 32 });
35 irq.enable(); 33 irq.enable();
36 Self { 34 Self { _irq: irq }
37 _temp: PhantomData,
38 _irq: irq,
39 }
40 } 35 }
41 36
42 /// Perform an asynchronous temperature measurement. The returned future 37 /// Perform an asynchronous temperature measurement. The returned future
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 459c56c8e..d5ffb3159 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -18,7 +18,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
18use core::task::Poll; 18use core::task::Poll;
19 19
20use embassy_hal_common::drop::OnDrop; 20use embassy_hal_common::drop::OnDrop;
21use embassy_hal_common::unborrow; 21use embassy_hal_common::{unborrow, Unborrowed};
22use futures::future::poll_fn; 22use futures::future::poll_fn;
23use pac::uarte0::RegisterBlock; 23use pac::uarte0::RegisterBlock;
24// Re-export SVD variants to allow user to directly set values. 24// Re-export SVD variants to allow user to directly set values.
@@ -89,8 +89,8 @@ impl<'d, T: Instance> Uarte<'d, T> {
89 txd: impl Unborrow<Target = impl GpioPin> + 'd, 89 txd: impl Unborrow<Target = impl GpioPin> + 'd,
90 config: Config, 90 config: Config,
91 ) -> Self { 91 ) -> Self {
92 unborrow!(rxd, txd); 92 unborrow_and_degrade!(rxd, txd);
93 Self::new_inner(uarte, irq, rxd.degrade(), txd.degrade(), None, None, config) 93 Self::new_inner(uarte, irq, rxd, txd, None, None, config)
94 } 94 }
95 95
96 /// Create a new UARTE with hardware flow control (RTS/CTS) 96 /// Create a new UARTE with hardware flow control (RTS/CTS)
@@ -103,25 +103,17 @@ impl<'d, T: Instance> Uarte<'d, T> {
103 rts: impl Unborrow<Target = impl GpioPin> + 'd, 103 rts: impl Unborrow<Target = impl GpioPin> + 'd,
104 config: Config, 104 config: Config,
105 ) -> Self { 105 ) -> Self {
106 unborrow!(rxd, txd, cts, rts); 106 unborrow_and_degrade!(rxd, txd, cts, rts);
107 Self::new_inner( 107 Self::new_inner(uarte, irq, rxd, txd, Some(cts), Some(rts), config)
108 uarte,
109 irq,
110 rxd.degrade(),
111 txd.degrade(),
112 Some(cts.degrade()),
113 Some(rts.degrade()),
114 config,
115 )
116 } 108 }
117 109
118 fn new_inner( 110 fn new_inner(
119 _uarte: impl Unborrow<Target = T> + 'd, 111 _uarte: impl Unborrow<Target = T> + 'd,
120 irq: impl Unborrow<Target = T::Interrupt> + 'd, 112 irq: impl Unborrow<Target = T::Interrupt> + 'd,
121 rxd: AnyPin, 113 rxd: Unborrowed<'d, AnyPin>,
122 txd: AnyPin, 114 txd: Unborrowed<'d, AnyPin>,
123 cts: Option<AnyPin>, 115 cts: Option<Unborrowed<'d, AnyPin>>,
124 rts: Option<AnyPin>, 116 rts: Option<Unborrowed<'d, AnyPin>>,
125 config: Config, 117 config: Config,
126 ) -> Self { 118 ) -> Self {
127 unborrow!(irq); 119 unborrow!(irq);
@@ -250,8 +242,8 @@ impl<'d, T: Instance> UarteTx<'d, T> {
250 txd: impl Unborrow<Target = impl GpioPin> + 'd, 242 txd: impl Unborrow<Target = impl GpioPin> + 'd,
251 config: Config, 243 config: Config,
252 ) -> Self { 244 ) -> Self {
253 unborrow!(txd); 245 unborrow_and_degrade!(txd);
254 Self::new_inner(uarte, irq, txd.degrade(), None, config) 246 Self::new_inner(uarte, irq, txd, None, config)
255 } 247 }
256 248
257 /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) 249 /// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
@@ -262,15 +254,15 @@ impl<'d, T: Instance> UarteTx<'d, T> {
262 cts: impl Unborrow<Target = impl GpioPin> + 'd, 254 cts: impl Unborrow<Target = impl GpioPin> + 'd,
263 config: Config, 255 config: Config,
264 ) -> Self { 256 ) -> Self {
265 unborrow!(txd, cts); 257 unborrow_and_degrade!(txd, cts);
266 Self::new_inner(uarte, irq, txd.degrade(), Some(cts.degrade()), config) 258 Self::new_inner(uarte, irq, txd, Some(cts), config)
267 } 259 }
268 260
269 fn new_inner( 261 fn new_inner(
270 _uarte: impl Unborrow<Target = T> + 'd, 262 _uarte: impl Unborrow<Target = T> + 'd,
271 irq: impl Unborrow<Target = T::Interrupt> + 'd, 263 irq: impl Unborrow<Target = T::Interrupt> + 'd,
272 txd: AnyPin, 264 txd: Unborrowed<'d, AnyPin>,
273 cts: Option<AnyPin>, 265 cts: Option<Unborrowed<'d, AnyPin>>,
274 config: Config, 266 config: Config,
275 ) -> Self { 267 ) -> Self {
276 unborrow!(irq); 268 unborrow!(irq);
@@ -442,8 +434,8 @@ impl<'d, T: Instance> UarteRx<'d, T> {
442 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 434 rxd: impl Unborrow<Target = impl GpioPin> + 'd,
443 config: Config, 435 config: Config,
444 ) -> Self { 436 ) -> Self {
445 unborrow!(rxd); 437 unborrow_and_degrade!(rxd);
446 Self::new_inner(uarte, irq, rxd.degrade(), None, config) 438 Self::new_inner(uarte, irq, rxd, None, config)
447 } 439 }
448 440
449 /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) 441 /// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
@@ -454,15 +446,15 @@ impl<'d, T: Instance> UarteRx<'d, T> {
454 rts: impl Unborrow<Target = impl GpioPin> + 'd, 446 rts: impl Unborrow<Target = impl GpioPin> + 'd,
455 config: Config, 447 config: Config,
456 ) -> Self { 448 ) -> Self {
457 unborrow!(rxd, rts); 449 unborrow_and_degrade!(rxd, rts);
458 Self::new_inner(uarte, irq, rxd.degrade(), Some(rts.degrade()), config) 450 Self::new_inner(uarte, irq, rxd, Some(rts), config)
459 } 451 }
460 452
461 fn new_inner( 453 fn new_inner(
462 _uarte: impl Unborrow<Target = T> + 'd, 454 _uarte: impl Unborrow<Target = T> + 'd,
463 irq: impl Unborrow<Target = T::Interrupt> + 'd, 455 irq: impl Unborrow<Target = T::Interrupt> + 'd,
464 rxd: AnyPin, 456 rxd: Unborrowed<'d, AnyPin>,
465 rts: Option<AnyPin>, 457 rts: Option<Unborrowed<'d, AnyPin>>,
466 config: Config, 458 config: Config,
467 ) -> Self { 459 ) -> Self {
468 unborrow!(irq); 460 unborrow!(irq);
@@ -685,19 +677,8 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
685 txd: impl Unborrow<Target = impl GpioPin> + 'd, 677 txd: impl Unborrow<Target = impl GpioPin> + 'd,
686 config: Config, 678 config: Config,
687 ) -> Self { 679 ) -> Self {
688 unborrow!(rxd, txd); 680 unborrow_and_degrade!(rxd, txd);
689 Self::new_inner( 681 Self::new_inner(uarte, timer, ppi_ch1, ppi_ch2, irq, rxd, txd, None, None, config)
690 uarte,
691 timer,
692 ppi_ch1,
693 ppi_ch2,
694 irq,
695 rxd.degrade(),
696 txd.degrade(),
697 None,
698 None,
699 config,
700 )
701 } 682 }
702 683
703 /// Create a new UARTE with hardware flow control (RTS/CTS) 684 /// Create a new UARTE with hardware flow control (RTS/CTS)
@@ -713,17 +694,17 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
713 rts: impl Unborrow<Target = impl GpioPin> + 'd, 694 rts: impl Unborrow<Target = impl GpioPin> + 'd,
714 config: Config, 695 config: Config,
715 ) -> Self { 696 ) -> Self {
716 unborrow!(rxd, txd, cts, rts); 697 unborrow_and_degrade!(rxd, txd, cts, rts);
717 Self::new_inner( 698 Self::new_inner(
718 uarte, 699 uarte,
719 timer, 700 timer,
720 ppi_ch1, 701 ppi_ch1,
721 ppi_ch2, 702 ppi_ch2,
722 irq, 703 irq,
723 rxd.degrade(), 704 rxd,
724 txd.degrade(), 705 txd,
725 Some(cts.degrade()), 706 Some(cts),
726 Some(rts.degrade()), 707 Some(rts),
727 config, 708 config,
728 ) 709 )
729 } 710 }
@@ -734,10 +715,10 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
734 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 715 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
735 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 716 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd,
736 irq: impl Unborrow<Target = U::Interrupt> + 'd, 717 irq: impl Unborrow<Target = U::Interrupt> + 'd,
737 rxd: AnyPin, 718 rxd: Unborrowed<'d, AnyPin>,
738 txd: AnyPin, 719 txd: Unborrowed<'d, AnyPin>,
739 cts: Option<AnyPin>, 720 cts: Option<Unborrowed<'d, AnyPin>>,
740 rts: Option<AnyPin>, 721 rts: Option<Unborrowed<'d, AnyPin>>,
741 config: Config, 722 config: Config,
742 ) -> Self { 723 ) -> Self {
743 let baudrate = config.baudrate; 724 let baudrate = config.baudrate;
@@ -763,7 +744,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
763 timer.cc(0).short_compare_stop(); 744 timer.cc(0).short_compare_stop();
764 745
765 let mut ppi_ch1 = Ppi::new_one_to_two( 746 let mut ppi_ch1 = Ppi::new_one_to_two(
766 ppi_ch1.degrade(), 747 unsafe { ppi_ch1.into_inner() }.degrade(),
767 Event::from_reg(&r.events_rxdrdy), 748 Event::from_reg(&r.events_rxdrdy),
768 timer.task_clear(), 749 timer.task_clear(),
769 timer.task_start(), 750 timer.task_start(),
@@ -771,7 +752,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
771 ppi_ch1.enable(); 752 ppi_ch1.enable();
772 753
773 let mut ppi_ch2 = Ppi::new_one_to_one( 754 let mut ppi_ch2 = Ppi::new_one_to_one(
774 ppi_ch2.degrade(), 755 unsafe { ppi_ch2.into_inner() }.degrade(),
775 timer.cc(0).event_compare(), 756 timer.cc(0).event_compare(),
776 Task::from_reg(&r.tasks_stoprx), 757 Task::from_reg(&r.tasks_stoprx),
777 ); 758 );