aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-07-23 13:15:17 +0000
committerGitHub <[email protected]>2022-07-23 13:15:17 +0000
commite61e36a8158073ec92df1a751cfdd7fce5004cf8 (patch)
tree4a54aee47c0d3881b9e0bc809e075728cee8eeae /embassy-nrf/src
parent96f67671677d8bf7175f98e87c98954dc728286c (diff)
parent709df0dc1dfff577fb79bbc2f67ea84670072456 (diff)
Merge #842
842: WIP: Make unborrow safe to use r=Dirbaio a=GrantM11235 The basic idea is that `Unborrow::unborrow` is now safe to call and returns an `Unborrowed<'a, T>` which impls `Deref` and `DerefMut` ```rust /// 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>, } ``` ## Todo - [x] Update other crates - [x] embassy-cortex-m - [x] embassy-hal-common - [x] embassy-lora - [x] embassy-nrf - [x] embassy-rp - [x] embassy-stm32 - [x] Remove usage of the unsafe `into_inner` method if possible - [x] Review and amend docs for `Unborrow` and `Unborrowed` Co-authored-by: Grant Miller <[email protected]> Co-authored-by: Dario Nieuwenhuis <[email protected]>
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/buffered_uarte.rs33
-rw-r--r--embassy-nrf/src/gpio.rs38
-rw-r--r--embassy-nrf/src/gpiote.rs44
-rw-r--r--embassy-nrf/src/lib.rs2
-rw-r--r--embassy-nrf/src/nvmc.rs14
-rw-r--r--embassy-nrf/src/ppi/dppi.rs21
-rw-r--r--embassy-nrf/src/ppi/mod.rs32
-rw-r--r--embassy-nrf/src/ppi/ppi.rs33
-rw-r--r--embassy-nrf/src/pwm.rs175
-rw-r--r--embassy-nrf/src/qdec.rs47
-rw-r--r--embassy-nrf/src/qspi.rs53
-rw-r--r--embassy-nrf/src/rng.rs17
-rw-r--r--embassy-nrf/src/saadc.rs163
-rw-r--r--embassy-nrf/src/spim.rs65
-rw-r--r--embassy-nrf/src/temp.rs17
-rw-r--r--embassy-nrf/src/timer.rs41
-rw-r--r--embassy-nrf/src/twim.rs21
-rw-r--r--embassy-nrf/src/uarte.rs207
-rw-r--r--embassy-nrf/src/usb.rs28
19 files changed, 505 insertions, 546 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 4fc78b95d..89c1ba908 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -15,14 +15,13 @@
15 15
16use core::cmp::min; 16use core::cmp::min;
17use core::future::Future; 17use core::future::Future;
18use core::marker::PhantomData;
19use core::sync::atomic::{compiler_fence, Ordering}; 18use core::sync::atomic::{compiler_fence, Ordering};
20use core::task::Poll; 19use core::task::Poll;
21 20
22use embassy::waitqueue::WakerRegistration; 21use embassy::waitqueue::WakerRegistration;
23use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 22use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
24use embassy_hal_common::ring_buffer::RingBuffer; 23use embassy_hal_common::ring_buffer::RingBuffer;
25use embassy_hal_common::{low_power_wait_until, unborrow}; 24use embassy_hal_common::{into_ref, low_power_wait_until, PeripheralRef};
26use futures::future::poll_fn; 25use futures::future::poll_fn;
27// Re-export SVD variants to allow user to directly set values 26// Re-export SVD variants to allow user to directly set values
28pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 27pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
@@ -32,7 +31,7 @@ use crate::interrupt::InterruptExt;
32use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; 31use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
33use crate::timer::{Frequency, Instance as TimerInstance, Timer}; 32use crate::timer::{Frequency, Instance as TimerInstance, Timer};
34use crate::uarte::{apply_workaround_for_enable_anomaly, Config, Instance as UarteInstance}; 33use crate::uarte::{apply_workaround_for_enable_anomaly, Config, Instance as UarteInstance};
35use crate::{pac, Unborrow}; 34use crate::{pac, Peripheral};
36 35
37#[derive(Copy, Clone, Debug, PartialEq)] 36#[derive(Copy, Clone, Debug, PartialEq)]
38enum RxState { 37enum RxState {
@@ -54,7 +53,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> {
54} 53}
55 54
56struct StateInner<'d, U: UarteInstance, T: TimerInstance> { 55struct StateInner<'d, U: UarteInstance, T: TimerInstance> {
57 phantom: PhantomData<&'d mut U>, 56 _peri: PeripheralRef<'d, U>,
58 timer: Timer<'d, T>, 57 timer: Timer<'d, T>,
59 _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, 58 _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>,
60 _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, 59 _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>,
@@ -78,20 +77,20 @@ impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {
78impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { 77impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
79 pub fn new( 78 pub fn new(
80 state: &'d mut State<'d, U, T>, 79 state: &'d mut State<'d, U, T>,
81 _uarte: impl Unborrow<Target = U> + 'd, 80 peri: impl Peripheral<P = U> + 'd,
82 timer: impl Unborrow<Target = T> + 'd, 81 timer: impl Peripheral<P = T> + 'd,
83 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 82 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
84 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 83 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
85 irq: impl Unborrow<Target = U::Interrupt> + 'd, 84 irq: impl Peripheral<P = U::Interrupt> + 'd,
86 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 85 rxd: impl Peripheral<P = impl GpioPin> + 'd,
87 txd: impl Unborrow<Target = impl GpioPin> + 'd, 86 txd: impl Peripheral<P = impl GpioPin> + 'd,
88 cts: impl Unborrow<Target = impl GpioPin> + 'd, 87 cts: impl Peripheral<P = impl GpioPin> + 'd,
89 rts: impl Unborrow<Target = impl GpioPin> + 'd, 88 rts: impl Peripheral<P = impl GpioPin> + 'd,
90 config: Config, 89 config: Config,
91 rx_buffer: &'d mut [u8], 90 rx_buffer: &'d mut [u8],
92 tx_buffer: &'d mut [u8], 91 tx_buffer: &'d mut [u8],
93 ) -> Self { 92 ) -> Self {
94 unborrow!(ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); 93 into_ref!(peri, ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts);
95 94
96 let r = U::regs(); 95 let r = U::regs();
97 96
@@ -147,7 +146,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
147 timer.cc(0).short_compare_stop(); 146 timer.cc(0).short_compare_stop();
148 147
149 let mut ppi_ch1 = Ppi::new_one_to_two( 148 let mut ppi_ch1 = Ppi::new_one_to_two(
150 ppi_ch1.degrade(), 149 ppi_ch1.map_into(),
151 Event::from_reg(&r.events_rxdrdy), 150 Event::from_reg(&r.events_rxdrdy),
152 timer.task_clear(), 151 timer.task_clear(),
153 timer.task_start(), 152 timer.task_start(),
@@ -155,7 +154,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
155 ppi_ch1.enable(); 154 ppi_ch1.enable();
156 155
157 let mut ppi_ch2 = Ppi::new_one_to_one( 156 let mut ppi_ch2 = Ppi::new_one_to_one(
158 ppi_ch2.degrade(), 157 ppi_ch2.map_into(),
159 timer.cc(0).event_compare(), 158 timer.cc(0).event_compare(),
160 Task::from_reg(&r.tasks_stoprx), 159 Task::from_reg(&r.tasks_stoprx),
161 ); 160 );
@@ -163,7 +162,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
163 162
164 Self { 163 Self {
165 inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner { 164 inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner {
166 phantom: PhantomData, 165 _peri: peri,
167 timer, 166 timer,
168 _ppi_ch1: ppi_ch1, 167 _ppi_ch1: ppi_ch1,
169 _ppi_ch2: ppi_ch2, 168 _ppi_ch2: ppi_ch2,
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index fd4ae2ec3..a61ff6aa5 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -2,15 +2,14 @@
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::{impl_peripheral, into_ref, PeripheralRef};
9 8
10use self::sealed::Pin as _; 9use self::sealed::Pin as _;
11use crate::pac::p0 as gpio; 10use crate::pac::p0 as gpio;
12use crate::pac::p0::pin_cnf::{DRIVE_A, PULL_A}; 11use crate::pac::p0::pin_cnf::{DRIVE_A, PULL_A};
13use crate::{pac, Unborrow}; 12use crate::{pac, Peripheral};
14 13
15/// A GPIO port with up to 32 pins. 14/// A GPIO port with up to 32 pins.
16#[derive(Debug, Eq, PartialEq)] 15#[derive(Debug, Eq, PartialEq)]
@@ -39,7 +38,7 @@ pub struct Input<'d, T: Pin> {
39 38
40impl<'d, T: Pin> Input<'d, T> { 39impl<'d, T: Pin> Input<'d, T> {
41 #[inline] 40 #[inline]
42 pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { 41 pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
43 let mut pin = Flex::new(pin); 42 let mut pin = Flex::new(pin);
44 pin.set_as_input(pull); 43 pin.set_as_input(pull);
45 44
@@ -119,7 +118,7 @@ pub struct Output<'d, T: Pin> {
119 118
120impl<'d, T: Pin> Output<'d, T> { 119impl<'d, T: Pin> Output<'d, T> {
121 #[inline] 120 #[inline]
122 pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self { 121 pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self {
123 let mut pin = Flex::new(pin); 122 let mut pin = Flex::new(pin);
124 match initial_output { 123 match initial_output {
125 Level::High => pin.set_high(), 124 Level::High => pin.set_high(),
@@ -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: PeripheralRef<'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> {
@@ -204,13 +202,10 @@ impl<'d, T: Pin> Flex<'d, T> {
204 /// The pin remains disconnected. The initial output level is unspecified, but can be changed 202 /// The pin remains disconnected. The initial output level is unspecified, but can be changed
205 /// before the pin is put into output mode. 203 /// before the pin is put into output mode.
206 #[inline] 204 #[inline]
207 pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self { 205 pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
208 unborrow!(pin); 206 into_ref!(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.
@@ -379,7 +374,7 @@ pub(crate) mod sealed {
379 } 374 }
380} 375}
381 376
382pub trait Pin: Unborrow<Target = Self> + sealed::Pin + Sized + 'static { 377pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
383 /// Number of the pin within the port (0..31) 378 /// Number of the pin within the port (0..31)
384 #[inline] 379 #[inline]
385 fn pin(&self) -> u8 { 380 fn pin(&self) -> u8 {
@@ -423,7 +418,7 @@ impl AnyPin {
423 } 418 }
424} 419}
425 420
426unsafe_impl_unborrow!(AnyPin); 421impl_peripheral!(AnyPin);
427impl Pin for AnyPin {} 422impl Pin for AnyPin {}
428impl sealed::Pin for AnyPin { 423impl sealed::Pin for AnyPin {
429 #[inline] 424 #[inline]
@@ -438,10 +433,13 @@ pub(crate) trait PselBits {
438 fn psel_bits(&self) -> u32; 433 fn psel_bits(&self) -> u32;
439} 434}
440 435
441impl PselBits for Option<AnyPin> { 436impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> {
442 #[inline] 437 #[inline]
443 fn psel_bits(&self) -> u32 { 438 fn psel_bits(&self) -> u32 {
444 self.as_ref().map_or(1u32 << 31, Pin::psel_bits) 439 match self {
440 Some(pin) => pin.psel_bits(),
441 None => 1u32 << 31,
442 }
445 } 443 }
446} 444}
447 445
@@ -463,6 +461,12 @@ macro_rules! impl_pin {
463 $port_num * 32 + $pin_num 461 $port_num * 32 + $pin_num
464 } 462 }
465 } 463 }
464
465 impl From<peripherals::$type> for crate::gpio::AnyPin {
466 fn from(val: peripherals::$type) -> Self {
467 crate::gpio::Pin::degrade(val)
468 }
469 }
466 }; 470 };
467} 471}
468 472
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index d4e1cb35c..cef80ae0a 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -1,10 +1,9 @@
1use core::convert::Infallible; 1use core::convert::Infallible;
2use core::future::Future; 2use core::future::Future;
3use core::marker::PhantomData;
4use core::task::{Context, Poll}; 3use core::task::{Context, Poll};
5 4
6use embassy::waitqueue::AtomicWaker; 5use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::unsafe_impl_unborrow; 6use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef};
8use futures::future::poll_fn; 7use futures::future::poll_fn;
9 8
10use crate::gpio::sealed::Pin as _; 9use crate::gpio::sealed::Pin as _;
@@ -301,16 +300,22 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
301// ======================= 300// =======================
302 301
303pub(crate) struct PortInputFuture<'a> { 302pub(crate) struct PortInputFuture<'a> {
304 pin_port: u8, 303 pin: PeripheralRef<'a, AnyPin>,
305 phantom: PhantomData<&'a mut AnyPin>, 304}
305
306impl<'a> PortInputFuture<'a> {
307 fn new(pin: impl Peripheral<P = impl GpioPin> + 'a) -> Self {
308 Self {
309 pin: pin.into_ref().map_into(),
310 }
311 }
306} 312}
307 313
308impl<'a> Unpin for PortInputFuture<'a> {} 314impl<'a> Unpin for PortInputFuture<'a> {}
309 315
310impl<'a> Drop for PortInputFuture<'a> { 316impl<'a> Drop for PortInputFuture<'a> {
311 fn drop(&mut self) { 317 fn drop(&mut self) {
312 let pin = unsafe { AnyPin::steal(self.pin_port) }; 318 self.pin.conf().modify(|_, w| w.sense().disabled());
313 pin.conf().modify(|_, w| w.sense().disabled());
314 } 319 }
315} 320}
316 321
@@ -318,10 +323,9 @@ impl<'a> Future for PortInputFuture<'a> {
318 type Output = (); 323 type Output = ();
319 324
320 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 325 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
321 PORT_WAKERS[self.pin_port as usize].register(cx.waker()); 326 PORT_WAKERS[self.pin.pin_port() as usize].register(cx.waker());
322 327
323 let pin = unsafe { AnyPin::steal(self.pin_port) }; 328 if self.pin.conf().read().sense().is_disabled() {
324 if pin.conf().read().sense().is_disabled() {
325 Poll::Ready(()) 329 Poll::Ready(())
326 } else { 330 } else {
327 Poll::Pending 331 Poll::Pending
@@ -354,22 +358,12 @@ impl<'d, T: GpioPin> Input<'d, T> {
354impl<'d, T: GpioPin> Flex<'d, T> { 358impl<'d, T: GpioPin> Flex<'d, T> {
355 pub async fn wait_for_high(&mut self) { 359 pub async fn wait_for_high(&mut self) {
356 self.pin.conf().modify(|_, w| w.sense().high()); 360 self.pin.conf().modify(|_, w| w.sense().high());
357 361 PortInputFuture::new(&mut self.pin).await
358 PortInputFuture {
359 pin_port: self.pin.pin_port(),
360 phantom: PhantomData,
361 }
362 .await
363 } 362 }
364 363
365 pub async fn wait_for_low(&mut self) { 364 pub async fn wait_for_low(&mut self) {
366 self.pin.conf().modify(|_, w| w.sense().low()); 365 self.pin.conf().modify(|_, w| w.sense().low());
367 366 PortInputFuture::new(&mut self.pin).await
368 PortInputFuture {
369 pin_port: self.pin.pin_port(),
370 phantom: PhantomData,
371 }
372 .await
373 } 367 }
374 368
375 pub async fn wait_for_rising_edge(&mut self) { 369 pub async fn wait_for_rising_edge(&mut self) {
@@ -388,11 +382,7 @@ impl<'d, T: GpioPin> Flex<'d, T> {
388 } else { 382 } else {
389 self.pin.conf().modify(|_, w| w.sense().high()); 383 self.pin.conf().modify(|_, w| w.sense().high());
390 } 384 }
391 PortInputFuture { 385 PortInputFuture::new(&mut self.pin).await
392 pin_port: self.pin.pin_port(),
393 phantom: PhantomData,
394 }
395 .await
396 } 386 }
397} 387}
398 388
@@ -414,7 +404,7 @@ pub trait Channel: sealed::Channel + Sized {
414pub struct AnyChannel { 404pub struct AnyChannel {
415 number: u8, 405 number: u8,
416} 406}
417unsafe_impl_unborrow!(AnyChannel); 407impl_peripheral!(AnyChannel);
418impl sealed::Channel for AnyChannel {} 408impl sealed::Channel for AnyChannel {}
419impl Channel for AnyChannel { 409impl Channel for AnyChannel {
420 fn number(&self) -> usize { 410 fn number(&self) -> usize {
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 3699ad0fa..ad6c16c1f 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -135,7 +135,7 @@ pub use chip::pac;
135pub(crate) use chip::pac; 135pub(crate) use chip::pac;
136pub use chip::{peripherals, Peripherals}; 136pub use chip::{peripherals, Peripherals};
137pub use embassy_cortex_m::executor; 137pub use embassy_cortex_m::executor;
138pub use embassy_hal_common::{unborrow, Unborrow}; 138pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
139pub use embassy_macros::cortex_m_interrupt as interrupt; 139pub use embassy_macros::cortex_m_interrupt as interrupt;
140 140
141pub mod config { 141pub mod config {
diff --git a/embassy-nrf/src/nvmc.rs b/embassy-nrf/src/nvmc.rs
index e350f8c99..cd6100339 100644
--- a/embassy-nrf/src/nvmc.rs
+++ b/embassy-nrf/src/nvmc.rs
@@ -1,15 +1,14 @@
1//! Nvmcerature sensor interface. 1//! Nvmcerature sensor interface.
2 2
3use core::marker::PhantomData;
4use core::{ptr, slice}; 3use core::{ptr, slice};
5 4
6use embassy_hal_common::unborrow; 5use embassy_hal_common::{into_ref, PeripheralRef};
7use embedded_storage::nor_flash::{ 6use embedded_storage::nor_flash::{
8 ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, 7 ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
9}; 8};
10 9
11use crate::peripherals::NVMC; 10use crate::peripherals::NVMC;
12use crate::{pac, Unborrow}; 11use crate::{pac, Peripheral};
13 12
14pub const PAGE_SIZE: usize = 4096; 13pub const PAGE_SIZE: usize = 4096;
15pub const FLASH_SIZE: usize = crate::chip::FLASH_SIZE; 14pub const FLASH_SIZE: usize = crate::chip::FLASH_SIZE;
@@ -31,14 +30,13 @@ impl NorFlashError for Error {
31} 30}
32 31
33pub struct Nvmc<'d> { 32pub struct Nvmc<'d> {
34 _p: PhantomData<&'d NVMC>, 33 _p: PeripheralRef<'d, NVMC>,
35} 34}
36 35
37impl<'d> Nvmc<'d> { 36impl<'d> Nvmc<'d> {
38 pub fn new(_p: impl Unborrow<Target = NVMC> + 'd) -> Self { 37 pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self {
39 unborrow!(_p); 38 into_ref!(_p);
40 39 Self { _p }
41 Self { _p: PhantomData }
42 } 40 }
43 41
44 fn regs() -> &'static pac::nvmc::RegisterBlock { 42 fn regs() -> &'static pac::nvmc::RegisterBlock {
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs
index d0bffb1e0..de856c0ca 100644
--- a/embassy-nrf/src/ppi/dppi.rs
+++ b/embassy-nrf/src/ppi/dppi.rs
@@ -1,9 +1,7 @@
1use core::marker::PhantomData; 1use embassy_hal_common::into_ref;
2
3use embassy_hal_common::unborrow;
4 2
5use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; 3use super::{Channel, ConfigurableChannel, Event, Ppi, Task};
6use crate::{pac, Unborrow}; 4use crate::{pac, Peripheral};
7 5
8const DPPI_ENABLE_BIT: u32 = 0x8000_0000; 6const DPPI_ENABLE_BIT: u32 = 0x8000_0000;
9const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; 7const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF;
@@ -13,13 +11,13 @@ fn regs() -> &'static pac::dppic::RegisterBlock {
13} 11}
14 12
15impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { 13impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
16 pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self { 14 pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event, task: Task) -> Self {
17 Ppi::new_many_to_many(ch, [event], [task]) 15 Ppi::new_many_to_many(ch, [event], [task])
18 } 16 }
19} 17}
20 18
21impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { 19impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
22 pub fn new_one_to_two(ch: impl Unborrow<Target = C> + 'd, event: Event, task1: Task, task2: Task) -> Self { 20 pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event, task1: Task, task2: Task) -> Self {
23 Ppi::new_many_to_many(ch, [event], [task1, task2]) 21 Ppi::new_many_to_many(ch, [event], [task1, task2])
24 } 22 }
25} 23}
@@ -28,11 +26,11 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi
28 Ppi<'d, C, EVENT_COUNT, TASK_COUNT> 26 Ppi<'d, C, EVENT_COUNT, TASK_COUNT>
29{ 27{
30 pub fn new_many_to_many( 28 pub fn new_many_to_many(
31 ch: impl Unborrow<Target = C> + 'd, 29 ch: impl Peripheral<P = C> + 'd,
32 events: [Event; EVENT_COUNT], 30 events: [Event; EVENT_COUNT],
33 tasks: [Task; TASK_COUNT], 31 tasks: [Task; TASK_COUNT],
34 ) -> Self { 32 ) -> Self {
35 unborrow!(ch); 33 into_ref!(ch);
36 34
37 let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK); 35 let val = DPPI_ENABLE_BIT | (ch.number() as u32 & DPPI_CHANNEL_MASK);
38 for task in tasks { 36 for task in tasks {
@@ -48,12 +46,7 @@ impl<'d, C: ConfigurableChannel, const EVENT_COUNT: usize, const TASK_COUNT: usi
48 unsafe { event.publish_reg().write_volatile(val) } 46 unsafe { event.publish_reg().write_volatile(val) }
49 } 47 }
50 48
51 Self { 49 Self { ch, events, tasks }
52 ch,
53 events,
54 tasks,
55 phantom: PhantomData,
56 }
57 } 50 }
58} 51}
59 52
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs
index 660db6410..23ab011bc 100644
--- a/embassy-nrf/src/ppi/mod.rs
+++ b/embassy-nrf/src/ppi/mod.rs
@@ -15,12 +15,11 @@
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::{impl_peripheral, PeripheralRef};
22 21
23use crate::{peripherals, Unborrow}; 22use crate::{peripherals, Peripheral};
24 23
25#[cfg(feature = "_dppi")] 24#[cfg(feature = "_dppi")]
26mod dppi; 25mod dppi;
@@ -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: PeripheralRef<'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>();
@@ -89,16 +87,16 @@ pub(crate) mod sealed {
89 pub trait Group {} 87 pub trait Group {}
90} 88}
91 89
92pub trait Channel: sealed::Channel + Unborrow<Target = Self> + Sized { 90pub trait Channel: sealed::Channel + Peripheral<P = Self> + Sized {
93 /// Returns the number of the channel 91 /// Returns the number of the channel
94 fn number(&self) -> usize; 92 fn number(&self) -> usize;
95} 93}
96 94
97pub trait ConfigurableChannel: Channel { 95pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> {
98 fn degrade(self) -> AnyConfigurableChannel; 96 fn degrade(self) -> AnyConfigurableChannel;
99} 97}
100 98
101pub trait StaticChannel: Channel { 99pub trait StaticChannel: Channel + Into<AnyStaticChannel> {
102 fn degrade(self) -> AnyStaticChannel; 100 fn degrade(self) -> AnyStaticChannel;
103} 101}
104 102
@@ -119,7 +117,7 @@ pub trait Group: sealed::Group + Sized {
119pub struct AnyStaticChannel { 117pub struct AnyStaticChannel {
120 pub(crate) number: u8, 118 pub(crate) number: u8,
121} 119}
122unsafe_impl_unborrow!(AnyStaticChannel); 120impl_peripheral!(AnyStaticChannel);
123impl sealed::Channel for AnyStaticChannel {} 121impl sealed::Channel for AnyStaticChannel {}
124impl Channel for AnyStaticChannel { 122impl Channel for AnyStaticChannel {
125 fn number(&self) -> usize { 123 fn number(&self) -> usize {
@@ -137,7 +135,7 @@ impl StaticChannel for AnyStaticChannel {
137pub struct AnyConfigurableChannel { 135pub struct AnyConfigurableChannel {
138 pub(crate) number: u8, 136 pub(crate) number: u8,
139} 137}
140unsafe_impl_unborrow!(AnyConfigurableChannel); 138impl_peripheral!(AnyConfigurableChannel);
141impl sealed::Channel for AnyConfigurableChannel {} 139impl sealed::Channel for AnyConfigurableChannel {}
142impl Channel for AnyConfigurableChannel { 140impl Channel for AnyConfigurableChannel {
143 fn number(&self) -> usize { 141 fn number(&self) -> usize {
@@ -169,6 +167,12 @@ macro_rules! impl_ppi_channel {
169 } 167 }
170 } 168 }
171 } 169 }
170
171 impl From<peripherals::$type> for crate::ppi::AnyStaticChannel {
172 fn from(val: peripherals::$type) -> Self {
173 crate::ppi::StaticChannel::degrade(val)
174 }
175 }
172 }; 176 };
173 ($type:ident, $number:expr => configurable) => { 177 ($type:ident, $number:expr => configurable) => {
174 impl_ppi_channel!($type, $number); 178 impl_ppi_channel!($type, $number);
@@ -180,6 +184,12 @@ macro_rules! impl_ppi_channel {
180 } 184 }
181 } 185 }
182 } 186 }
187
188 impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel {
189 fn from(val: peripherals::$type) -> Self {
190 crate::ppi::ConfigurableChannel::degrade(val)
191 }
192 }
183 }; 193 };
184} 194}
185 195
@@ -189,7 +199,7 @@ macro_rules! impl_ppi_channel {
189pub struct AnyGroup { 199pub struct AnyGroup {
190 number: u8, 200 number: u8,
191} 201}
192unsafe_impl_unborrow!(AnyGroup); 202impl_peripheral!(AnyGroup);
193impl sealed::Group for AnyGroup {} 203impl sealed::Group for AnyGroup {}
194impl Group for AnyGroup { 204impl Group for AnyGroup {
195 fn number(&self) -> usize { 205 fn number(&self) -> usize {
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs
index e5c86d444..450a290a2 100644
--- a/embassy-nrf/src/ppi/ppi.rs
+++ b/embassy-nrf/src/ppi/ppi.rs
@@ -1,9 +1,7 @@
1use core::marker::PhantomData; 1use embassy_hal_common::into_ref;
2
3use embassy_hal_common::unborrow;
4 2
5use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task}; 3use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};
6use crate::{pac, Unborrow}; 4use crate::{pac, Peripheral};
7 5
8impl Task { 6impl Task {
9 fn reg_val(&self) -> u32 { 7 fn reg_val(&self) -> u32 {
@@ -22,40 +20,34 @@ fn regs() -> &'static pac::ppi::RegisterBlock {
22 20
23#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task 21#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
24impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> { 22impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
25 pub fn new_zero_to_one(ch: impl Unborrow<Target = C> + 'd, task: Task) -> Self { 23 pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self {
26 unborrow!(ch); 24 into_ref!(ch);
27 25
28 let r = regs(); 26 let r = regs();
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
39impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { 34impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
40 pub fn new_one_to_one(ch: impl Unborrow<Target = C> + 'd, event: Event, task: Task) -> Self { 35 pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event, task: Task) -> Self {
41 unborrow!(ch); 36 into_ref!(ch);
42 37
43 let r = regs(); 38 let r = regs();
44 let n = ch.number(); 39 let n = ch.number();
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
55#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task 47#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
56impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { 48impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
57 pub fn new_one_to_two(ch: impl Unborrow<Target = C> + 'd, event: Event, task1: Task, task2: Task) -> Self { 49 pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event, task1: Task, task2: Task) -> Self {
58 unborrow!(ch); 50 into_ref!(ch);
59 51
60 let r = regs(); 52 let r = regs();
61 let n = ch.number(); 53 let n = ch.number();
@@ -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..5f750a91e 100644
--- a/embassy-nrf/src/pwm.rs
+++ b/embassy-nrf/src/pwm.rs
@@ -1,36 +1,35 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::marker::PhantomData;
4use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
5 4
6use embassy_hal_common::unborrow; 5use embassy_hal_common::{into_ref, PeripheralRef};
7 6
8use crate::gpio::sealed::Pin as _; 7use crate::gpio::sealed::Pin as _;
9use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; 8use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
10use crate::interrupt::Interrupt; 9use crate::interrupt::Interrupt;
11use crate::ppi::{Event, Task}; 10use crate::ppi::{Event, Task};
12use crate::util::slice_in_ram_or; 11use crate::util::slice_in_ram_or;
13use crate::{pac, Unborrow}; 12use crate::{pac, Peripheral};
14 13
15/// SimplePwm is the traditional pwm interface you're probably used to, allowing 14/// SimplePwm is the traditional pwm interface you're probably used to, allowing
16/// to simply set a duty cycle across up to four channels. 15/// to simply set a duty cycle across up to four channels.
17pub struct SimplePwm<'d, T: Instance> { 16pub struct SimplePwm<'d, T: Instance> {
18 phantom: PhantomData<&'d mut T>, 17 _peri: PeripheralRef<'d, T>,
19 duty: [u16; 4], 18 duty: [u16; 4],
20 ch0: Option<AnyPin>, 19 ch0: Option<PeripheralRef<'d, AnyPin>>,
21 ch1: Option<AnyPin>, 20 ch1: Option<PeripheralRef<'d, AnyPin>>,
22 ch2: Option<AnyPin>, 21 ch2: Option<PeripheralRef<'d, AnyPin>>,
23 ch3: Option<AnyPin>, 22 ch3: Option<PeripheralRef<'d, AnyPin>>,
24} 23}
25 24
26/// SequencePwm allows you to offload the updating of a sequence of duty cycles 25/// 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. 26/// to up to four channels, as well as repeat that sequence n times.
28pub struct SequencePwm<'d, T: Instance> { 27pub struct SequencePwm<'d, T: Instance> {
29 phantom: PhantomData<&'d mut T>, 28 _peri: PeripheralRef<'d, T>,
30 ch0: Option<AnyPin>, 29 ch0: Option<PeripheralRef<'d, AnyPin>>,
31 ch1: Option<AnyPin>, 30 ch1: Option<PeripheralRef<'d, AnyPin>>,
32 ch2: Option<AnyPin>, 31 ch2: Option<PeripheralRef<'d, AnyPin>>,
33 ch3: Option<AnyPin>, 32 ch3: Option<PeripheralRef<'d, AnyPin>>,
34} 33}
35 34
36#[derive(Debug, Clone, Copy, PartialEq, Eq)] 35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -51,41 +50,41 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
51 /// Create a new 1-channel PWM 50 /// Create a new 1-channel PWM
52 #[allow(unused_unsafe)] 51 #[allow(unused_unsafe)]
53 pub fn new_1ch( 52 pub fn new_1ch(
54 pwm: impl Unborrow<Target = T> + 'd, 53 pwm: impl Peripheral<P = T> + 'd,
55 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 54 ch0: impl Peripheral<P = impl GpioPin> + 'd,
56 config: Config, 55 config: Config,
57 ) -> Result<Self, Error> { 56 ) -> Result<Self, Error> {
58 unborrow!(ch0); 57 into_ref!(ch0);
59 Self::new_inner(pwm, Some(ch0.degrade()), None, None, None, config) 58 Self::new_inner(pwm, Some(ch0.map_into()), None, None, None, config)
60 } 59 }
61 60
62 /// Create a new 2-channel PWM 61 /// Create a new 2-channel PWM
63 #[allow(unused_unsafe)] 62 #[allow(unused_unsafe)]
64 pub fn new_2ch( 63 pub fn new_2ch(
65 pwm: impl Unborrow<Target = T> + 'd, 64 pwm: impl Peripheral<P = T> + 'd,
66 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 65 ch0: impl Peripheral<P = impl GpioPin> + 'd,
67 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 66 ch1: impl Peripheral<P = impl GpioPin> + 'd,
68 config: Config, 67 config: Config,
69 ) -> Result<Self, Error> { 68 ) -> Result<Self, Error> {
70 unborrow!(ch0, ch1); 69 into_ref!(ch0, ch1);
71 Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None, config) 70 Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None, config)
72 } 71 }
73 72
74 /// Create a new 3-channel PWM 73 /// Create a new 3-channel PWM
75 #[allow(unused_unsafe)] 74 #[allow(unused_unsafe)]
76 pub fn new_3ch( 75 pub fn new_3ch(
77 pwm: impl Unborrow<Target = T> + 'd, 76 pwm: impl Peripheral<P = T> + 'd,
78 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 77 ch0: impl Peripheral<P = impl GpioPin> + 'd,
79 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 78 ch1: impl Peripheral<P = impl GpioPin> + 'd,
80 ch2: impl Unborrow<Target = impl GpioPin> + 'd, 79 ch2: impl Peripheral<P = impl GpioPin> + 'd,
81 config: Config, 80 config: Config,
82 ) -> Result<Self, Error> { 81 ) -> Result<Self, Error> {
83 unborrow!(ch0, ch1, ch2); 82 into_ref!(ch0, ch1, ch2);
84 Self::new_inner( 83 Self::new_inner(
85 pwm, 84 pwm,
86 Some(ch0.degrade()), 85 Some(ch0.map_into()),
87 Some(ch1.degrade()), 86 Some(ch1.map_into()),
88 Some(ch2.degrade()), 87 Some(ch2.map_into()),
89 None, 88 None,
90 config, 89 config,
91 ) 90 )
@@ -94,32 +93,34 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
94 /// Create a new 4-channel PWM 93 /// Create a new 4-channel PWM
95 #[allow(unused_unsafe)] 94 #[allow(unused_unsafe)]
96 pub fn new_4ch( 95 pub fn new_4ch(
97 pwm: impl Unborrow<Target = T> + 'd, 96 pwm: impl Peripheral<P = T> + 'd,
98 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 97 ch0: impl Peripheral<P = impl GpioPin> + 'd,
99 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 98 ch1: impl Peripheral<P = impl GpioPin> + 'd,
100 ch2: impl Unborrow<Target = impl GpioPin> + 'd, 99 ch2: impl Peripheral<P = impl GpioPin> + 'd,
101 ch3: impl Unborrow<Target = impl GpioPin> + 'd, 100 ch3: impl Peripheral<P = impl GpioPin> + 'd,
102 config: Config, 101 config: Config,
103 ) -> Result<Self, Error> { 102 ) -> Result<Self, Error> {
104 unborrow!(ch0, ch1, ch2, ch3); 103 into_ref!(ch0, ch1, ch2, ch3);
105 Self::new_inner( 104 Self::new_inner(
106 pwm, 105 pwm,
107 Some(ch0.degrade()), 106 Some(ch0.map_into()),
108 Some(ch1.degrade()), 107 Some(ch1.map_into()),
109 Some(ch2.degrade()), 108 Some(ch2.map_into()),
110 Some(ch3.degrade()), 109 Some(ch3.map_into()),
111 config, 110 config,
112 ) 111 )
113 } 112 }
114 113
115 fn new_inner( 114 fn new_inner(
116 _pwm: impl Unborrow<Target = T> + 'd, 115 _pwm: impl Peripheral<P = T> + 'd,
117 ch0: Option<AnyPin>, 116 ch0: Option<PeripheralRef<'d, AnyPin>>,
118 ch1: Option<AnyPin>, 117 ch1: Option<PeripheralRef<'d, AnyPin>>,
119 ch2: Option<AnyPin>, 118 ch2: Option<PeripheralRef<'d, AnyPin>>,
120 ch3: Option<AnyPin>, 119 ch3: Option<PeripheralRef<'d, AnyPin>>,
121 config: Config, 120 config: Config,
122 ) -> Result<Self, Error> { 121 ) -> Result<Self, Error> {
122 into_ref!(_pwm);
123
123 let r = T::regs(); 124 let r = T::regs();
124 125
125 if let Some(pin) = &ch0 { 126 if let Some(pin) = &ch0 {
@@ -168,7 +169,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
168 r.countertop.write(|w| unsafe { w.countertop().bits(config.max_duty) }); 169 r.countertop.write(|w| unsafe { w.countertop().bits(config.max_duty) });
169 170
170 Ok(Self { 171 Ok(Self {
171 phantom: PhantomData, 172 _peri: _pwm,
172 ch0, 173 ch0,
173 ch1, 174 ch1,
174 ch2, 175 ch2,
@@ -573,60 +574,74 @@ pub enum CounterMode {
573impl<'d, T: Instance> SimplePwm<'d, T> { 574impl<'d, T: Instance> SimplePwm<'d, T> {
574 /// Create a new 1-channel PWM 575 /// Create a new 1-channel PWM
575 #[allow(unused_unsafe)] 576 #[allow(unused_unsafe)]
576 pub fn new_1ch(pwm: impl Unborrow<Target = T> + 'd, ch0: impl Unborrow<Target = impl GpioPin> + 'd) -> Self { 577 pub fn new_1ch(pwm: impl Peripheral<P = T> + 'd, ch0: impl Peripheral<P = impl GpioPin> + 'd) -> Self {
577 unborrow!(ch0); 578 unsafe {
578 Self::new_inner(pwm, Some(ch0.degrade()), None, None, None) 579 into_ref!(ch0);
580 Self::new_inner(pwm, Some(ch0.map_into()), None, None, None)
581 }
579 } 582 }
580 583
581 /// Create a new 2-channel PWM 584 /// Create a new 2-channel PWM
582 #[allow(unused_unsafe)] 585 #[allow(unused_unsafe)]
583 pub fn new_2ch( 586 pub fn new_2ch(
584 pwm: impl Unborrow<Target = T> + 'd, 587 pwm: impl Peripheral<P = T> + 'd,
585 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 588 ch0: impl Peripheral<P = impl GpioPin> + 'd,
586 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 589 ch1: impl Peripheral<P = impl GpioPin> + 'd,
587 ) -> Self { 590 ) -> Self {
588 unborrow!(ch0, ch1); 591 into_ref!(ch0, ch1);
589 Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), None, None) 592 Self::new_inner(pwm, Some(ch0.map_into()), Some(ch1.map_into()), None, None)
590 } 593 }
591 594
592 /// Create a new 3-channel PWM 595 /// Create a new 3-channel PWM
593 #[allow(unused_unsafe)] 596 #[allow(unused_unsafe)]
594 pub fn new_3ch( 597 pub fn new_3ch(
595 pwm: impl Unborrow<Target = T> + 'd, 598 pwm: impl Peripheral<P = T> + 'd,
596 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 599 ch0: impl Peripheral<P = impl GpioPin> + 'd,
597 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 600 ch1: impl Peripheral<P = impl GpioPin> + 'd,
598 ch2: impl Unborrow<Target = impl GpioPin> + 'd, 601 ch2: impl Peripheral<P = impl GpioPin> + 'd,
599 ) -> Self { 602 ) -> Self {
600 unborrow!(ch0, ch1, ch2); 603 unsafe {
601 Self::new_inner(pwm, Some(ch0.degrade()), Some(ch1.degrade()), Some(ch2.degrade()), None) 604 into_ref!(ch0, ch1, ch2);
605 Self::new_inner(
606 pwm,
607 Some(ch0.map_into()),
608 Some(ch1.map_into()),
609 Some(ch2.map_into()),
610 None,
611 )
612 }
602 } 613 }
603 614
604 /// Create a new 4-channel PWM 615 /// Create a new 4-channel PWM
605 #[allow(unused_unsafe)] 616 #[allow(unused_unsafe)]
606 pub fn new_4ch( 617 pub fn new_4ch(
607 pwm: impl Unborrow<Target = T> + 'd, 618 pwm: impl Peripheral<P = T> + 'd,
608 ch0: impl Unborrow<Target = impl GpioPin> + 'd, 619 ch0: impl Peripheral<P = impl GpioPin> + 'd,
609 ch1: impl Unborrow<Target = impl GpioPin> + 'd, 620 ch1: impl Peripheral<P = impl GpioPin> + 'd,
610 ch2: impl Unborrow<Target = impl GpioPin> + 'd, 621 ch2: impl Peripheral<P = impl GpioPin> + 'd,
611 ch3: impl Unborrow<Target = impl GpioPin> + 'd, 622 ch3: impl Peripheral<P = impl GpioPin> + 'd,
612 ) -> Self { 623 ) -> Self {
613 unborrow!(ch0, ch1, ch2, ch3); 624 unsafe {
614 Self::new_inner( 625 into_ref!(ch0, ch1, ch2, ch3);
615 pwm, 626 Self::new_inner(
616 Some(ch0.degrade()), 627 pwm,
617 Some(ch1.degrade()), 628 Some(ch0.map_into()),
618 Some(ch2.degrade()), 629 Some(ch1.map_into()),
619 Some(ch3.degrade()), 630 Some(ch2.map_into()),
620 ) 631 Some(ch3.map_into()),
632 )
633 }
621 } 634 }
622 635
623 fn new_inner( 636 fn new_inner(
624 _pwm: impl Unborrow<Target = T> + 'd, 637 _pwm: impl Peripheral<P = T> + 'd,
625 ch0: Option<AnyPin>, 638 ch0: Option<PeripheralRef<'d, AnyPin>>,
626 ch1: Option<AnyPin>, 639 ch1: Option<PeripheralRef<'d, AnyPin>>,
627 ch2: Option<AnyPin>, 640 ch2: Option<PeripheralRef<'d, AnyPin>>,
628 ch3: Option<AnyPin>, 641 ch3: Option<PeripheralRef<'d, AnyPin>>,
629 ) -> Self { 642 ) -> Self {
643 into_ref!(_pwm);
644
630 let r = T::regs(); 645 let r = T::regs();
631 646
632 if let Some(pin) = &ch0 { 647 if let Some(pin) = &ch0 {
@@ -654,7 +669,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
654 r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) }); 669 r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) });
655 670
656 let pwm = Self { 671 let pwm = Self {
657 phantom: PhantomData, 672 _peri: _pwm,
658 ch0, 673 ch0,
659 ch1, 674 ch1,
660 ch2, 675 ch2,
@@ -813,7 +828,7 @@ pub(crate) mod sealed {
813 } 828 }
814} 829}
815 830
816pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { 831pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
817 type Interrupt: Interrupt; 832 type Interrupt: Interrupt;
818} 833}
819 834
diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs
index e254328a6..f6daec252 100644
--- a/embassy-nrf/src/qdec.rs
+++ b/embassy-nrf/src/qdec.rs
@@ -1,21 +1,20 @@
1//! Quadrature decoder interface 1//! Quadrature decoder 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::unborrow; 6use embassy_hal_common::{into_ref, PeripheralRef};
8use futures::future::poll_fn; 7use futures::future::poll_fn;
9 8
10use crate::gpio::sealed::Pin as _; 9use crate::gpio::sealed::Pin as _;
11use crate::gpio::{AnyPin, Pin as GpioPin}; 10use crate::gpio::{AnyPin, Pin as GpioPin};
12use crate::interrupt::InterruptExt; 11use crate::interrupt::InterruptExt;
13use crate::peripherals::QDEC; 12use crate::peripherals::QDEC;
14use crate::{interrupt, pac, Unborrow}; 13use crate::{interrupt, pac, Peripheral};
15 14
16/// Quadrature decoder 15/// Quadrature decoder
17pub struct Qdec<'d> { 16pub struct Qdec<'d> {
18 phantom: PhantomData<&'d QDEC>, 17 _p: PeripheralRef<'d, QDEC>,
19} 18}
20 19
21#[non_exhaustive] 20#[non_exhaustive]
@@ -43,37 +42,37 @@ static WAKER: AtomicWaker = AtomicWaker::new();
43 42
44impl<'d> Qdec<'d> { 43impl<'d> Qdec<'d> {
45 pub fn new( 44 pub fn new(
46 qdec: impl Unborrow<Target = QDEC> + 'd, 45 qdec: impl Peripheral<P = QDEC> + 'd,
47 irq: impl Unborrow<Target = interrupt::QDEC> + 'd, 46 irq: impl Peripheral<P = interrupt::QDEC> + 'd,
48 a: impl Unborrow<Target = impl GpioPin> + 'd, 47 a: impl Peripheral<P = impl GpioPin> + 'd,
49 b: impl Unborrow<Target = impl GpioPin> + 'd, 48 b: impl Peripheral<P = impl GpioPin> + 'd,
50 config: Config, 49 config: Config,
51 ) -> Self { 50 ) -> Self {
52 unborrow!(a, b); 51 into_ref!(a, b);
53 Self::new_inner(qdec, irq, a.degrade(), b.degrade(), None, config) 52 Self::new_inner(qdec, irq, a.map_into(), b.map_into(), None, config)
54 } 53 }
55 54
56 pub fn new_with_led( 55 pub fn new_with_led(
57 qdec: impl Unborrow<Target = QDEC> + 'd, 56 qdec: impl Peripheral<P = QDEC> + 'd,
58 irq: impl Unborrow<Target = interrupt::QDEC> + 'd, 57 irq: impl Peripheral<P = interrupt::QDEC> + 'd,
59 a: impl Unborrow<Target = impl GpioPin> + 'd, 58 a: impl Peripheral<P = impl GpioPin> + 'd,
60 b: impl Unborrow<Target = impl GpioPin> + 'd, 59 b: impl Peripheral<P = impl GpioPin> + 'd,
61 led: impl Unborrow<Target = impl GpioPin> + 'd, 60 led: impl Peripheral<P = impl GpioPin> + 'd,
62 config: Config, 61 config: Config,
63 ) -> Self { 62 ) -> Self {
64 unborrow!(a, b, led); 63 into_ref!(a, b, led);
65 Self::new_inner(qdec, irq, a.degrade(), b.degrade(), Some(led.degrade()), config) 64 Self::new_inner(qdec, irq, a.map_into(), b.map_into(), Some(led.map_into()), config)
66 } 65 }
67 66
68 fn new_inner( 67 fn new_inner(
69 _t: impl Unborrow<Target = QDEC> + 'd, 68 p: impl Peripheral<P = QDEC> + 'd,
70 irq: impl Unborrow<Target = interrupt::QDEC> + 'd, 69 irq: impl Peripheral<P = interrupt::QDEC> + 'd,
71 a: AnyPin, 70 a: PeripheralRef<'d, AnyPin>,
72 b: AnyPin, 71 b: PeripheralRef<'d, AnyPin>,
73 led: Option<AnyPin>, 72 led: Option<PeripheralRef<'d, AnyPin>>,
74 config: Config, 73 config: Config,
75 ) -> Self { 74 ) -> Self {
76 unborrow!(irq); 75 into_ref!(p, irq);
77 let r = Self::regs(); 76 let r = Self::regs();
78 77
79 // Select pins. 78 // Select pins.
@@ -131,7 +130,7 @@ impl<'d> Qdec<'d> {
131 }); 130 });
132 irq.enable(); 131 irq.enable();
133 132
134 Self { phantom: PhantomData } 133 Self { _p: p }
135 } 134 }
136 135
137 /// Perform an asynchronous read of the decoder. 136 /// Perform an asynchronous read of the decoder.
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 92fa79b8a..67634b5b7 100644
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -1,20 +1,18 @@
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::{into_ref, PeripheralRef};
9use futures::future::poll_fn; 8use futures::future::poll_fn;
10 9
11use crate::gpio::sealed::Pin as _;
12use crate::gpio::{self, Pin as GpioPin}; 10use crate::gpio::{self, Pin as GpioPin};
13use crate::interrupt::{Interrupt, InterruptExt}; 11use crate::interrupt::{Interrupt, InterruptExt};
14pub use crate::pac::qspi::ifconfig0::{ 12pub use crate::pac::qspi::ifconfig0::{
15 ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode, 13 ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode,
16}; 14};
17use crate::{pac, Unborrow}; 15use crate::{pac, Peripheral};
18 16
19// TODO 17// TODO
20// - config: 18// - config:
@@ -63,38 +61,38 @@ pub enum Error {
63} 61}
64 62
65pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> { 63pub struct Qspi<'d, T: Instance, const FLASH_SIZE: usize> {
66 irq: T::Interrupt, 64 irq: PeripheralRef<'d, T::Interrupt>,
67 dpm_enabled: bool, 65 dpm_enabled: bool,
68 phantom: PhantomData<&'d mut T>,
69} 66}
70 67
71impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> { 68impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
72 pub fn new( 69 pub fn new(
73 _qspi: impl Unborrow<Target = T> + 'd, 70 _qspi: impl Peripheral<P = T> + 'd,
74 irq: impl Unborrow<Target = T::Interrupt> + 'd, 71 irq: impl Peripheral<P = T::Interrupt> + 'd,
75 sck: impl Unborrow<Target = impl GpioPin> + 'd, 72 sck: impl Peripheral<P = impl GpioPin> + 'd,
76 csn: impl Unborrow<Target = impl GpioPin> + 'd, 73 csn: impl Peripheral<P = impl GpioPin> + 'd,
77 io0: impl Unborrow<Target = impl GpioPin> + 'd, 74 io0: impl Peripheral<P = impl GpioPin> + 'd,
78 io1: impl Unborrow<Target = impl GpioPin> + 'd, 75 io1: impl Peripheral<P = impl GpioPin> + 'd,
79 io2: impl Unborrow<Target = impl GpioPin> + 'd, 76 io2: impl Peripheral<P = impl GpioPin> + 'd,
80 io3: impl Unborrow<Target = impl GpioPin> + 'd, 77 io3: impl Peripheral<P = impl GpioPin> + 'd,
81 config: Config, 78 config: Config,
82 ) -> Qspi<'d, T, FLASH_SIZE> { 79 ) -> Qspi<'d, T, FLASH_SIZE> {
83 unborrow!(irq, sck, csn, io0, io1, io2, io3); 80 into_ref!(irq, sck, csn, io0, io1, io2, io3);
84 81
85 let r = T::regs(); 82 let r = T::regs();
86 83
87 let sck = sck.degrade(); 84 sck.set_high();
88 let csn = csn.degrade(); 85 csn.set_high();
89 let io0 = io0.degrade(); 86 io0.set_high();
90 let io1 = io1.degrade(); 87 io1.set_high();
91 let io2 = io2.degrade(); 88 io2.set_high();
92 let io3 = io3.degrade(); 89 io3.set_high();
93 90 sck.conf().write(|w| w.dir().output().drive().h0h1());
94 for pin in [&sck, &csn, &io0, &io1, &io2, &io3] { 91 csn.conf().write(|w| w.dir().output().drive().h0h1());
95 pin.set_high(); 92 io0.conf().write(|w| w.dir().output().drive().h0h1());
96 pin.conf().write(|w| w.dir().output().drive().h0h1()); 93 io1.conf().write(|w| w.dir().output().drive().h0h1());
97 } 94 io2.conf().write(|w| w.dir().output().drive().h0h1());
95 io3.conf().write(|w| w.dir().output().drive().h0h1());
98 96
99 r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); 97 r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) });
100 r.psel.csn.write(|w| unsafe { w.bits(csn.psel_bits()) }); 98 r.psel.csn.write(|w| unsafe { w.bits(csn.psel_bits()) });
@@ -143,7 +141,6 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Qspi<'d, T, FLASH_SIZE> {
143 let mut res = Self { 141 let mut res = Self {
144 dpm_enabled: config.deep_power_down.is_some(), 142 dpm_enabled: config.deep_power_down.is_some(),
145 irq, 143 irq,
146 phantom: PhantomData,
147 }; 144 };
148 145
149 r.events_ready.reset(); 146 r.events_ready.reset();
@@ -536,7 +533,7 @@ pub(crate) mod sealed {
536 } 533 }
537} 534}
538 535
539pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { 536pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
540 type Interrupt: Interrupt; 537 type Interrupt: Interrupt;
541} 538}
542 539
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index e68ed912e..9bebd6fa3 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -1,16 +1,15 @@
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::{into_ref, PeripheralRef};
9use futures::future::poll_fn; 8use futures::future::poll_fn;
10 9
11use crate::interrupt::InterruptExt; 10use crate::interrupt::InterruptExt;
12use crate::peripherals::RNG; 11use crate::peripherals::RNG;
13use crate::{interrupt, pac, Unborrow}; 12use crate::{interrupt, pac, Peripheral};
14 13
15impl RNG { 14impl RNG {
16 fn regs() -> &'static pac::rng::RegisterBlock { 15 fn regs() -> &'static pac::rng::RegisterBlock {
@@ -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: PeripheralRef<'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> {
@@ -45,13 +43,10 @@ impl<'d> Rng<'d> {
45 /// e.g. using `mem::forget`. 43 /// e.g. using `mem::forget`.
46 /// 44 ///
47 /// The synchronous API is safe. 45 /// The synchronous API is safe.
48 pub fn new(_rng: impl Unborrow<Target = RNG> + 'd, irq: impl Unborrow<Target = interrupt::RNG> + 'd) -> Self { 46 pub fn new(_rng: impl Peripheral<P = RNG> + 'd, irq: impl Peripheral<P = interrupt::RNG> + 'd) -> Self {
49 unborrow!(irq); 47 into_ref!(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..6ddc70e52 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -1,11 +1,10 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::marker::PhantomData;
4use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 4use core::task::Poll;
6 5
7use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
8use embassy_hal_common::unborrow; 7use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
9use futures::future::poll_fn; 8use futures::future::poll_fn;
10use pac::{saadc, SAADC}; 9use pac::{saadc, SAADC};
11use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; 10use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A};
@@ -14,10 +13,11 @@ pub(crate) use saadc::ch::pselp::PSELP_A as InputChannel;
14use saadc::oversample::OVERSAMPLE_A; 13use saadc::oversample::OVERSAMPLE_A;
15use saadc::resolution::VAL_A; 14use saadc::resolution::VAL_A;
16 15
16use self::sealed::Input as _;
17use crate::interrupt::InterruptExt; 17use crate::interrupt::InterruptExt;
18use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; 18use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
19use crate::timer::{Frequency, Instance as TimerInstance, Timer}; 19use crate::timer::{Frequency, Instance as TimerInstance, Timer};
20use crate::{interrupt, pac, peripherals, Unborrow}; 20use crate::{interrupt, pac, peripherals, Peripheral};
21 21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)] 22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))] 23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -26,7 +26,7 @@ pub enum Error {}
26 26
27/// One-shot and continuous SAADC. 27/// One-shot and continuous SAADC.
28pub struct Saadc<'d, const N: usize> { 28pub struct Saadc<'d, const N: usize> {
29 phantom: PhantomData<&'d mut peripherals::SAADC>, 29 _p: PeripheralRef<'d, peripherals::SAADC>,
30} 30}
31 31
32static WAKER: AtomicWaker = AtomicWaker::new(); 32static WAKER: AtomicWaker = AtomicWaker::new();
@@ -66,106 +66,37 @@ pub struct ChannelConfig<'d> {
66 /// Acquisition time in microseconds. 66 /// Acquisition time in microseconds.
67 pub time: Time, 67 pub time: Time,
68 /// Positive channel to sample 68 /// Positive channel to sample
69 p_channel: InputChannel, 69 p_channel: PeripheralRef<'d, AnyInput>,
70 /// An optional negative channel to sample 70 /// An optional negative channel to sample
71 n_channel: Option<InputChannel>, 71 n_channel: Option<PeripheralRef<'d, AnyInput>>,
72
73 phantom: PhantomData<&'d ()>,
74}
75
76/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
77/// internal voltage.
78pub struct VddInput;
79
80unsafe impl Unborrow for VddInput {
81 type Target = VddInput;
82 unsafe fn unborrow(self) -> Self::Target {
83 self
84 }
85}
86
87impl sealed::Input for VddInput {
88 #[cfg(not(feature = "_nrf9160"))]
89 fn channel(&self) -> InputChannel {
90 InputChannel::VDD
91 }
92 #[cfg(feature = "_nrf9160")]
93 fn channel(&self) -> InputChannel {
94 InputChannel::VDDGPIO
95 }
96}
97impl Input for VddInput {}
98
99/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
100/// VDDH / 5 voltage.
101#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
102pub struct VddhDiv5Input;
103
104#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
105unsafe impl Unborrow for VddhDiv5Input {
106 type Target = VddhDiv5Input;
107 unsafe fn unborrow(self) -> Self::Target {
108 self
109 }
110}
111
112#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
113impl sealed::Input for VddhDiv5Input {
114 fn channel(&self) -> InputChannel {
115 InputChannel::VDDHDIV5
116 }
117}
118
119#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
120impl Input for VddhDiv5Input {}
121
122pub struct AnyInput {
123 channel: InputChannel,
124}
125
126unsafe impl Unborrow for AnyInput {
127 type Target = AnyInput;
128 unsafe fn unborrow(self) -> Self::Target {
129 self
130 }
131}
132
133impl sealed::Input for AnyInput {
134 fn channel(&self) -> InputChannel {
135 self.channel
136 }
137} 72}
138 73
139impl Input for AnyInput {}
140
141impl<'d> ChannelConfig<'d> { 74impl<'d> ChannelConfig<'d> {
142 /// Default configuration for single ended channel sampling. 75 /// Default configuration for single ended channel sampling.
143 pub fn single_ended(input: impl Unborrow<Target = impl Input> + 'd) -> Self { 76 pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self {
144 unborrow!(input); 77 into_ref!(input);
145 Self { 78 Self {
146 reference: Reference::INTERNAL, 79 reference: Reference::INTERNAL,
147 gain: Gain::GAIN1_6, 80 gain: Gain::GAIN1_6,
148 resistor: Resistor::BYPASS, 81 resistor: Resistor::BYPASS,
149 time: Time::_10US, 82 time: Time::_10US,
150 p_channel: input.channel(), 83 p_channel: input.map_into(),
151 n_channel: None, 84 n_channel: None,
152 phantom: PhantomData,
153 } 85 }
154 } 86 }
155 /// Default configuration for differential channel sampling. 87 /// Default configuration for differential channel sampling.
156 pub fn differential( 88 pub fn differential(
157 p_input: impl Unborrow<Target = impl Input> + 'd, 89 p_input: impl Peripheral<P = impl Input> + 'd,
158 n_input: impl Unborrow<Target = impl Input> + 'd, 90 n_input: impl Peripheral<P = impl Input> + 'd,
159 ) -> Self { 91 ) -> Self {
160 unborrow!(p_input, n_input); 92 into_ref!(p_input, n_input);
161 Self { 93 Self {
162 reference: Reference::INTERNAL, 94 reference: Reference::INTERNAL,
163 gain: Gain::GAIN1_6, 95 gain: Gain::GAIN1_6,
164 resistor: Resistor::BYPASS, 96 resistor: Resistor::BYPASS,
165 time: Time::_10US, 97 time: Time::_10US,
166 p_channel: p_input.channel(), 98 p_channel: p_input.map_into(),
167 n_channel: Some(n_input.channel()), 99 n_channel: Some(n_input.map_into()),
168 phantom: PhantomData,
169 } 100 }
170 } 101 }
171} 102}
@@ -182,12 +113,12 @@ pub enum SamplerState {
182 113
183impl<'d, const N: usize> Saadc<'d, N> { 114impl<'d, const N: usize> Saadc<'d, N> {
184 pub fn new( 115 pub fn new(
185 _saadc: impl Unborrow<Target = peripherals::SAADC> + 'd, 116 saadc: impl Peripheral<P = peripherals::SAADC> + 'd,
186 irq: impl Unborrow<Target = interrupt::SAADC> + 'd, 117 irq: impl Peripheral<P = interrupt::SAADC> + 'd,
187 config: Config, 118 config: Config,
188 channel_configs: [ChannelConfig; N], 119 channel_configs: [ChannelConfig; N],
189 ) -> Self { 120 ) -> Self {
190 unborrow!(irq); 121 into_ref!(saadc, irq);
191 122
192 let r = unsafe { &*SAADC::ptr() }; 123 let r = unsafe { &*SAADC::ptr() };
193 124
@@ -199,9 +130,11 @@ impl<'d, const N: usize> Saadc<'d, N> {
199 r.oversample.write(|w| w.oversample().variant(oversample.into())); 130 r.oversample.write(|w| w.oversample().variant(oversample.into()));
200 131
201 for (i, cc) in channel_configs.iter().enumerate() { 132 for (i, cc) in channel_configs.iter().enumerate() {
202 r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel)); 133 r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel.channel()));
203 if let Some(n_channel) = cc.n_channel { 134 if let Some(n_channel) = &cc.n_channel {
204 r.ch[i].pseln.write(|w| unsafe { w.pseln().bits(n_channel as u8) }); 135 r.ch[i]
136 .pseln
137 .write(|w| unsafe { w.pseln().bits(n_channel.channel() as u8) });
205 } 138 }
206 r.ch[i].config.write(|w| { 139 r.ch[i].config.write(|w| {
207 w.refsel().variant(cc.reference.into()); 140 w.refsel().variant(cc.reference.into());
@@ -230,7 +163,7 @@ impl<'d, const N: usize> Saadc<'d, N> {
230 irq.unpend(); 163 irq.unpend();
231 irq.enable(); 164 irq.enable();
232 165
233 Self { phantom: PhantomData } 166 Self { _p: saadc }
234 } 167 }
235 168
236 fn on_interrupt(_ctx: *mut ()) { 169 fn on_interrupt(_ctx: *mut ()) {
@@ -689,7 +622,7 @@ pub(crate) mod sealed {
689} 622}
690 623
691/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. 624/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal.
692pub trait Input: sealed::Input + Unborrow<Target = Self> + Sized { 625pub trait Input: sealed::Input + Into<AnyInput> + Peripheral<P = Self> + Sized + 'static {
693 fn degrade_saadc(self) -> AnyInput { 626 fn degrade_saadc(self) -> AnyInput {
694 AnyInput { 627 AnyInput {
695 channel: self.channel(), 628 channel: self.channel(),
@@ -697,13 +630,57 @@ pub trait Input: sealed::Input + Unborrow<Target = Self> + Sized {
697 } 630 }
698} 631}
699 632
633pub struct AnyInput {
634 channel: InputChannel,
635}
636
637impl_peripheral!(AnyInput);
638
639impl sealed::Input for AnyInput {
640 fn channel(&self) -> InputChannel {
641 self.channel
642 }
643}
644
645impl Input for AnyInput {}
646
700macro_rules! impl_saadc_input { 647macro_rules! impl_saadc_input {
701 ($pin:ident, $ch:ident) => { 648 ($pin:ident, $ch:ident) => {
702 impl crate::saadc::sealed::Input for crate::peripherals::$pin { 649 impl_saadc_input!(@local, crate::peripherals::$pin, $ch);
650 };
651 (@local, $pin:ty, $ch:ident) => {
652 impl crate::saadc::sealed::Input for $pin {
703 fn channel(&self) -> crate::saadc::InputChannel { 653 fn channel(&self) -> crate::saadc::InputChannel {
704 crate::saadc::InputChannel::$ch 654 crate::saadc::InputChannel::$ch
705 } 655 }
706 } 656 }
707 impl crate::saadc::Input for crate::peripherals::$pin {} 657 impl crate::saadc::Input for $pin {}
658
659 impl From<$pin> for crate::saadc::AnyInput {
660 fn from(val: $pin) -> Self {
661 crate::saadc::Input::degrade_saadc(val)
662 }
663 }
708 }; 664 };
709} 665}
666
667/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
668/// internal voltage.
669pub struct VddInput;
670
671impl_peripheral!(VddInput);
672#[cfg(not(feature = "_nrf9160"))]
673impl_saadc_input!(@local, VddInput, VDD);
674#[cfg(feature = "_nrf9160")]
675impl_saadc_input!(@local, VddInput, VDDGPIO);
676
677/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
678/// VDDH / 5 voltage.
679#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
680pub struct VddhDiv5Input;
681
682#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
683impl_peripheral!(VddhDiv5Input);
684
685#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
686impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5);
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index d34d9a0c8..a512b4813 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -1,11 +1,10 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::marker::PhantomData;
4use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 4use core::task::Poll;
6 5
7use embassy_embedded_hal::SetConfig; 6use embassy_embedded_hal::SetConfig;
8use embassy_hal_common::unborrow; 7use embassy_hal_common::{into_ref, PeripheralRef};
9pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 8pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
10use futures::future::poll_fn; 9use futures::future::poll_fn;
11pub use pac::spim0::frequency::FREQUENCY_A as Frequency; 10pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
@@ -15,7 +14,7 @@ use crate::gpio::sealed::Pin as _;
15use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; 14use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
16use crate::interrupt::{Interrupt, InterruptExt}; 15use crate::interrupt::{Interrupt, InterruptExt};
17use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; 16use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
18use crate::{pac, Unborrow}; 17use crate::{pac, Peripheral};
19 18
20#[derive(Debug, Clone, Copy, PartialEq, Eq)] 19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21#[cfg_attr(feature = "defmt", derive(defmt::Format))] 20#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -31,7 +30,7 @@ pub enum Error {
31/// 30///
32/// For more details about EasyDMA, consult the module documentation. 31/// For more details about EasyDMA, consult the module documentation.
33pub struct Spim<'d, T: Instance> { 32pub struct Spim<'d, T: Instance> {
34 phantom: PhantomData<&'d mut T>, 33 _p: PeripheralRef<'d, T>,
35} 34}
36 35
37#[non_exhaustive] 36#[non_exhaustive]
@@ -53,55 +52,55 @@ impl Default for Config {
53 52
54impl<'d, T: Instance> Spim<'d, T> { 53impl<'d, T: Instance> Spim<'d, T> {
55 pub fn new( 54 pub fn new(
56 spim: impl Unborrow<Target = T> + 'd, 55 spim: impl Peripheral<P = T> + 'd,
57 irq: impl Unborrow<Target = T::Interrupt> + 'd, 56 irq: impl Peripheral<P = T::Interrupt> + 'd,
58 sck: impl Unborrow<Target = impl GpioPin> + 'd, 57 sck: impl Peripheral<P = impl GpioPin> + 'd,
59 miso: impl Unborrow<Target = impl GpioPin> + 'd, 58 miso: impl Peripheral<P = impl GpioPin> + 'd,
60 mosi: impl Unborrow<Target = impl GpioPin> + 'd, 59 mosi: impl Peripheral<P = impl GpioPin> + 'd,
61 config: Config, 60 config: Config,
62 ) -> Self { 61 ) -> Self {
63 unborrow!(sck, miso, mosi); 62 into_ref!(sck, miso, mosi);
64 Self::new_inner( 63 Self::new_inner(
65 spim, 64 spim,
66 irq, 65 irq,
67 sck.degrade(), 66 sck.map_into(),
68 Some(miso.degrade()), 67 Some(miso.map_into()),
69 Some(mosi.degrade()), 68 Some(mosi.map_into()),
70 config, 69 config,
71 ) 70 )
72 } 71 }
73 72
74 pub fn new_txonly( 73 pub fn new_txonly(
75 spim: impl Unborrow<Target = T> + 'd, 74 spim: impl Peripheral<P = T> + 'd,
76 irq: impl Unborrow<Target = T::Interrupt> + 'd, 75 irq: impl Peripheral<P = T::Interrupt> + 'd,
77 sck: impl Unborrow<Target = impl GpioPin> + 'd, 76 sck: impl Peripheral<P = impl GpioPin> + 'd,
78 mosi: impl Unborrow<Target = impl GpioPin> + 'd, 77 mosi: impl Peripheral<P = impl GpioPin> + 'd,
79 config: Config, 78 config: Config,
80 ) -> Self { 79 ) -> Self {
81 unborrow!(sck, mosi); 80 into_ref!(sck, mosi);
82 Self::new_inner(spim, irq, sck.degrade(), None, Some(mosi.degrade()), config) 81 Self::new_inner(spim, irq, sck.map_into(), None, Some(mosi.map_into()), config)
83 } 82 }
84 83
85 pub fn new_rxonly( 84 pub fn new_rxonly(
86 spim: impl Unborrow<Target = T> + 'd, 85 spim: impl Peripheral<P = T> + 'd,
87 irq: impl Unborrow<Target = T::Interrupt> + 'd, 86 irq: impl Peripheral<P = T::Interrupt> + 'd,
88 sck: impl Unborrow<Target = impl GpioPin> + 'd, 87 sck: impl Peripheral<P = impl GpioPin> + 'd,
89 miso: impl Unborrow<Target = impl GpioPin> + 'd, 88 miso: impl Peripheral<P = impl GpioPin> + 'd,
90 config: Config, 89 config: Config,
91 ) -> Self { 90 ) -> Self {
92 unborrow!(sck, miso); 91 into_ref!(sck, miso);
93 Self::new_inner(spim, irq, sck.degrade(), Some(miso.degrade()), None, config) 92 Self::new_inner(spim, irq, sck.map_into(), Some(miso.map_into()), None, config)
94 } 93 }
95 94
96 fn new_inner( 95 fn new_inner(
97 _spim: impl Unborrow<Target = T> + 'd, 96 spim: impl Peripheral<P = T> + 'd,
98 irq: impl Unborrow<Target = T::Interrupt> + 'd, 97 irq: impl Peripheral<P = T::Interrupt> + 'd,
99 sck: AnyPin, 98 sck: PeripheralRef<'d, AnyPin>,
100 miso: Option<AnyPin>, 99 miso: Option<PeripheralRef<'d, AnyPin>>,
101 mosi: Option<AnyPin>, 100 mosi: Option<PeripheralRef<'d, AnyPin>>,
102 config: Config, 101 config: Config,
103 ) -> Self { 102 ) -> Self {
104 unborrow!(irq); 103 into_ref!(spim, irq);
105 104
106 let r = T::regs(); 105 let r = T::regs();
107 106
@@ -181,7 +180,7 @@ impl<'d, T: Instance> Spim<'d, T> {
181 irq.unpend(); 180 irq.unpend();
182 irq.enable(); 181 irq.enable();
183 182
184 Self { phantom: PhantomData } 183 Self { _p: spim }
185 } 184 }
186 185
187 fn on_interrupt(_: *mut ()) { 186 fn on_interrupt(_: *mut ()) {
@@ -386,7 +385,7 @@ pub(crate) mod sealed {
386 } 385 }
387} 386}
388 387
389pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { 388pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
390 type Interrupt: Interrupt; 389 type Interrupt: Interrupt;
391} 390}
392 391
diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs
index 43ba3e042..a3b25ce05 100644
--- a/embassy-nrf/src/temp.rs
+++ b/embassy-nrf/src/temp.rs
@@ -1,29 +1,27 @@
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::{into_ref, PeripheralRef};
9use fixed::types::I30F2; 8use fixed::types::I30F2;
10use futures::future::poll_fn; 9use futures::future::poll_fn;
11 10
12use crate::interrupt::InterruptExt; 11use crate::interrupt::InterruptExt;
13use crate::peripherals::TEMP; 12use crate::peripherals::TEMP;
14use crate::{interrupt, pac, Unborrow}; 13use crate::{interrupt, pac, Peripheral};
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: PeripheralRef<'d, interrupt::TEMP>,
19 _irq: interrupt::TEMP,
20} 18}
21 19
22static WAKER: AtomicWaker = AtomicWaker::new(); 20static WAKER: AtomicWaker = AtomicWaker::new();
23 21
24impl<'d> Temp<'d> { 22impl<'d> Temp<'d> {
25 pub fn new(_t: impl Unborrow<Target = TEMP> + 'd, irq: impl Unborrow<Target = interrupt::TEMP> + 'd) -> Self { 23 pub fn new(_t: impl Peripheral<P = TEMP> + 'd, irq: impl Peripheral<P = interrupt::TEMP> + 'd) -> Self {
26 unborrow!(_t, irq); 24 into_ref!(_t, irq);
27 25
28 // Enable interrupt that signals temperature values 26 // Enable interrupt that signals temperature values
29 irq.disable(); 27 irq.disable();
@@ -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/timer.rs b/embassy-nrf/src/timer.rs
index c8c36dfae..8deecdc03 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -5,12 +5,12 @@ use core::task::Poll;
5 5
6use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::drop::OnDrop; 7use embassy_hal_common::drop::OnDrop;
8use embassy_hal_common::unborrow; 8use embassy_hal_common::{into_ref, PeripheralRef};
9use futures::future::poll_fn; 9use futures::future::poll_fn;
10 10
11use crate::interrupt::{Interrupt, InterruptExt}; 11use crate::interrupt::{Interrupt, InterruptExt};
12use crate::ppi::{Event, Task}; 12use crate::ppi::{Event, Task};
13use crate::{pac, Unborrow}; 13use crate::{pac, Peripheral};
14 14
15pub(crate) mod sealed { 15pub(crate) mod sealed {
16 16
@@ -28,7 +28,7 @@ pub(crate) mod sealed {
28 pub trait TimerType {} 28 pub trait TimerType {}
29} 29}
30 30
31pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send { 31pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
32 type Interrupt: Interrupt; 32 type Interrupt: Interrupt;
33} 33}
34pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {} 34pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {}
@@ -95,15 +95,13 @@ impl TimerType for Awaitable {}
95impl TimerType for NotAwaitable {} 95impl TimerType for NotAwaitable {}
96 96
97pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> { 97pub struct Timer<'d, T: Instance, I: TimerType = NotAwaitable> {
98 phantom: PhantomData<(&'d mut T, I)>, 98 _p: PeripheralRef<'d, T>,
99 _i: PhantomData<I>,
99} 100}
100 101
101impl<'d, T: Instance> Timer<'d, T, Awaitable> { 102impl<'d, T: Instance> Timer<'d, T, Awaitable> {
102 pub fn new_awaitable( 103 pub fn new_awaitable(timer: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd) -> Self {
103 timer: impl Unborrow<Target = T> + 'd, 104 into_ref!(irq);
104 irq: impl Unborrow<Target = T::Interrupt> + 'd,
105 ) -> Self {
106 unborrow!(irq);
107 105
108 irq.set_handler(Self::on_interrupt); 106 irq.set_handler(Self::on_interrupt);
109 irq.unpend(); 107 irq.unpend();
@@ -117,7 +115,7 @@ impl<'d, T: Instance> Timer<'d, T, NotAwaitable> {
117 /// 115 ///
118 /// This can be useful for triggering tasks via PPI 116 /// This can be useful for triggering tasks via PPI
119 /// `Uarte` uses this internally. 117 /// `Uarte` uses this internally.
120 pub fn new(timer: impl Unborrow<Target = T> + 'd) -> Self { 118 pub fn new(timer: impl Peripheral<P = T> + 'd) -> Self {
121 Self::new_irqless(timer) 119 Self::new_irqless(timer)
122 } 120 }
123} 121}
@@ -126,10 +124,15 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
126 /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work. 124 /// Create a `Timer` without an interrupt, meaning `Cc::wait` won't work.
127 /// 125 ///
128 /// This is used by the public constructors. 126 /// This is used by the public constructors.
129 fn new_irqless(_timer: impl Unborrow<Target = T> + 'd) -> Self { 127 fn new_irqless(timer: impl Peripheral<P = T> + 'd) -> Self {
128 into_ref!(timer);
129
130 let regs = T::regs(); 130 let regs = T::regs();
131 131
132 let mut this = Self { phantom: PhantomData }; 132 let mut this = Self {
133 _p: timer,
134 _i: PhantomData,
135 };
133 136
134 // Stop the timer before doing anything else, 137 // Stop the timer before doing anything else,
135 // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. 138 // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification.
@@ -233,7 +236,8 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
233 } 236 }
234 Cc { 237 Cc {
235 n, 238 n,
236 phantom: PhantomData, 239 _p: self._p.reborrow(),
240 _i: PhantomData,
237 } 241 }
238 } 242 }
239} 243}
@@ -245,12 +249,13 @@ impl<'d, T: Instance, I: TimerType> Timer<'d, T, I> {
245/// 249///
246/// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. 250/// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register.
247/// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register 251/// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register
248pub struct Cc<'a, T: Instance, I: TimerType = NotAwaitable> { 252pub struct Cc<'d, T: Instance, I: TimerType = NotAwaitable> {
249 n: usize, 253 n: usize,
250 phantom: PhantomData<(&'a mut T, I)>, 254 _p: PeripheralRef<'d, T>,
255 _i: PhantomData<I>,
251} 256}
252 257
253impl<'a, T: Instance> Cc<'a, T, Awaitable> { 258impl<'d, T: Instance> Cc<'d, T, Awaitable> {
254 /// Wait until the timer's counter reaches the value stored in this register. 259 /// Wait until the timer's counter reaches the value stored in this register.
255 /// 260 ///
256 /// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`. 261 /// This requires a mutable reference so that this task's waker cannot be overwritten by a second call to `wait`.
@@ -284,9 +289,9 @@ impl<'a, T: Instance> Cc<'a, T, Awaitable> {
284 on_drop.defuse(); 289 on_drop.defuse();
285 } 290 }
286} 291}
287impl<'a, T: Instance> Cc<'a, T, NotAwaitable> {} 292impl<'d, T: Instance> Cc<'d, T, NotAwaitable> {}
288 293
289impl<'a, T: Instance, I: TimerType> Cc<'a, T, I> { 294impl<'d, T: Instance, I: TimerType> Cc<'d, T, I> {
290 /// Get the current value stored in the register. 295 /// Get the current value stored in the register.
291 pub fn read(&self) -> u32 { 296 pub fn read(&self) -> u32 {
292 T::regs().cc[self.n].read().cc().bits() 297 T::regs().cc[self.n].read().cc().bits()
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index 2088691b2..6d6eb84e7 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -7,7 +7,6 @@
7//! - nRF52832: Section 33 7//! - nRF52832: Section 33
8//! - nRF52840: Section 6.31 8//! - nRF52840: Section 6.31
9use core::future::Future; 9use core::future::Future;
10use core::marker::PhantomData;
11use core::sync::atomic::compiler_fence; 10use core::sync::atomic::compiler_fence;
12use core::sync::atomic::Ordering::SeqCst; 11use core::sync::atomic::Ordering::SeqCst;
13use core::task::Poll; 12use core::task::Poll;
@@ -16,14 +15,14 @@ use core::task::Poll;
16use embassy::time::{Duration, Instant}; 15use embassy::time::{Duration, Instant};
17use embassy::waitqueue::AtomicWaker; 16use embassy::waitqueue::AtomicWaker;
18use embassy_embedded_hal::SetConfig; 17use embassy_embedded_hal::SetConfig;
19use embassy_hal_common::unborrow; 18use embassy_hal_common::{into_ref, PeripheralRef};
20use futures::future::poll_fn; 19use futures::future::poll_fn;
21 20
22use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; 21use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
23use crate::gpio::Pin as GpioPin; 22use crate::gpio::Pin as GpioPin;
24use crate::interrupt::{Interrupt, InterruptExt}; 23use crate::interrupt::{Interrupt, InterruptExt};
25use crate::util::{slice_in_ram, slice_in_ram_or}; 24use crate::util::{slice_in_ram, slice_in_ram_or};
26use crate::{gpio, pac, Unborrow}; 25use crate::{gpio, pac, Peripheral};
27 26
28#[derive(Clone, Copy)] 27#[derive(Clone, Copy)]
29pub enum Frequency { 28pub enum Frequency {
@@ -75,18 +74,18 @@ pub enum Error {
75/// 74///
76/// For more details about EasyDMA, consult the module documentation. 75/// For more details about EasyDMA, consult the module documentation.
77pub struct Twim<'d, T: Instance> { 76pub struct Twim<'d, T: Instance> {
78 phantom: PhantomData<&'d mut T>, 77 _p: PeripheralRef<'d, T>,
79} 78}
80 79
81impl<'d, T: Instance> Twim<'d, T> { 80impl<'d, T: Instance> Twim<'d, T> {
82 pub fn new( 81 pub fn new(
83 _twim: impl Unborrow<Target = T> + 'd, 82 twim: impl Peripheral<P = T> + 'd,
84 irq: impl Unborrow<Target = T::Interrupt> + 'd, 83 irq: impl Peripheral<P = T::Interrupt> + 'd,
85 sda: impl Unborrow<Target = impl GpioPin> + 'd, 84 sda: impl Peripheral<P = impl GpioPin> + 'd,
86 scl: impl Unborrow<Target = impl GpioPin> + 'd, 85 scl: impl Peripheral<P = impl GpioPin> + 'd,
87 config: Config, 86 config: Config,
88 ) -> Self { 87 ) -> Self {
89 unborrow!(irq, sda, scl); 88 into_ref!(twim, irq, sda, scl);
90 89
91 let r = T::regs(); 90 let r = T::regs();
92 91
@@ -136,7 +135,7 @@ impl<'d, T: Instance> Twim<'d, T> {
136 irq.unpend(); 135 irq.unpend();
137 irq.enable(); 136 irq.enable();
138 137
139 Self { phantom: PhantomData } 138 Self { _p: twim }
140 } 139 }
141 140
142 fn on_interrupt(_: *mut ()) { 141 fn on_interrupt(_: *mut ()) {
@@ -707,7 +706,7 @@ pub(crate) mod sealed {
707 } 706 }
708} 707}
709 708
710pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static { 709pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
711 type Interrupt: Interrupt; 710 type Interrupt: Interrupt;
712} 711}
713 712
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 459c56c8e..792b8ecca 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -13,12 +13,11 @@
13//! memory may be used given that buffers are passed in directly to its read and write 13//! memory may be used given that buffers are passed in directly to its read and write
14//! methods. 14//! methods.
15 15
16use core::marker::PhantomData;
17use core::sync::atomic::{compiler_fence, Ordering}; 16use core::sync::atomic::{compiler_fence, Ordering};
18use core::task::Poll; 17use core::task::Poll;
19 18
20use embassy_hal_common::drop::OnDrop; 19use embassy_hal_common::drop::OnDrop;
21use embassy_hal_common::unborrow; 20use embassy_hal_common::{into_ref, PeripheralRef};
22use futures::future::poll_fn; 21use futures::future::poll_fn;
23use pac::uarte0::RegisterBlock; 22use pac::uarte0::RegisterBlock;
24// Re-export SVD variants to allow user to directly set values. 23// Re-export SVD variants to allow user to directly set values.
@@ -31,7 +30,7 @@ use crate::interrupt::{Interrupt, InterruptExt};
31use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; 30use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
32use crate::timer::{Frequency, Instance as TimerInstance, Timer}; 31use crate::timer::{Frequency, Instance as TimerInstance, Timer};
33use crate::util::slice_in_ram_or; 32use crate::util::slice_in_ram_or;
34use crate::{pac, Unborrow}; 33use crate::{pac, Peripheral};
35 34
36#[derive(Clone)] 35#[derive(Clone)]
37#[non_exhaustive] 36#[non_exhaustive]
@@ -63,7 +62,6 @@ pub enum Error {
63/// 62///
64/// For more details about EasyDMA, consult the module documentation. 63/// For more details about EasyDMA, consult the module documentation.
65pub struct Uarte<'d, T: Instance> { 64pub struct Uarte<'d, T: Instance> {
66 phantom: PhantomData<&'d mut T>,
67 tx: UarteTx<'d, T>, 65 tx: UarteTx<'d, T>,
68 rx: UarteRx<'d, T>, 66 rx: UarteRx<'d, T>,
69} 67}
@@ -71,60 +69,60 @@ pub struct Uarte<'d, T: Instance> {
71/// Transmitter interface to the UARTE peripheral obtained 69/// Transmitter interface to the UARTE peripheral obtained
72/// via [Uarte]::split. 70/// via [Uarte]::split.
73pub struct UarteTx<'d, T: Instance> { 71pub struct UarteTx<'d, T: Instance> {
74 phantom: PhantomData<&'d mut T>, 72 _p: PeripheralRef<'d, T>,
75} 73}
76 74
77/// Receiver interface to the UARTE peripheral obtained 75/// Receiver interface to the UARTE peripheral obtained
78/// via [Uarte]::split. 76/// via [Uarte]::split.
79pub struct UarteRx<'d, T: Instance> { 77pub struct UarteRx<'d, T: Instance> {
80 phantom: PhantomData<&'d mut T>, 78 _p: PeripheralRef<'d, T>,
81} 79}
82 80
83impl<'d, T: Instance> Uarte<'d, T> { 81impl<'d, T: Instance> Uarte<'d, T> {
84 /// Create a new UARTE without hardware flow control 82 /// Create a new UARTE without hardware flow control
85 pub fn new( 83 pub fn new(
86 uarte: impl Unborrow<Target = T> + 'd, 84 uarte: impl Peripheral<P = T> + 'd,
87 irq: impl Unborrow<Target = T::Interrupt> + 'd, 85 irq: impl Peripheral<P = T::Interrupt> + 'd,
88 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 86 rxd: impl Peripheral<P = impl GpioPin> + 'd,
89 txd: impl Unborrow<Target = impl GpioPin> + 'd, 87 txd: impl Peripheral<P = impl GpioPin> + 'd,
90 config: Config, 88 config: Config,
91 ) -> Self { 89 ) -> Self {
92 unborrow!(rxd, txd); 90 into_ref!(rxd, txd);
93 Self::new_inner(uarte, irq, rxd.degrade(), txd.degrade(), None, None, config) 91 Self::new_inner(uarte, irq, rxd.map_into(), txd.map_into(), None, None, config)
94 } 92 }
95 93
96 /// Create a new UARTE with hardware flow control (RTS/CTS) 94 /// Create a new UARTE with hardware flow control (RTS/CTS)
97 pub fn new_with_rtscts( 95 pub fn new_with_rtscts(
98 uarte: impl Unborrow<Target = T> + 'd, 96 uarte: impl Peripheral<P = T> + 'd,
99 irq: impl Unborrow<Target = T::Interrupt> + 'd, 97 irq: impl Peripheral<P = T::Interrupt> + 'd,
100 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 98 rxd: impl Peripheral<P = impl GpioPin> + 'd,
101 txd: impl Unborrow<Target = impl GpioPin> + 'd, 99 txd: impl Peripheral<P = impl GpioPin> + 'd,
102 cts: impl Unborrow<Target = impl GpioPin> + 'd, 100 cts: impl Peripheral<P = impl GpioPin> + 'd,
103 rts: impl Unborrow<Target = impl GpioPin> + 'd, 101 rts: impl Peripheral<P = impl GpioPin> + 'd,
104 config: Config, 102 config: Config,
105 ) -> Self { 103 ) -> Self {
106 unborrow!(rxd, txd, cts, rts); 104 into_ref!(rxd, txd, cts, rts);
107 Self::new_inner( 105 Self::new_inner(
108 uarte, 106 uarte,
109 irq, 107 irq,
110 rxd.degrade(), 108 rxd.map_into(),
111 txd.degrade(), 109 txd.map_into(),
112 Some(cts.degrade()), 110 Some(cts.map_into()),
113 Some(rts.degrade()), 111 Some(rts.map_into()),
114 config, 112 config,
115 ) 113 )
116 } 114 }
117 115
118 fn new_inner( 116 fn new_inner(
119 _uarte: impl Unborrow<Target = T> + 'd, 117 uarte: impl Peripheral<P = T> + 'd,
120 irq: impl Unborrow<Target = T::Interrupt> + 'd, 118 irq: impl Peripheral<P = T::Interrupt> + 'd,
121 rxd: AnyPin, 119 rxd: PeripheralRef<'d, AnyPin>,
122 txd: AnyPin, 120 txd: PeripheralRef<'d, AnyPin>,
123 cts: Option<AnyPin>, 121 cts: Option<PeripheralRef<'d, AnyPin>>,
124 rts: Option<AnyPin>, 122 rts: Option<PeripheralRef<'d, AnyPin>>,
125 config: Config, 123 config: Config,
126 ) -> Self { 124 ) -> Self {
127 unborrow!(irq); 125 into_ref!(uarte, irq);
128 126
129 let r = T::regs(); 127 let r = T::regs();
130 128
@@ -161,9 +159,10 @@ impl<'d, T: Instance> Uarte<'d, T> {
161 s.tx_rx_refcount.store(2, Ordering::Relaxed); 159 s.tx_rx_refcount.store(2, Ordering::Relaxed);
162 160
163 Self { 161 Self {
164 phantom: PhantomData, 162 tx: UarteTx {
165 tx: UarteTx { phantom: PhantomData }, 163 _p: unsafe { uarte.clone_unchecked() },
166 rx: UarteRx { phantom: PhantomData }, 164 },
165 rx: UarteRx { _p: uarte },
167 } 166 }
168 } 167 }
169 168
@@ -245,35 +244,35 @@ fn configure(r: &RegisterBlock, config: Config, hardware_flow_control: bool) {
245impl<'d, T: Instance> UarteTx<'d, T> { 244impl<'d, T: Instance> UarteTx<'d, T> {
246 /// Create a new tx-only UARTE without hardware flow control 245 /// Create a new tx-only UARTE without hardware flow control
247 pub fn new( 246 pub fn new(
248 uarte: impl Unborrow<Target = T> + 'd, 247 uarte: impl Peripheral<P = T> + 'd,
249 irq: impl Unborrow<Target = T::Interrupt> + 'd, 248 irq: impl Peripheral<P = T::Interrupt> + 'd,
250 txd: impl Unborrow<Target = impl GpioPin> + 'd, 249 txd: impl Peripheral<P = impl GpioPin> + 'd,
251 config: Config, 250 config: Config,
252 ) -> Self { 251 ) -> Self {
253 unborrow!(txd); 252 into_ref!(txd);
254 Self::new_inner(uarte, irq, txd.degrade(), None, config) 253 Self::new_inner(uarte, irq, txd.map_into(), None, config)
255 } 254 }
256 255
257 /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) 256 /// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
258 pub fn new_with_rtscts( 257 pub fn new_with_rtscts(
259 uarte: impl Unborrow<Target = T> + 'd, 258 uarte: impl Peripheral<P = T> + 'd,
260 irq: impl Unborrow<Target = T::Interrupt> + 'd, 259 irq: impl Peripheral<P = T::Interrupt> + 'd,
261 txd: impl Unborrow<Target = impl GpioPin> + 'd, 260 txd: impl Peripheral<P = impl GpioPin> + 'd,
262 cts: impl Unborrow<Target = impl GpioPin> + 'd, 261 cts: impl Peripheral<P = impl GpioPin> + 'd,
263 config: Config, 262 config: Config,
264 ) -> Self { 263 ) -> Self {
265 unborrow!(txd, cts); 264 into_ref!(txd, cts);
266 Self::new_inner(uarte, irq, txd.degrade(), Some(cts.degrade()), config) 265 Self::new_inner(uarte, irq, txd.map_into(), Some(cts.map_into()), config)
267 } 266 }
268 267
269 fn new_inner( 268 fn new_inner(
270 _uarte: impl Unborrow<Target = T> + 'd, 269 uarte: impl Peripheral<P = T> + 'd,
271 irq: impl Unborrow<Target = T::Interrupt> + 'd, 270 irq: impl Peripheral<P = T::Interrupt> + 'd,
272 txd: AnyPin, 271 txd: PeripheralRef<'d, AnyPin>,
273 cts: Option<AnyPin>, 272 cts: Option<PeripheralRef<'d, AnyPin>>,
274 config: Config, 273 config: Config,
275 ) -> Self { 274 ) -> Self {
276 unborrow!(irq); 275 into_ref!(uarte, irq);
277 276
278 let r = T::regs(); 277 let r = T::regs();
279 278
@@ -299,7 +298,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
299 let s = T::state(); 298 let s = T::state();
300 s.tx_rx_refcount.store(1, Ordering::Relaxed); 299 s.tx_rx_refcount.store(1, Ordering::Relaxed);
301 300
302 Self { phantom: PhantomData } 301 Self { _p: uarte }
303 } 302 }
304 303
305 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 304 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
@@ -437,35 +436,35 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> {
437impl<'d, T: Instance> UarteRx<'d, T> { 436impl<'d, T: Instance> UarteRx<'d, T> {
438 /// Create a new rx-only UARTE without hardware flow control 437 /// Create a new rx-only UARTE without hardware flow control
439 pub fn new( 438 pub fn new(
440 uarte: impl Unborrow<Target = T> + 'd, 439 uarte: impl Peripheral<P = T> + 'd,
441 irq: impl Unborrow<Target = T::Interrupt> + 'd, 440 irq: impl Peripheral<P = T::Interrupt> + 'd,
442 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 441 rxd: impl Peripheral<P = impl GpioPin> + 'd,
443 config: Config, 442 config: Config,
444 ) -> Self { 443 ) -> Self {
445 unborrow!(rxd); 444 into_ref!(rxd);
446 Self::new_inner(uarte, irq, rxd.degrade(), None, config) 445 Self::new_inner(uarte, irq, rxd.map_into(), None, config)
447 } 446 }
448 447
449 /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) 448 /// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
450 pub fn new_with_rtscts( 449 pub fn new_with_rtscts(
451 uarte: impl Unborrow<Target = T> + 'd, 450 uarte: impl Peripheral<P = T> + 'd,
452 irq: impl Unborrow<Target = T::Interrupt> + 'd, 451 irq: impl Peripheral<P = T::Interrupt> + 'd,
453 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 452 rxd: impl Peripheral<P = impl GpioPin> + 'd,
454 rts: impl Unborrow<Target = impl GpioPin> + 'd, 453 rts: impl Peripheral<P = impl GpioPin> + 'd,
455 config: Config, 454 config: Config,
456 ) -> Self { 455 ) -> Self {
457 unborrow!(rxd, rts); 456 into_ref!(rxd, rts);
458 Self::new_inner(uarte, irq, rxd.degrade(), Some(rts.degrade()), config) 457 Self::new_inner(uarte, irq, rxd.map_into(), Some(rts.map_into()), config)
459 } 458 }
460 459
461 fn new_inner( 460 fn new_inner(
462 _uarte: impl Unborrow<Target = T> + 'd, 461 uarte: impl Peripheral<P = T> + 'd,
463 irq: impl Unborrow<Target = T::Interrupt> + 'd, 462 irq: impl Peripheral<P = T::Interrupt> + 'd,
464 rxd: AnyPin, 463 rxd: PeripheralRef<'d, AnyPin>,
465 rts: Option<AnyPin>, 464 rts: Option<PeripheralRef<'d, AnyPin>>,
466 config: Config, 465 config: Config,
467 ) -> Self { 466 ) -> Self {
468 unborrow!(irq); 467 into_ref!(uarte, irq);
469 468
470 let r = T::regs(); 469 let r = T::regs();
471 470
@@ -491,7 +490,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
491 let s = T::state(); 490 let s = T::state();
492 s.tx_rx_refcount.store(1, Ordering::Relaxed); 491 s.tx_rx_refcount.store(1, Ordering::Relaxed);
493 492
494 Self { phantom: PhantomData } 493 Self { _p: uarte }
495 } 494 }
496 495
497 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 496 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
@@ -676,24 +675,24 @@ pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> {
676impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { 675impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
677 /// Create a new UARTE without hardware flow control 676 /// Create a new UARTE without hardware flow control
678 pub fn new( 677 pub fn new(
679 uarte: impl Unborrow<Target = U> + 'd, 678 uarte: impl Peripheral<P = U> + 'd,
680 timer: impl Unborrow<Target = T> + 'd, 679 timer: impl Peripheral<P = T> + 'd,
681 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 680 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
682 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 681 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
683 irq: impl Unborrow<Target = U::Interrupt> + 'd, 682 irq: impl Peripheral<P = U::Interrupt> + 'd,
684 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 683 rxd: impl Peripheral<P = impl GpioPin> + 'd,
685 txd: impl Unborrow<Target = impl GpioPin> + 'd, 684 txd: impl Peripheral<P = impl GpioPin> + 'd,
686 config: Config, 685 config: Config,
687 ) -> Self { 686 ) -> Self {
688 unborrow!(rxd, txd); 687 into_ref!(rxd, txd);
689 Self::new_inner( 688 Self::new_inner(
690 uarte, 689 uarte,
691 timer, 690 timer,
692 ppi_ch1, 691 ppi_ch1,
693 ppi_ch2, 692 ppi_ch2,
694 irq, 693 irq,
695 rxd.degrade(), 694 rxd.map_into(),
696 txd.degrade(), 695 txd.map_into(),
697 None, 696 None,
698 None, 697 None,
699 config, 698 config,
@@ -702,42 +701,42 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
702 701
703 /// Create a new UARTE with hardware flow control (RTS/CTS) 702 /// Create a new UARTE with hardware flow control (RTS/CTS)
704 pub fn new_with_rtscts( 703 pub fn new_with_rtscts(
705 uarte: impl Unborrow<Target = U> + 'd, 704 uarte: impl Peripheral<P = U> + 'd,
706 timer: impl Unborrow<Target = T> + 'd, 705 timer: impl Peripheral<P = T> + 'd,
707 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 706 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
708 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 707 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
709 irq: impl Unborrow<Target = U::Interrupt> + 'd, 708 irq: impl Peripheral<P = U::Interrupt> + 'd,
710 rxd: impl Unborrow<Target = impl GpioPin> + 'd, 709 rxd: impl Peripheral<P = impl GpioPin> + 'd,
711 txd: impl Unborrow<Target = impl GpioPin> + 'd, 710 txd: impl Peripheral<P = impl GpioPin> + 'd,
712 cts: impl Unborrow<Target = impl GpioPin> + 'd, 711 cts: impl Peripheral<P = impl GpioPin> + 'd,
713 rts: impl Unborrow<Target = impl GpioPin> + 'd, 712 rts: impl Peripheral<P = impl GpioPin> + 'd,
714 config: Config, 713 config: Config,
715 ) -> Self { 714 ) -> Self {
716 unborrow!(rxd, txd, cts, rts); 715 into_ref!(rxd, txd, cts, rts);
717 Self::new_inner( 716 Self::new_inner(
718 uarte, 717 uarte,
719 timer, 718 timer,
720 ppi_ch1, 719 ppi_ch1,
721 ppi_ch2, 720 ppi_ch2,
722 irq, 721 irq,
723 rxd.degrade(), 722 rxd.map_into(),
724 txd.degrade(), 723 txd.map_into(),
725 Some(cts.degrade()), 724 Some(cts.map_into()),
726 Some(rts.degrade()), 725 Some(rts.map_into()),
727 config, 726 config,
728 ) 727 )
729 } 728 }
730 729
731 fn new_inner( 730 fn new_inner(
732 uarte: impl Unborrow<Target = U> + 'd, 731 uarte: impl Peripheral<P = U> + 'd,
733 timer: impl Unborrow<Target = T> + 'd, 732 timer: impl Peripheral<P = T> + 'd,
734 ppi_ch1: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 733 ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
735 ppi_ch2: impl Unborrow<Target = impl ConfigurableChannel + 'd> + 'd, 734 ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd,
736 irq: impl Unborrow<Target = U::Interrupt> + 'd, 735 irq: impl Peripheral<P = U::Interrupt> + 'd,
737 rxd: AnyPin, 736 rxd: PeripheralRef<'d, AnyPin>,
738 txd: AnyPin, 737 txd: PeripheralRef<'d, AnyPin>,
739 cts: Option<AnyPin>, 738 cts: Option<PeripheralRef<'d, AnyPin>>,
740 rts: Option<AnyPin>, 739 rts: Option<PeripheralRef<'d, AnyPin>>,
741 config: Config, 740 config: Config,
742 ) -> Self { 741 ) -> Self {
743 let baudrate = config.baudrate; 742 let baudrate = config.baudrate;
@@ -745,7 +744,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
745 744
746 let mut timer = Timer::new(timer); 745 let mut timer = Timer::new(timer);
747 746
748 unborrow!(ppi_ch1, ppi_ch2); 747 into_ref!(ppi_ch1, ppi_ch2);
749 748
750 let r = U::regs(); 749 let r = U::regs();
751 750
@@ -763,7 +762,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
763 timer.cc(0).short_compare_stop(); 762 timer.cc(0).short_compare_stop();
764 763
765 let mut ppi_ch1 = Ppi::new_one_to_two( 764 let mut ppi_ch1 = Ppi::new_one_to_two(
766 ppi_ch1.degrade(), 765 ppi_ch1.map_into(),
767 Event::from_reg(&r.events_rxdrdy), 766 Event::from_reg(&r.events_rxdrdy),
768 timer.task_clear(), 767 timer.task_clear(),
769 timer.task_start(), 768 timer.task_start(),
@@ -771,7 +770,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> {
771 ppi_ch1.enable(); 770 ppi_ch1.enable();
772 771
773 let mut ppi_ch2 = Ppi::new_one_to_one( 772 let mut ppi_ch2 = Ppi::new_one_to_one(
774 ppi_ch2.degrade(), 773 ppi_ch2.map_into(),
775 timer.cc(0).event_compare(), 774 timer.cc(0).event_compare(),
776 Task::from_reg(&r.tasks_stoprx), 775 Task::from_reg(&r.tasks_stoprx),
777 ); 776 );
@@ -958,7 +957,7 @@ pub(crate) mod sealed {
958 } 957 }
959} 958}
960 959
961pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send { 960pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
962 type Interrupt: Interrupt; 961 type Interrupt: Interrupt;
963} 962}
964 963
diff --git a/embassy-nrf/src/usb.rs b/embassy-nrf/src/usb.rs
index a039427f1..378492859 100644
--- a/embassy-nrf/src/usb.rs
+++ b/embassy-nrf/src/usb.rs
@@ -7,7 +7,7 @@ use core::task::Poll;
7 7
8use cortex_m::peripheral::NVIC; 8use cortex_m::peripheral::NVIC;
9use embassy::waitqueue::AtomicWaker; 9use embassy::waitqueue::AtomicWaker;
10use embassy_hal_common::unborrow; 10use embassy_hal_common::{into_ref, PeripheralRef};
11pub use embassy_usb; 11pub use embassy_usb;
12use embassy_usb::driver::{self, EndpointError, Event, Unsupported}; 12use embassy_usb::driver::{self, EndpointError, Event, Unsupported};
13use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; 13use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
@@ -17,7 +17,7 @@ use pac::usbd::RegisterBlock;
17 17
18use crate::interrupt::{Interrupt, InterruptExt}; 18use crate::interrupt::{Interrupt, InterruptExt};
19use crate::util::slice_in_ram; 19use crate::util::slice_in_ram;
20use crate::{pac, Unborrow}; 20use crate::{pac, Peripheral};
21 21
22const NEW_AW: AtomicWaker = AtomicWaker::new(); 22const NEW_AW: AtomicWaker = AtomicWaker::new();
23static BUS_WAKER: AtomicWaker = NEW_AW; 23static BUS_WAKER: AtomicWaker = NEW_AW;
@@ -38,7 +38,7 @@ pub trait UsbSupply {
38} 38}
39 39
40pub struct Driver<'d, T: Instance, P: UsbSupply> { 40pub struct Driver<'d, T: Instance, P: UsbSupply> {
41 phantom: PhantomData<&'d mut T>, 41 _p: PeripheralRef<'d, T>,
42 alloc_in: Allocator, 42 alloc_in: Allocator,
43 alloc_out: Allocator, 43 alloc_out: Allocator,
44 usb_supply: P, 44 usb_supply: P,
@@ -166,18 +166,14 @@ impl UsbSupply for SignalledSupply {
166} 166}
167 167
168impl<'d, T: Instance, P: UsbSupply> Driver<'d, T, P> { 168impl<'d, T: Instance, P: UsbSupply> Driver<'d, T, P> {
169 pub fn new( 169 pub fn new(usb: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd, usb_supply: P) -> Self {
170 _usb: impl Unborrow<Target = T> + 'd, 170 into_ref!(usb, irq);
171 irq: impl Unborrow<Target = T::Interrupt> + 'd,
172 usb_supply: P,
173 ) -> Self {
174 unborrow!(irq);
175 irq.set_handler(Self::on_interrupt); 171 irq.set_handler(Self::on_interrupt);
176 irq.unpend(); 172 irq.unpend();
177 irq.enable(); 173 irq.enable();
178 174
179 Self { 175 Self {
180 phantom: PhantomData, 176 _p: usb,
181 alloc_in: Allocator::new(), 177 alloc_in: Allocator::new(),
182 alloc_out: Allocator::new(), 178 alloc_out: Allocator::new(),
183 usb_supply, 179 usb_supply,
@@ -273,15 +269,15 @@ impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P>
273 })) 269 }))
274 } 270 }
275 271
276 fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { 272 fn start(mut self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) {
277 ( 273 (
278 Bus { 274 Bus {
279 phantom: PhantomData, 275 _p: unsafe { self._p.clone_unchecked() },
280 power_available: false, 276 power_available: false,
281 usb_supply: self.usb_supply, 277 usb_supply: self.usb_supply,
282 }, 278 },
283 ControlPipe { 279 ControlPipe {
284 _phantom: PhantomData, 280 _p: self._p,
285 max_packet_size: control_max_packet_size, 281 max_packet_size: control_max_packet_size,
286 }, 282 },
287 ) 283 )
@@ -289,7 +285,7 @@ impl<'d, T: Instance, P: UsbSupply + 'd> driver::Driver<'d> for Driver<'d, T, P>
289} 285}
290 286
291pub struct Bus<'d, T: Instance, P: UsbSupply> { 287pub struct Bus<'d, T: Instance, P: UsbSupply> {
292 phantom: PhantomData<&'d mut T>, 288 _p: PeripheralRef<'d, T>,
293 power_available: bool, 289 power_available: bool,
294 usb_supply: P, 290 usb_supply: P,
295} 291}
@@ -750,7 +746,7 @@ impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
750} 746}
751 747
752pub struct ControlPipe<'d, T: Instance> { 748pub struct ControlPipe<'d, T: Instance> {
753 _phantom: PhantomData<&'d mut T>, 749 _p: PeripheralRef<'d, T>,
754 max_packet_size: u16, 750 max_packet_size: u16,
755} 751}
756 752
@@ -950,7 +946,7 @@ pub(crate) mod sealed {
950 } 946 }
951} 947}
952 948
953pub trait Instance: Unborrow<Target = Self> + sealed::Instance + 'static + Send { 949pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
954 type Interrupt: Interrupt; 950 type Interrupt: Interrupt;
955} 951}
956 952