aboutsummaryrefslogtreecommitdiff
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
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]>
-rw-r--r--embassy-cortex-m/src/interrupt.rs4
-rw-r--r--embassy-cortex-m/src/peripheral.rs21
-rw-r--r--embassy-hal-common/src/lib.rs4
-rw-r--r--embassy-hal-common/src/macros.rs23
-rw-r--r--embassy-hal-common/src/peripheral.rs173
-rw-r--r--embassy-hal-common/src/unborrow.rs60
-rw-r--r--embassy-lora/src/stm32wl/mod.rs50
-rw-r--r--embassy-macros/src/macros/cortex_m_interrupt_declare.rs7
-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
-rw-r--r--embassy-rp/src/gpio.rs48
-rw-r--r--embassy-rp/src/lib.rs2
-rw-r--r--embassy-rp/src/spi.rs62
-rw-r--r--embassy-rp/src/uart.rs26
-rw-r--r--embassy-stm32/src/adc/f1.rs8
-rw-r--r--embassy-stm32/src/adc/v2.rs8
-rw-r--r--embassy-stm32/src/adc/v3.rs8
-rw-r--r--embassy-stm32/src/adc/v4.rs6
-rw-r--r--embassy-stm32/src/can/bxcan.rs58
-rw-r--r--embassy-stm32/src/crc/v1.rs21
-rw-r--r--embassy-stm32/src/crc/v2v3.rs14
-rw-r--r--embassy-stm32/src/dac/v2.rs27
-rw-r--r--embassy-stm32/src/dcmi.rs296
-rw-r--r--embassy-stm32/src/dma/mod.rs45
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs50
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs50
-rw-r--r--embassy-stm32/src/exti.rs8
-rw-r--r--embassy-stm32/src/flash/mod.rs20
-rw-r--r--embassy-stm32/src/fmc/mod.rs18
-rw-r--r--embassy-stm32/src/gpio.rs33
-rw-r--r--embassy-stm32/src/i2c/v1.rs12
-rw-r--r--embassy-stm32/src/i2c/v2.rs27
-rw-r--r--embassy-stm32/src/lib.rs2
-rw-r--r--embassy-stm32/src/pwm/simple_pwm.rs48
-rw-r--r--embassy-stm32/src/rcc/h7.rs10
-rw-r--r--embassy-stm32/src/rng.rs17
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs385
-rw-r--r--embassy-stm32/src/spi/mod.rs87
-rw-r--r--embassy-stm32/src/subghz/mod.rs14
-rw-r--r--embassy-stm32/src/usart/buffered.rs4
-rw-r--r--embassy-stm32/src/usart/mod.rs26
-rw-r--r--embassy-stm32/src/usb/usb.rs14
-rw-r--r--embassy-stm32/src/usb_otg.rs40
-rw-r--r--embassy-stm32/src/wdg/mod.rs6
-rw-r--r--examples/stm32f4/src/bin/sdmmc.rs11
-rw-r--r--examples/stm32f7/src/bin/sdmmc.rs11
-rw-r--r--examples/stm32h7/src/bin/low_level_timer_api.rs24
-rw-r--r--examples/stm32h7/src/bin/sdmmc.rs9
65 files changed, 1527 insertions, 1421 deletions
diff --git a/embassy-cortex-m/src/interrupt.rs b/embassy-cortex-m/src/interrupt.rs
index 715f00381..7358caa46 100644
--- a/embassy-cortex-m/src/interrupt.rs
+++ b/embassy-cortex-m/src/interrupt.rs
@@ -3,7 +3,7 @@ use core::{mem, ptr};
3 3
4use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering}; 4use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
5use cortex_m::peripheral::NVIC; 5use cortex_m::peripheral::NVIC;
6use embassy_hal_common::Unborrow; 6use embassy_hal_common::Peripheral;
7pub use embassy_macros::cortex_m_interrupt_take as take; 7pub use embassy_macros::cortex_m_interrupt_take as take;
8 8
9/// Implementation detail, do not use outside embassy crates. 9/// Implementation detail, do not use outside embassy crates.
@@ -32,7 +32,7 @@ unsafe impl cortex_m::interrupt::InterruptNumber for NrWrap {
32 32
33/// Represents an interrupt type that can be configured by embassy to handle 33/// Represents an interrupt type that can be configured by embassy to handle
34/// interrupts. 34/// interrupts.
35pub unsafe trait Interrupt: Unborrow<Target = Self> { 35pub unsafe trait Interrupt: Peripheral<P = Self> {
36 /// Return the NVIC interrupt number for this interrupt. 36 /// Return the NVIC interrupt number for this interrupt.
37 fn number(&self) -> u16; 37 fn number(&self) -> u16;
38 /// Steal an instance of this interrupt 38 /// Steal an instance of this interrupt
diff --git a/embassy-cortex-m/src/peripheral.rs b/embassy-cortex-m/src/peripheral.rs
index 6a03bfb9f..e2f295579 100644
--- a/embassy-cortex-m/src/peripheral.rs
+++ b/embassy-cortex-m/src/peripheral.rs
@@ -1,9 +1,9 @@
1//! Peripheral interrupt handling specific to cortex-m devices. 1//! Peripheral interrupt handling specific to cortex-m devices.
2use core::marker::PhantomData;
3use core::mem::MaybeUninit; 2use core::mem::MaybeUninit;
4 3
5use cortex_m::peripheral::scb::VectActive; 4use cortex_m::peripheral::scb::VectActive;
6use cortex_m::peripheral::{NVIC, SCB}; 5use cortex_m::peripheral::{NVIC, SCB};
6use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
7 7
8use crate::interrupt::{Interrupt, InterruptExt, Priority}; 8use crate::interrupt::{Interrupt, InterruptExt, Priority};
9 9
@@ -33,8 +33,7 @@ impl<S> StateStorage<S> {
33/// a safe way. 33/// a safe way.
34pub struct PeripheralMutex<'a, S: PeripheralState> { 34pub struct PeripheralMutex<'a, S: PeripheralState> {
35 state: *mut S, 35 state: *mut S,
36 _phantom: PhantomData<&'a mut S>, 36 irq: PeripheralRef<'a, S::Interrupt>,
37 irq: S::Interrupt,
38} 37}
39 38
40/// Whether `irq` can be preempted by the current interrupt. 39/// Whether `irq` can be preempted by the current interrupt.
@@ -62,8 +61,14 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
62 /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state. 61 /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state.
63 /// 62 ///
64 /// Registers `on_interrupt` as the `irq`'s handler, and enables it. 63 /// Registers `on_interrupt` as the `irq`'s handler, and enables it.
65 pub fn new(irq: S::Interrupt, storage: &'a mut StateStorage<S>, init: impl FnOnce() -> S) -> Self { 64 pub fn new(
66 if can_be_preempted(&irq) { 65 irq: impl Peripheral<P = S::Interrupt> + 'a,
66 storage: &'a mut StateStorage<S>,
67 init: impl FnOnce() -> S,
68 ) -> Self {
69 into_ref!(irq);
70
71 if can_be_preempted(&*irq) {
67 panic!( 72 panic!(
68 "`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps" 73 "`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps"
69 ); 74 );
@@ -88,11 +93,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
88 irq.set_handler_context(state_ptr as *mut ()); 93 irq.set_handler_context(state_ptr as *mut ());
89 irq.enable(); 94 irq.enable();
90 95
91 Self { 96 Self { irq, state: state_ptr }
92 irq,
93 state: state_ptr,
94 _phantom: PhantomData,
95 }
96 } 97 }
97 98
98 /// Access the peripheral state ensuring interrupts are disabled so that the state can be 99 /// Access the peripheral state ensuring interrupts are disabled so that the state can be
diff --git a/embassy-hal-common/src/lib.rs b/embassy-hal-common/src/lib.rs
index c8cf1c4cd..d3d9e0a84 100644
--- a/embassy-hal-common/src/lib.rs
+++ b/embassy-hal-common/src/lib.rs
@@ -6,10 +6,10 @@ pub(crate) mod fmt;
6 6
7pub mod drop; 7pub mod drop;
8mod macros; 8mod macros;
9mod peripheral;
9pub mod ratio; 10pub mod ratio;
10pub mod ring_buffer; 11pub mod ring_buffer;
11mod unborrow; 12pub use peripheral::{Peripheral, PeripheralRef};
12pub use unborrow::Unborrow;
13 13
14/// Low power blocking wait loop using WFE/SEV. 14/// Low power blocking wait loop using WFE/SEV.
15pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { 15pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) {
diff --git a/embassy-hal-common/src/macros.rs b/embassy-hal-common/src/macros.rs
index ffa5e4fb6..7af85f782 100644
--- a/embassy-hal-common/src/macros.rs
+++ b/embassy-hal-common/src/macros.rs
@@ -21,13 +21,7 @@ macro_rules! peripherals {
21 } 21 }
22 22
23 $(#[$cfg])? 23 $(#[$cfg])?
24 unsafe impl $crate::Unborrow for $name { 24 $crate::impl_peripheral!($name);
25 type Target = $name;
26 #[inline]
27 unsafe fn unborrow(self) -> $name {
28 self
29 }
30 }
31 )* 25 )*
32 } 26 }
33 27
@@ -77,22 +71,23 @@ macro_rules! peripherals {
77} 71}
78 72
79#[macro_export] 73#[macro_export]
80macro_rules! unborrow { 74macro_rules! into_ref {
81 ($($name:ident),*) => { 75 ($($name:ident),*) => {
82 $( 76 $(
83 let mut $name = unsafe { $name.unborrow() }; 77 let mut $name = $name.into_ref();
84 )* 78 )*
85 } 79 }
86} 80}
87 81
88#[macro_export] 82#[macro_export]
89macro_rules! unsafe_impl_unborrow { 83macro_rules! impl_peripheral {
90 ($type:ident) => { 84 ($type:ident) => {
91 unsafe impl $crate::Unborrow for $type { 85 impl $crate::Peripheral for $type {
92 type Target = $type; 86 type P = $type;
87
93 #[inline] 88 #[inline]
94 unsafe fn unborrow(self) -> Self::Target { 89 unsafe fn clone_unchecked(&mut self) -> Self::P {
95 self 90 $type { ..*self }
96 } 91 }
97 } 92 }
98 }; 93 };
diff --git a/embassy-hal-common/src/peripheral.rs b/embassy-hal-common/src/peripheral.rs
new file mode 100644
index 000000000..038cebb5e
--- /dev/null
+++ b/embassy-hal-common/src/peripheral.rs
@@ -0,0 +1,173 @@
1use core::marker::PhantomData;
2use core::ops::{Deref, DerefMut};
3
4/// An exclusive reference to a peripheral.
5///
6/// This is functionally the same as a `&'a mut T`. The reason for having a
7/// dedicated struct is memory efficiency:
8///
9/// Peripheral singletons are typically either zero-sized (for concrete peripehrals
10/// like `PA9` or `Spi4`) or very small (for example `AnyPin` which is 1 byte).
11/// However `&mut T` is always 4 bytes for 32-bit targets, even if T is zero-sized.
12/// PeripheralRef stores a copy of `T` instead, so it's the same size.
13///
14/// but it is the size of `T` not the size
15/// of a pointer. This is useful if T is a zero sized type.
16pub struct PeripheralRef<'a, T> {
17 inner: T,
18 _lifetime: PhantomData<&'a mut T>,
19}
20
21impl<'a, T> PeripheralRef<'a, T> {
22 #[inline]
23 pub fn new(inner: T) -> Self {
24 Self {
25 inner,
26 _lifetime: PhantomData,
27 }
28 }
29
30 /// Unsafely clone (duplicate) a peripheral singleton.
31 ///
32 /// # Safety
33 ///
34 /// This returns an owned clone of the peripheral. You must manually ensure
35 /// only one copy of the peripheral is in use at a time. For example, don't
36 /// create two SPI drivers on `SPI1`, because they will "fight" each other.
37 ///
38 /// You should strongly prefer using `reborrow()` instead. It returns a
39 /// `PeripheralRef` that borrows `self`, which allows the borrow checker
40 /// to enforce this at compile time.
41 pub unsafe fn clone_unchecked(&mut self) -> PeripheralRef<'a, T>
42 where
43 T: Peripheral<P = T>,
44 {
45 PeripheralRef::new(self.inner.clone_unchecked())
46 }
47
48 /// Reborrow into a "child" PeripheralRef.
49 ///
50 /// `self` will stay borrowed until the child PeripheralRef is dropped.
51 pub fn reborrow(&mut self) -> PeripheralRef<'_, T>
52 where
53 T: Peripheral<P = T>,
54 {
55 // safety: we're returning the clone inside a new PeripheralRef that borrows
56 // self, so user code can't use both at the same time.
57 PeripheralRef::new(unsafe { self.inner.clone_unchecked() })
58 }
59
60 /// Map the inner peripheral using `Into`.
61 ///
62 /// This converts from `PeripheralRef<'a, T>` to `PeripheralRef<'a, U>`, using an
63 /// `Into` impl to convert from `T` to `U`.
64 ///
65 /// For example, this can be useful to degrade GPIO pins: converting from PeripheralRef<'a, PB11>` to `PeripheralRef<'a, AnyPin>`.
66 #[inline]
67 pub fn map_into<U>(self) -> PeripheralRef<'a, U>
68 where
69 T: Into<U>,
70 {
71 PeripheralRef {
72 inner: self.inner.into(),
73 _lifetime: PhantomData,
74 }
75 }
76}
77
78impl<'a, T> Deref for PeripheralRef<'a, T> {
79 type Target = T;
80
81 #[inline]
82 fn deref(&self) -> &Self::Target {
83 &self.inner
84 }
85}
86
87impl<'a, T> DerefMut for PeripheralRef<'a, T> {
88 #[inline]
89 fn deref_mut(&mut self) -> &mut Self::Target {
90 &mut self.inner
91 }
92}
93
94/// Trait for any type that can be used as a peripheral of type `P`.
95///
96/// This is used in driver constructors, to allow passing either owned peripherals (e.g. `TWISPI0`),
97/// or borrowed peripherals (e.g. `&mut TWISPI0`).
98///
99/// For example, if you have a driver with a constructor like this:
100///
101/// ```ignore
102/// impl<'d, T: Instance> Twim<'d, T> {
103/// pub fn new(
104/// twim: impl Peripheral<P = T> + 'd,
105/// irq: impl Peripheral<P = T::Interrupt> + 'd,
106/// sda: impl Peripheral<P = impl GpioPin> + 'd,
107/// scl: impl Peripheral<P = impl GpioPin> + 'd,
108/// config: Config,
109/// ) -> Self { .. }
110/// }
111/// ```
112///
113/// You may call it with owned peripherals, which yields an instance that can live forever (`'static`):
114///
115/// ```ignore
116/// let mut twi: Twim<'static, ...> = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
117/// ```
118///
119/// Or you may call it with borrowed peripherals, which yields an instance that can only live for as long
120/// as the borrows last:
121///
122/// ```ignore
123/// let mut twi: Twim<'_, ...> = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config);
124/// ```
125///
126/// # Implementation details, for HAL authors
127///
128/// When writing a HAL, the intended way to use this trait is to take `impl Peripheral<P = ..>` in
129/// the HAL's public API (such as driver constructors), calling `.into_ref()` to obtain a `PeripheralRef`,
130/// and storing that in the driver struct.
131///
132/// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`.
133/// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`.
134pub trait Peripheral: Sized {
135 /// Peripheral singleton type
136 type P;
137
138 /// Unsafely clone (duplicate) a peripheral singleton.
139 ///
140 /// # Safety
141 ///
142 /// This returns an owned clone of the peripheral. You must manually ensure
143 /// only one copy of the peripheral is in use at a time. For example, don't
144 /// create two SPI drivers on `SPI1`, because they will "fight" each other.
145 ///
146 /// You should strongly prefer using `into_ref()` instead. It returns a
147 /// `PeripheralRef`, which allows the borrow checker to enforce this at compile time.
148 unsafe fn clone_unchecked(&mut self) -> Self::P;
149
150 /// Convert a value into a `PeripheralRef`.
151 ///
152 /// When called on an owned `T`, yields a `PeripheralRef<'static, T>`.
153 /// When called on an `&'a mut T`, yields a `PeripheralRef<'a, T>`.
154 #[inline]
155 fn into_ref<'a>(mut self) -> PeripheralRef<'a, Self::P>
156 where
157 Self: 'a,
158 {
159 PeripheralRef::new(unsafe { self.clone_unchecked() })
160 }
161}
162
163impl<'b, T: DerefMut> Peripheral for T
164where
165 T::Target: Peripheral,
166{
167 type P = <T::Target as Peripheral>::P;
168
169 #[inline]
170 unsafe fn clone_unchecked(&mut self) -> Self::P {
171 self.deref_mut().clone_unchecked()
172 }
173}
diff --git a/embassy-hal-common/src/unborrow.rs b/embassy-hal-common/src/unborrow.rs
deleted file mode 100644
index dacfa3d42..000000000
--- a/embassy-hal-common/src/unborrow.rs
+++ /dev/null
@@ -1,60 +0,0 @@
1/// Unsafely unborrow an owned singleton out of a `&mut`.
2///
3/// It is intended to be implemented for owned peripheral singletons, such as `USART3` or `AnyPin`.
4/// Unborrowing an owned `T` yields the same `T`. Unborrowing a `&mut T` yields a copy of the T.
5///
6/// This allows writing HAL drivers that either own or borrow their peripherals, but that don't have
7/// to store pointers in the borrowed case.
8///
9/// Safety: this trait can be used to copy non-Copy types. Implementors must not cause
10/// immediate UB when copied, and must not cause UB when copies are later used, provided they
11/// are only used according the [`Self::unborrow`] safety contract.
12///
13pub unsafe trait Unborrow {
14 /// Unborrow result type
15 type Target;
16
17 /// Unborrow a value.
18 ///
19 /// Safety: This returns a copy of a singleton that's normally not
20 /// copiable. The returned copy must ONLY be used while the lifetime of `self` is
21 /// valid, as if it were accessed through `self` every time.
22 unsafe fn unborrow(self) -> Self::Target;
23}
24
25unsafe impl<'a, T: Unborrow> Unborrow for &'a mut T {
26 type Target = T::Target;
27 unsafe fn unborrow(self) -> Self::Target {
28 T::unborrow(core::ptr::read(self))
29 }
30}
31
32macro_rules! unsafe_impl_unborrow_tuples {
33 ($($t:ident),+) => {
34 unsafe impl<$($t),+> Unborrow for ($($t),+)
35 where
36 $(
37 $t: Unborrow<Target = $t>
38 ),+
39 {
40 type Target = ($($t),+);
41 unsafe fn unborrow(self) -> Self::Target {
42 self
43 }
44 }
45
46
47 };
48}
49
50unsafe_impl_unborrow_tuples!(A, B);
51unsafe_impl_unborrow_tuples!(A, B, C);
52unsafe_impl_unborrow_tuples!(A, B, C, D);
53unsafe_impl_unborrow_tuples!(A, B, C, D, E);
54unsafe_impl_unborrow_tuples!(A, B, C, D, E, F);
55unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G);
56unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H);
57unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I);
58unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J);
59unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K);
60unsafe_impl_unborrow_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
diff --git a/embassy-lora/src/stm32wl/mod.rs b/embassy-lora/src/stm32wl/mod.rs
index d7d399692..b0d101b77 100644
--- a/embassy-lora/src/stm32wl/mod.rs
+++ b/embassy-lora/src/stm32wl/mod.rs
@@ -3,7 +3,7 @@ use core::future::Future;
3use core::mem::MaybeUninit; 3use core::mem::MaybeUninit;
4 4
5use embassy::channel::signal::Signal; 5use embassy::channel::signal::Signal;
6use embassy_hal_common::unborrow; 6use embassy_hal_common::{into_ref, PeripheralRef};
7use embassy_stm32::dma::NoDma; 7use embassy_stm32::dma::NoDma;
8use embassy_stm32::gpio::{AnyPin, Output}; 8use embassy_stm32::gpio::{AnyPin, Output};
9use embassy_stm32::interrupt::{InterruptExt, SUBGHZ_RADIO}; 9use embassy_stm32::interrupt::{InterruptExt, SUBGHZ_RADIO};
@@ -12,7 +12,7 @@ use embassy_stm32::subghz::{
12 LoRaSyncWord, Ocp, PaConfig, PaSel, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF, StandbyClk, 12 LoRaSyncWord, Ocp, PaConfig, PaSel, PacketType, RampTime, RegMode, RfFreq, SpreadingFactor as SF, StandbyClk,
13 Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams, 13 Status, SubGhz, TcxoMode, TcxoTrim, Timeout, TxParams,
14}; 14};
15use embassy_stm32::Unborrow; 15use embassy_stm32::Peripheral;
16use lorawan_device::async_device::radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig}; 16use lorawan_device::async_device::radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig};
17use lorawan_device::async_device::Timings; 17use lorawan_device::async_device::Timings;
18 18
@@ -30,37 +30,37 @@ pub struct RadioError;
30 30
31static IRQ: Signal<(Status, u16)> = Signal::new(); 31static IRQ: Signal<(Status, u16)> = Signal::new();
32 32
33struct StateInner<'a> { 33struct StateInner<'d> {
34 radio: SubGhz<'a, NoDma, NoDma>, 34 radio: SubGhz<'d, NoDma, NoDma>,
35 switch: RadioSwitch<'a>, 35 switch: RadioSwitch<'d>,
36} 36}
37 37
38/// External state storage for the radio state 38/// External state storage for the radio state
39pub struct SubGhzState<'a>(MaybeUninit<StateInner<'a>>); 39pub struct SubGhzState<'a>(MaybeUninit<StateInner<'a>>);
40impl<'a> SubGhzState<'a> { 40impl<'d> SubGhzState<'d> {
41 pub const fn new() -> Self { 41 pub const fn new() -> Self {
42 Self(MaybeUninit::uninit()) 42 Self(MaybeUninit::uninit())
43 } 43 }
44} 44}
45 45
46/// The radio peripheral keeping the radio state and owning the radio IRQ. 46/// The radio peripheral keeping the radio state and owning the radio IRQ.
47pub struct SubGhzRadio<'a> { 47pub struct SubGhzRadio<'d> {
48 state: *mut StateInner<'a>, 48 state: *mut StateInner<'d>,
49 _irq: SUBGHZ_RADIO, 49 _irq: PeripheralRef<'d, SUBGHZ_RADIO>,
50} 50}
51 51
52impl<'a> SubGhzRadio<'a> { 52impl<'d> SubGhzRadio<'d> {
53 /// Create a new instance of a SubGhz radio for LoRaWAN. 53 /// Create a new instance of a SubGhz radio for LoRaWAN.
54 /// 54 ///
55 /// # Safety 55 /// # Safety
56 /// Do not leak self or futures 56 /// Do not leak self or futures
57 pub unsafe fn new( 57 pub unsafe fn new(
58 state: &'a mut SubGhzState<'a>, 58 state: &'d mut SubGhzState<'d>,
59 radio: SubGhz<'a, NoDma, NoDma>, 59 radio: SubGhz<'d, NoDma, NoDma>,
60 switch: RadioSwitch<'a>, 60 switch: RadioSwitch<'d>,
61 irq: impl Unborrow<Target = SUBGHZ_RADIO>, 61 irq: impl Peripheral<P = SUBGHZ_RADIO> + 'd,
62 ) -> Self { 62 ) -> Self {
63 unborrow!(irq); 63 into_ref!(irq);
64 64
65 let mut inner = StateInner { radio, switch }; 65 let mut inner = StateInner { radio, switch };
66 inner.radio.reset(); 66 inner.radio.reset();
@@ -73,7 +73,7 @@ impl<'a> SubGhzRadio<'a> {
73 // This is safe because we only get interrupts when configured for, so 73 // This is safe because we only get interrupts when configured for, so
74 // the radio will be awaiting on the signal at this point. If not, the ISR will 74 // the radio will be awaiting on the signal at this point. If not, the ISR will
75 // anyway only adjust the state in the IRQ signal state. 75 // anyway only adjust the state in the IRQ signal state.
76 let state = &mut *(p as *mut StateInner<'a>); 76 let state = &mut *(p as *mut StateInner<'d>);
77 state.on_interrupt(); 77 state.on_interrupt();
78 }); 78 });
79 irq.set_handler_context(state_ptr as *mut ()); 79 irq.set_handler_context(state_ptr as *mut ());
@@ -86,7 +86,7 @@ impl<'a> SubGhzRadio<'a> {
86 } 86 }
87} 87}
88 88
89impl<'a> StateInner<'a> { 89impl<'d> StateInner<'d> {
90 /// Configure radio settings in preparation for TX or RX 90 /// Configure radio settings in preparation for TX or RX
91 pub(crate) fn configure(&mut self) -> Result<(), RadioError> { 91 pub(crate) fn configure(&mut self) -> Result<(), RadioError> {
92 trace!("Configuring STM32WL SUBGHZ radio"); 92 trace!("Configuring STM32WL SUBGHZ radio");
@@ -272,13 +272,13 @@ impl PhyRxTx for SubGhzRadio<'static> {
272 } 272 }
273} 273}
274 274
275impl<'a> From<embassy_stm32::spi::Error> for RadioError { 275impl From<embassy_stm32::spi::Error> for RadioError {
276 fn from(_: embassy_stm32::spi::Error) -> Self { 276 fn from(_: embassy_stm32::spi::Error) -> Self {
277 RadioError 277 RadioError
278 } 278 }
279} 279}
280 280
281impl<'a> Timings for SubGhzRadio<'a> { 281impl<'d> Timings for SubGhzRadio<'d> {
282 fn get_rx_window_offset_ms(&self) -> i32 { 282 fn get_rx_window_offset_ms(&self) -> i32 {
283 -200 283 -200
284 } 284 }
@@ -288,14 +288,14 @@ impl<'a> Timings for SubGhzRadio<'a> {
288} 288}
289 289
290/// Represents the radio switch found on STM32WL based boards, used to control the radio for transmission or reception. 290/// Represents the radio switch found on STM32WL based boards, used to control the radio for transmission or reception.
291pub struct RadioSwitch<'a> { 291pub struct RadioSwitch<'d> {
292 ctrl1: Output<'a, AnyPin>, 292 ctrl1: Output<'d, AnyPin>,
293 ctrl2: Output<'a, AnyPin>, 293 ctrl2: Output<'d, AnyPin>,
294 ctrl3: Output<'a, AnyPin>, 294 ctrl3: Output<'d, AnyPin>,
295} 295}
296 296
297impl<'a> RadioSwitch<'a> { 297impl<'d> RadioSwitch<'d> {
298 pub fn new(ctrl1: Output<'a, AnyPin>, ctrl2: Output<'a, AnyPin>, ctrl3: Output<'a, AnyPin>) -> Self { 298 pub fn new(ctrl1: Output<'d, AnyPin>, ctrl2: Output<'d, AnyPin>, ctrl3: Output<'d, AnyPin>) -> Self {
299 Self { ctrl1, ctrl2, ctrl3 } 299 Self { ctrl1, ctrl2, ctrl3 }
300 } 300 }
301 301
diff --git a/embassy-macros/src/macros/cortex_m_interrupt_declare.rs b/embassy-macros/src/macros/cortex_m_interrupt_declare.rs
index eeed5d483..ab61ad5da 100644
--- a/embassy-macros/src/macros/cortex_m_interrupt_declare.rs
+++ b/embassy-macros/src/macros/cortex_m_interrupt_declare.rs
@@ -25,12 +25,7 @@ pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
25 } 25 }
26 } 26 }
27 27
28 unsafe impl ::embassy_hal_common::Unborrow for #name_interrupt { 28 ::embassy_hal_common::impl_peripheral!(#name_interrupt);
29 type Target = #name_interrupt;
30 unsafe fn unborrow(self) -> #name_interrupt {
31 self
32 }
33 }
34 }; 29 };
35 Ok(result) 30 Ok(result)
36} 31}
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
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index 53c26de1c..5db1a690b 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -1,15 +1,15 @@
1#![macro_use]
1use core::future::Future; 2use core::future::Future;
2use core::marker::PhantomData;
3use core::pin::Pin as FuturePin; 3use core::pin::Pin as FuturePin;
4use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
5 5
6use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
7use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; 7use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
8use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; 8use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
9 9
10use crate::pac::common::{Reg, RW}; 10use crate::pac::common::{Reg, RW};
11use crate::pac::SIO; 11use crate::pac::SIO;
12use crate::{interrupt, pac, peripherals, Unborrow}; 12use crate::{interrupt, pac, peripherals, Peripheral};
13 13
14const PIN_COUNT: usize = 30; 14const PIN_COUNT: usize = 30;
15const NEW_AW: AtomicWaker = AtomicWaker::new(); 15const NEW_AW: AtomicWaker = AtomicWaker::new();
@@ -61,7 +61,7 @@ pub struct Input<'d, T: Pin> {
61 61
62impl<'d, T: Pin> Input<'d, T> { 62impl<'d, T: Pin> Input<'d, T> {
63 #[inline] 63 #[inline]
64 pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { 64 pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
65 let mut pin = Flex::new(pin); 65 let mut pin = Flex::new(pin);
66 pin.set_as_input(); 66 pin.set_as_input();
67 pin.set_pull(pull); 67 pin.set_pull(pull);
@@ -177,13 +177,13 @@ unsafe fn IO_IRQ_BANK0() {
177} 177}
178 178
179struct InputFuture<'a, T: Pin> { 179struct InputFuture<'a, T: Pin> {
180 pin: &'a mut T, 180 pin: PeripheralRef<'a, T>,
181 level: InterruptTrigger, 181 level: InterruptTrigger,
182 phantom: PhantomData<&'a mut AnyPin>,
183} 182}
184 183
185impl<'d, T: Pin> InputFuture<'d, T> { 184impl<'d, T: Pin> InputFuture<'d, T> {
186 pub fn new(pin: &'d mut T, level: InterruptTrigger) -> Self { 185 pub fn new(pin: impl Peripheral<P = T> + 'd, level: InterruptTrigger) -> Self {
186 into_ref!(pin);
187 unsafe { 187 unsafe {
188 let irq = interrupt::IO_IRQ_BANK0::steal(); 188 let irq = interrupt::IO_IRQ_BANK0::steal();
189 irq.disable(); 189 irq.disable();
@@ -215,11 +215,7 @@ impl<'d, T: Pin> InputFuture<'d, T> {
215 irq.enable(); 215 irq.enable();
216 } 216 }
217 217
218 Self { 218 Self { pin, level }
219 pin,
220 level,
221 phantom: PhantomData,
222 }
223 } 219 }
224} 220}
225 221
@@ -294,7 +290,7 @@ pub struct Output<'d, T: Pin> {
294 290
295impl<'d, T: Pin> Output<'d, T> { 291impl<'d, T: Pin> Output<'d, T> {
296 #[inline] 292 #[inline]
297 pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level) -> Self { 293 pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level) -> Self {
298 let mut pin = Flex::new(pin); 294 let mut pin = Flex::new(pin);
299 match initial_output { 295 match initial_output {
300 Level::High => pin.set_high(), 296 Level::High => pin.set_high(),
@@ -355,7 +351,7 @@ pub struct OutputOpenDrain<'d, T: Pin> {
355 351
356impl<'d, T: Pin> OutputOpenDrain<'d, T> { 352impl<'d, T: Pin> OutputOpenDrain<'d, T> {
357 #[inline] 353 #[inline]
358 pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level) -> Self { 354 pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level) -> Self {
359 let mut pin = Flex::new(pin); 355 let mut pin = Flex::new(pin);
360 pin.set_low(); 356 pin.set_low();
361 match initial_output { 357 match initial_output {
@@ -419,14 +415,13 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
419/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output 415/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
420/// mode. 416/// mode.
421pub struct Flex<'d, T: Pin> { 417pub struct Flex<'d, T: Pin> {
422 pin: T, 418 pin: PeripheralRef<'d, T>,
423 phantom: PhantomData<&'d mut T>,
424} 419}
425 420
426impl<'d, T: Pin> Flex<'d, T> { 421impl<'d, T: Pin> Flex<'d, T> {
427 #[inline] 422 #[inline]
428 pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self { 423 pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
429 unborrow!(pin); 424 into_ref!(pin);
430 425
431 unsafe { 426 unsafe {
432 pin.pad_ctrl().write(|w| { 427 pin.pad_ctrl().write(|w| {
@@ -438,10 +433,7 @@ impl<'d, T: Pin> Flex<'d, T> {
438 }); 433 });
439 } 434 }
440 435
441 Self { 436 Self { pin }
442 pin,
443 phantom: PhantomData,
444 }
445 } 437 }
446 438
447 #[inline] 439 #[inline]
@@ -655,7 +647,7 @@ pub(crate) mod sealed {
655 } 647 }
656} 648}
657 649
658pub trait Pin: Unborrow<Target = Self> + sealed::Pin { 650pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
659 /// Degrade to a generic pin struct 651 /// Degrade to a generic pin struct
660 fn degrade(self) -> AnyPin { 652 fn degrade(self) -> AnyPin {
661 AnyPin { 653 AnyPin {
@@ -667,7 +659,9 @@ pub trait Pin: Unborrow<Target = Self> + sealed::Pin {
667pub struct AnyPin { 659pub struct AnyPin {
668 pin_bank: u8, 660 pin_bank: u8,
669} 661}
670unsafe_impl_unborrow!(AnyPin); 662
663impl_peripheral!(AnyPin);
664
671impl Pin for AnyPin {} 665impl Pin for AnyPin {}
672impl sealed::Pin for AnyPin { 666impl sealed::Pin for AnyPin {
673 fn pin_bank(&self) -> u8 { 667 fn pin_bank(&self) -> u8 {
@@ -685,6 +679,12 @@ macro_rules! impl_pin {
685 ($bank as u8) * 32 + $pin_num 679 ($bank as u8) * 32 + $pin_num
686 } 680 }
687 } 681 }
682
683 impl From<peripherals::$name> for crate::gpio::AnyPin {
684 fn from(val: peripherals::$name) -> Self {
685 crate::gpio::Pin::degrade(val)
686 }
687 }
688 }; 688 };
689} 689}
690 690
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 7da0d30c1..44150be0d 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -17,7 +17,7 @@ mod reset;
17// Reexports 17// Reexports
18 18
19pub use embassy_cortex_m::executor; 19pub use embassy_cortex_m::executor;
20pub use embassy_hal_common::{unborrow, Unborrow}; 20pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
21pub use embassy_macros::cortex_m_interrupt as interrupt; 21pub use embassy_macros::cortex_m_interrupt as interrupt;
22#[cfg(feature = "unstable-pac")] 22#[cfg(feature = "unstable-pac")]
23pub use rp2040_pac2 as pac; 23pub use rp2040_pac2 as pac;
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index 6b3f2238a..d0261598e 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -1,12 +1,10 @@
1use core::marker::PhantomData;
2
3use embassy_embedded_hal::SetConfig; 1use embassy_embedded_hal::SetConfig;
4use embassy_hal_common::unborrow; 2use embassy_hal_common::{into_ref, PeripheralRef};
5pub use embedded_hal_02::spi::{Phase, Polarity}; 3pub use embedded_hal_02::spi::{Phase, Polarity};
6 4
7use crate::gpio::sealed::Pin as _; 5use crate::gpio::sealed::Pin as _;
8use crate::gpio::{AnyPin, Pin as GpioPin}; 6use crate::gpio::{AnyPin, Pin as GpioPin};
9use crate::{pac, peripherals, Unborrow}; 7use crate::{pac, peripherals, Peripheral};
10 8
11#[derive(Debug, Clone, Copy, PartialEq, Eq)] 9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[cfg_attr(feature = "defmt", derive(defmt::Format))] 10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -33,8 +31,7 @@ impl Default for Config {
33} 31}
34 32
35pub struct Spi<'d, T: Instance> { 33pub struct Spi<'d, T: Instance> {
36 inner: T, 34 inner: PeripheralRef<'d, T>,
37 phantom: PhantomData<&'d mut T>,
38} 35}
39 36
40fn div_roundup(a: u32, b: u32) -> u32 { 37fn div_roundup(a: u32, b: u32) -> u32 {
@@ -62,52 +59,52 @@ fn calc_prescs(freq: u32) -> (u8, u8) {
62 59
63impl<'d, T: Instance> Spi<'d, T> { 60impl<'d, T: Instance> Spi<'d, T> {
64 pub fn new( 61 pub fn new(
65 inner: impl Unborrow<Target = T> + 'd, 62 inner: impl Peripheral<P = T> + 'd,
66 clk: impl Unborrow<Target = impl ClkPin<T>> + 'd, 63 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
67 mosi: impl Unborrow<Target = impl MosiPin<T>> + 'd, 64 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd,
68 miso: impl Unborrow<Target = impl MisoPin<T>> + 'd, 65 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd,
69 config: Config, 66 config: Config,
70 ) -> Self { 67 ) -> Self {
71 unborrow!(clk, mosi, miso); 68 into_ref!(clk, mosi, miso);
72 Self::new_inner( 69 Self::new_inner(
73 inner, 70 inner,
74 Some(clk.degrade()), 71 Some(clk.map_into()),
75 Some(mosi.degrade()), 72 Some(mosi.map_into()),
76 Some(miso.degrade()), 73 Some(miso.map_into()),
77 None, 74 None,
78 config, 75 config,
79 ) 76 )
80 } 77 }
81 78
82 pub fn new_txonly( 79 pub fn new_txonly(
83 inner: impl Unborrow<Target = T> + 'd, 80 inner: impl Peripheral<P = T> + 'd,
84 clk: impl Unborrow<Target = impl ClkPin<T>> + 'd, 81 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
85 mosi: impl Unborrow<Target = impl MosiPin<T>> + 'd, 82 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd,
86 config: Config, 83 config: Config,
87 ) -> Self { 84 ) -> Self {
88 unborrow!(clk, mosi); 85 into_ref!(clk, mosi);
89 Self::new_inner(inner, Some(clk.degrade()), Some(mosi.degrade()), None, None, config) 86 Self::new_inner(inner, Some(clk.map_into()), Some(mosi.map_into()), None, None, config)
90 } 87 }
91 88
92 pub fn new_rxonly( 89 pub fn new_rxonly(
93 inner: impl Unborrow<Target = T> + 'd, 90 inner: impl Peripheral<P = T> + 'd,
94 clk: impl Unborrow<Target = impl ClkPin<T>> + 'd, 91 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
95 miso: impl Unborrow<Target = impl MisoPin<T>> + 'd, 92 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd,
96 config: Config, 93 config: Config,
97 ) -> Self { 94 ) -> Self {
98 unborrow!(clk, miso); 95 into_ref!(clk, miso);
99 Self::new_inner(inner, Some(clk.degrade()), None, Some(miso.degrade()), None, config) 96 Self::new_inner(inner, Some(clk.map_into()), None, Some(miso.map_into()), None, config)
100 } 97 }
101 98
102 fn new_inner( 99 fn new_inner(
103 inner: impl Unborrow<Target = T> + 'd, 100 inner: impl Peripheral<P = T> + 'd,
104 clk: Option<AnyPin>, 101 clk: Option<PeripheralRef<'d, AnyPin>>,
105 mosi: Option<AnyPin>, 102 mosi: Option<PeripheralRef<'d, AnyPin>>,
106 miso: Option<AnyPin>, 103 miso: Option<PeripheralRef<'d, AnyPin>>,
107 cs: Option<AnyPin>, 104 cs: Option<PeripheralRef<'d, AnyPin>>,
108 config: Config, 105 config: Config,
109 ) -> Self { 106 ) -> Self {
110 unborrow!(inner); 107 into_ref!(inner);
111 108
112 unsafe { 109 unsafe {
113 let p = inner.regs(); 110 let p = inner.regs();
@@ -137,10 +134,7 @@ impl<'d, T: Instance> Spi<'d, T> {
137 pin.io().ctrl().write(|w| w.set_funcsel(1)); 134 pin.io().ctrl().write(|w| w.set_funcsel(1));
138 } 135 }
139 } 136 }
140 Self { 137 Self { inner }
141 inner,
142 phantom: PhantomData,
143 }
144 } 138 }
145 139
146 pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> { 140 pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> {
diff --git a/embassy-rp/src/uart.rs b/embassy-rp/src/uart.rs
index c95407b6f..b19f043f8 100644
--- a/embassy-rp/src/uart.rs
+++ b/embassy-rp/src/uart.rs
@@ -1,9 +1,7 @@
1use core::marker::PhantomData; 1use embassy_hal_common::{into_ref, PeripheralRef};
2
3use embassy_hal_common::unborrow;
4use gpio::Pin; 2use gpio::Pin;
5 3
6use crate::{gpio, pac, peripherals, Unborrow}; 4use crate::{gpio, pac, peripherals, Peripheral};
7 5
8#[non_exhaustive] 6#[non_exhaustive]
9pub struct Config { 7pub struct Config {
@@ -23,20 +21,19 @@ impl Default for Config {
23} 21}
24 22
25pub struct Uart<'d, T: Instance> { 23pub struct Uart<'d, T: Instance> {
26 inner: T, 24 inner: PeripheralRef<'d, T>,
27 phantom: PhantomData<&'d mut T>,
28} 25}
29 26
30impl<'d, T: Instance> Uart<'d, T> { 27impl<'d, T: Instance> Uart<'d, T> {
31 pub fn new( 28 pub fn new(
32 inner: impl Unborrow<Target = T> + 'd, 29 inner: impl Peripheral<P = T> + 'd,
33 tx: impl Unborrow<Target = impl TxPin<T>> + 'd, 30 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
34 rx: impl Unborrow<Target = impl RxPin<T>> + 'd, 31 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
35 cts: impl Unborrow<Target = impl CtsPin<T>> + 'd, 32 cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
36 rts: impl Unborrow<Target = impl RtsPin<T>> + 'd, 33 rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
37 config: Config, 34 config: Config,
38 ) -> Self { 35 ) -> Self {
39 unborrow!(inner, tx, rx, cts, rts); 36 into_ref!(inner, tx, rx, cts, rts);
40 37
41 unsafe { 38 unsafe {
42 let p = inner.regs(); 39 let p = inner.regs();
@@ -78,10 +75,7 @@ impl<'d, T: Instance> Uart<'d, T> {
78 cts.io().ctrl().write(|w| w.set_funcsel(2)); 75 cts.io().ctrl().write(|w| w.set_funcsel(2));
79 rts.io().ctrl().write(|w| w.set_funcsel(2)); 76 rts.io().ctrl().write(|w| w.set_funcsel(2));
80 } 77 }
81 Self { 78 Self { inner }
82 inner,
83 phantom: PhantomData,
84 }
85 } 79 }
86 80
87 pub fn send(&mut self, data: &[u8]) { 81 pub fn send(&mut self, data: &[u8]) {
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 74cfac136..50d4f9bf9 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -1,12 +1,12 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::unborrow; 3use embassy_hal_common::into_ref;
4use embedded_hal_02::blocking::delay::DelayUs; 4use embedded_hal_02::blocking::delay::DelayUs;
5 5
6use crate::adc::{AdcPin, Instance}; 6use crate::adc::{AdcPin, Instance};
7use crate::rcc::get_freqs; 7use crate::rcc::get_freqs;
8use crate::time::Hertz; 8use crate::time::Hertz;
9use crate::Unborrow; 9use crate::Peripheral;
10 10
11pub const VDDA_CALIB_MV: u32 = 3300; 11pub const VDDA_CALIB_MV: u32 = 3300;
12pub const ADC_MAX: u32 = (1 << 12) - 1; 12pub const ADC_MAX: u32 = (1 << 12) - 1;
@@ -91,8 +91,8 @@ pub struct Adc<'d, T: Instance> {
91} 91}
92 92
93impl<'d, T: Instance> Adc<'d, T> { 93impl<'d, T: Instance> Adc<'d, T> {
94 pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 94 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
95 unborrow!(_peri); 95 into_ref!(_peri);
96 T::enable(); 96 T::enable();
97 T::reset(); 97 T::reset();
98 unsafe { 98 unsafe {
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 936a35562..5c608451b 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,11 +1,11 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::unborrow; 3use embassy_hal_common::into_ref;
4use embedded_hal_02::blocking::delay::DelayUs; 4use embedded_hal_02::blocking::delay::DelayUs;
5 5
6use crate::adc::{AdcPin, Instance}; 6use crate::adc::{AdcPin, Instance};
7use crate::time::Hertz; 7use crate::time::Hertz;
8use crate::Unborrow; 8use crate::Peripheral;
9 9
10pub const VDDA_CALIB_MV: u32 = 3000; 10pub const VDDA_CALIB_MV: u32 = 3000;
11 11
@@ -159,8 +159,8 @@ impl<'d, T> Adc<'d, T>
159where 159where
160 T: Instance, 160 T: Instance,
161{ 161{
162 pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 162 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
163 unborrow!(_peri); 163 into_ref!(_peri);
164 enable(); 164 enable();
165 165
166 let presc = unsafe { Prescaler::from_pclk2(crate::rcc::get_freqs().apb2) }; 166 let presc = unsafe { Prescaler::from_pclk2(crate::rcc::get_freqs().apb2) };
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 49d149b18..dbfd18810 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -1,10 +1,10 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::unborrow; 3use embassy_hal_common::into_ref;
4use embedded_hal_02::blocking::delay::DelayUs; 4use embedded_hal_02::blocking::delay::DelayUs;
5 5
6use crate::adc::{AdcPin, Instance}; 6use crate::adc::{AdcPin, Instance};
7use crate::Unborrow; 7use crate::Peripheral;
8 8
9pub const VDDA_CALIB_MV: u32 = 3000; 9pub const VDDA_CALIB_MV: u32 = 3000;
10 10
@@ -208,8 +208,8 @@ pub struct Adc<'d, T: Instance> {
208} 208}
209 209
210impl<'d, T: Instance> Adc<'d, T> { 210impl<'d, T: Instance> Adc<'d, T> {
211 pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 211 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
212 unborrow!(_peri); 212 into_ref!(_peri);
213 enable(); 213 enable();
214 unsafe { 214 unsafe {
215 T::regs().cr().modify(|reg| { 215 T::regs().cr().modify(|reg| {
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 3f933f4fc..92e8ac369 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -7,7 +7,7 @@ use pac::adccommon::vals::Presc;
7 7
8use super::{AdcPin, Instance}; 8use super::{AdcPin, Instance};
9use crate::time::Hertz; 9use crate::time::Hertz;
10use crate::{pac, Unborrow}; 10use crate::{pac, Peripheral};
11 11
12pub enum Resolution { 12pub enum Resolution {
13 SixteenBit, 13 SixteenBit,
@@ -322,8 +322,8 @@ pub struct Adc<'d, T: Instance> {
322} 322}
323 323
324impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> { 324impl<'d, T: Instance + crate::rcc::RccPeripheral> Adc<'d, T> {
325 pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self { 325 pub fn new(_peri: impl Peripheral<P = T> + 'd, delay: &mut impl DelayUs<u16>) -> Self {
326 embassy_hal_common::unborrow!(_peri); 326 embassy_hal_common::into_ref!(_peri);
327 T::enable(); 327 T::enable();
328 T::reset(); 328 T::reset();
329 329
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs
index b54fd3ff3..c0bd44e0f 100644
--- a/embassy-stm32/src/can/bxcan.rs
+++ b/embassy-stm32/src/can/bxcan.rs
@@ -1,25 +1,23 @@
1use core::marker::PhantomData;
2use core::ops::{Deref, DerefMut}; 1use core::ops::{Deref, DerefMut};
3 2
4pub use bxcan; 3pub use bxcan;
5use embassy_hal_common::unborrow; 4use embassy_hal_common::{into_ref, PeripheralRef};
6 5
7use crate::gpio::sealed::AFType; 6use crate::gpio::sealed::AFType;
8use crate::rcc::RccPeripheral; 7use crate::rcc::RccPeripheral;
9use crate::{peripherals, Unborrow}; 8use crate::{peripherals, Peripheral};
10 9
11pub struct Can<'d, T: Instance + bxcan::Instance> { 10pub struct Can<'d, T: Instance> {
12 phantom: PhantomData<&'d mut T>, 11 can: bxcan::Can<BxcanInstance<'d, T>>,
13 can: bxcan::Can<T>,
14} 12}
15 13
16impl<'d, T: Instance + bxcan::Instance> Can<'d, T> { 14impl<'d, T: Instance> Can<'d, T> {
17 pub fn new( 15 pub fn new(
18 peri: impl Unborrow<Target = T> + 'd, 16 peri: impl Peripheral<P = T> + 'd,
19 rx: impl Unborrow<Target = impl RxPin<T>> + 'd, 17 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
20 tx: impl Unborrow<Target = impl TxPin<T>> + 'd, 18 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
21 ) -> Self { 19 ) -> Self {
22 unborrow!(peri, rx, tx); 20 into_ref!(peri, rx, tx);
23 21
24 unsafe { 22 unsafe {
25 rx.set_as_af(rx.af_num(), AFType::Input); 23 rx.set_as_af(rx.af_num(), AFType::Input);
@@ -30,32 +28,29 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> {
30 T::reset(); 28 T::reset();
31 29
32 Self { 30 Self {
33 phantom: PhantomData, 31 can: bxcan::Can::builder(BxcanInstance(peri)).enable(),
34 can: bxcan::Can::builder(peri).enable(),
35 } 32 }
36 } 33 }
37} 34}
38 35
39impl<'d, T: Instance + bxcan::Instance> Drop for Can<'d, T> { 36impl<'d, T: Instance> Drop for Can<'d, T> {
40 fn drop(&mut self) { 37 fn drop(&mut self) {
41 // Cannot call `free()` because it moves the instance. 38 // Cannot call `free()` because it moves the instance.
42 // Manually reset the peripheral. 39 // Manually reset the peripheral.
43 unsafe { 40 unsafe { T::regs().mcr().write(|w| w.set_reset(true)) }
44 T::regs().mcr().write(|w| w.set_reset(true));
45 }
46 T::disable(); 41 T::disable();
47 } 42 }
48} 43}
49 44
50impl<'d, T: Instance + bxcan::Instance> Deref for Can<'d, T> { 45impl<'d, T: Instance> Deref for Can<'d, T> {
51 type Target = bxcan::Can<T>; 46 type Target = bxcan::Can<BxcanInstance<'d, T>>;
52 47
53 fn deref(&self) -> &Self::Target { 48 fn deref(&self) -> &Self::Target {
54 &self.can 49 &self.can
55 } 50 }
56} 51}
57 52
58impl<'d, T: Instance + bxcan::Instance> DerefMut for Can<'d, T> { 53impl<'d, T: Instance> DerefMut for Can<'d, T> {
59 fn deref_mut(&mut self) -> &mut Self::Target { 54 fn deref_mut(&mut self) -> &mut Self::Target {
60 &mut self.can 55 &mut self.can
61 } 56 }
@@ -63,15 +58,25 @@ impl<'d, T: Instance + bxcan::Instance> DerefMut for Can<'d, T> {
63 58
64pub(crate) mod sealed { 59pub(crate) mod sealed {
65 pub trait Instance { 60 pub trait Instance {
61 const REGISTERS: *mut bxcan::RegisterBlock;
62
66 fn regs() -> &'static crate::pac::can::Can; 63 fn regs() -> &'static crate::pac::can::Can;
67 } 64 }
68} 65}
69 66
70pub trait Instance: sealed::Instance + RccPeripheral {} 67pub trait Instance: sealed::Instance + RccPeripheral {}
71 68
69pub struct BxcanInstance<'a, T>(PeripheralRef<'a, T>);
70
71unsafe impl<'d, T: Instance> bxcan::Instance for BxcanInstance<'d, T> {
72 const REGISTERS: *mut bxcan::RegisterBlock = T::REGISTERS;
73}
74
72foreach_peripheral!( 75foreach_peripheral!(
73 (can, $inst:ident) => { 76 (can, $inst:ident) => {
74 impl sealed::Instance for peripherals::$inst { 77 impl sealed::Instance for peripherals::$inst {
78 const REGISTERS: *mut bxcan::RegisterBlock = crate::pac::$inst.0 as *mut _;
79
75 fn regs() -> &'static crate::pac::can::Can { 80 fn regs() -> &'static crate::pac::can::Can {
76 &crate::pac::$inst 81 &crate::pac::$inst
77 } 82 }
@@ -79,15 +84,12 @@ foreach_peripheral!(
79 84
80 impl Instance for peripherals::$inst {} 85 impl Instance for peripherals::$inst {}
81 86
82 unsafe impl bxcan::Instance for peripherals::$inst {
83 const REGISTERS: *mut bxcan::RegisterBlock = crate::pac::$inst.0 as *mut _;
84 }
85 }; 87 };
86); 88);
87 89
88foreach_peripheral!( 90foreach_peripheral!(
89 (can, CAN) => { 91 (can, CAN) => {
90 unsafe impl bxcan::FilterOwner for peripherals::CAN { 92 unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN> {
91 const NUM_FILTER_BANKS: u8 = 14; 93 const NUM_FILTER_BANKS: u8 = 14;
92 } 94 }
93 }; 95 };
@@ -102,19 +104,19 @@ foreach_peripheral!(
102 ))] { 104 ))] {
103 // Most L4 devices and some F7 devices use the name "CAN1" 105 // Most L4 devices and some F7 devices use the name "CAN1"
104 // even if there is no "CAN2" peripheral. 106 // even if there is no "CAN2" peripheral.
105 unsafe impl bxcan::FilterOwner for peripherals::CAN1 { 107 unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN1> {
106 const NUM_FILTER_BANKS: u8 = 14; 108 const NUM_FILTER_BANKS: u8 = 14;
107 } 109 }
108 } else { 110 } else {
109 unsafe impl bxcan::FilterOwner for peripherals::CAN1 { 111 unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN1> {
110 const NUM_FILTER_BANKS: u8 = 28; 112 const NUM_FILTER_BANKS: u8 = 28;
111 } 113 }
112 unsafe impl bxcan::MasterInstance for peripherals::CAN1 {} 114 unsafe impl<'d> bxcan::MasterInstance for BxcanInstance<'d, peripherals::CAN1> {}
113 } 115 }
114 } 116 }
115 }; 117 };
116 (can, CAN3) => { 118 (can, CAN3) => {
117 unsafe impl bxcan::FilterOwner for peripherals::CAN3 { 119 unsafe impl<'d> bxcan::FilterOwner for BxcanInstance<'d, peripherals::CAN3> {
118 const NUM_FILTER_BANKS: u8 = 14; 120 const NUM_FILTER_BANKS: u8 = 14;
119 } 121 }
120 }; 122 };
diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs
index 87133714c..393089eed 100644
--- a/embassy-stm32/src/crc/v1.rs
+++ b/embassy-stm32/src/crc/v1.rs
@@ -1,31 +1,26 @@
1use core::marker::PhantomData; 1use embassy_hal_common::{into_ref, PeripheralRef};
2
3use embassy_hal_common::unborrow;
4 2
5use crate::pac::CRC as PAC_CRC; 3use crate::pac::CRC as PAC_CRC;
6use crate::peripherals::CRC; 4use crate::peripherals::CRC;
7use crate::rcc::sealed::RccPeripheral; 5use crate::rcc::sealed::RccPeripheral;
8use crate::Unborrow; 6use crate::Peripheral;
9 7
10pub struct Crc<'d> { 8pub struct Crc<'d> {
11 _peripheral: CRC, 9 _peri: PeripheralRef<'d, CRC>,
12 _phantom: PhantomData<&'d mut CRC>,
13} 10}
14 11
15impl<'d> Crc<'d> { 12impl<'d> Crc<'d> {
16 /// Instantiates the CRC32 peripheral and initializes it to default values. 13 /// Instantiates the CRC32 peripheral and initializes it to default values.
17 pub fn new(peripheral: impl Unborrow<Target = CRC> + 'd) -> Self { 14 pub fn new(peripheral: impl Peripheral<P = CRC> + 'd) -> Self {
15 into_ref!(peripheral);
16
18 // Note: enable and reset come from RccPeripheral. 17 // Note: enable and reset come from RccPeripheral.
19 // enable CRC clock in RCC. 18 // enable CRC clock in RCC.
20 CRC::enable(); 19 CRC::enable();
21 // Reset CRC to default values. 20 // Reset CRC to default values.
22 CRC::reset(); 21 CRC::reset();
23 // Unborrow the peripheral 22 // Peripheral the peripheral
24 unborrow!(peripheral); 23 let mut instance = Self { _peri: peripheral };
25 let mut instance = Self {
26 _peripheral: peripheral,
27 _phantom: PhantomData,
28 };
29 instance.reset(); 24 instance.reset();
30 instance 25 instance
31 } 26 }
diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs
index 63f24e4e1..8acb3a770 100644
--- a/embassy-stm32/src/crc/v2v3.rs
+++ b/embassy-stm32/src/crc/v2v3.rs
@@ -1,16 +1,13 @@
1use core::marker::PhantomData; 1use embassy_hal_common::{into_ref, PeripheralRef};
2
3use embassy_hal_common::unborrow;
4 2
5use crate::pac::crc::vals; 3use crate::pac::crc::vals;
6use crate::pac::CRC as PAC_CRC; 4use crate::pac::CRC as PAC_CRC;
7use crate::peripherals::CRC; 5use crate::peripherals::CRC;
8use crate::rcc::sealed::RccPeripheral; 6use crate::rcc::sealed::RccPeripheral;
9use crate::Unborrow; 7use crate::Peripheral;
10 8
11pub struct Crc<'d> { 9pub struct Crc<'d> {
12 _peripheral: CRC, 10 _peripheral: PeripheralRef<'d, CRC>,
13 _phantom: PhantomData<&'d mut CRC>,
14 _config: Config, 11 _config: Config,
15} 12}
16 13
@@ -70,16 +67,15 @@ pub enum PolySize {
70 67
71impl<'d> Crc<'d> { 68impl<'d> Crc<'d> {
72 /// Instantiates the CRC32 peripheral and initializes it to default values. 69 /// Instantiates the CRC32 peripheral and initializes it to default values.
73 pub fn new(peripheral: impl Unborrow<Target = CRC> + 'd, config: Config) -> Self { 70 pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self {
74 // Note: enable and reset come from RccPeripheral. 71 // Note: enable and reset come from RccPeripheral.
75 // enable CRC clock in RCC. 72 // enable CRC clock in RCC.
76 CRC::enable(); 73 CRC::enable();
77 // Reset CRC to default values. 74 // Reset CRC to default values.
78 CRC::reset(); 75 CRC::reset();
79 unborrow!(peripheral); 76 into_ref!(peripheral);
80 let mut instance = Self { 77 let mut instance = Self {
81 _peripheral: peripheral, 78 _peripheral: peripheral,
82 _phantom: PhantomData,
83 _config: config, 79 _config: config,
84 }; 80 };
85 CRC::reset(); 81 CRC::reset();
diff --git a/embassy-stm32/src/dac/v2.rs b/embassy-stm32/src/dac/v2.rs
index ba7856a5a..6b7f41c63 100644
--- a/embassy-stm32/src/dac/v2.rs
+++ b/embassy-stm32/src/dac/v2.rs
@@ -1,10 +1,8 @@
1use core::marker::PhantomData; 1use embassy_hal_common::{into_ref, PeripheralRef};
2
3use embassy_hal_common::unborrow;
4 2
5use crate::dac::{DacPin, Instance}; 3use crate::dac::{DacPin, Instance};
6use crate::pac::dac; 4use crate::pac::dac;
7use crate::Unborrow; 5use crate::Peripheral;
8 6
9#[derive(Debug, Copy, Clone, Eq, PartialEq)] 7#[derive(Debug, Copy, Clone, Eq, PartialEq)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))] 8#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -90,7 +88,7 @@ pub enum Value {
90 88
91pub struct Dac<'d, T: Instance> { 89pub struct Dac<'d, T: Instance> {
92 channels: u8, 90 channels: u8,
93 phantom: PhantomData<&'d mut T>, 91 _peri: PeripheralRef<'d, T>,
94} 92}
95 93
96macro_rules! enable { 94macro_rules! enable {
@@ -102,21 +100,21 @@ macro_rules! enable {
102} 100}
103 101
104impl<'d, T: Instance> Dac<'d, T> { 102impl<'d, T: Instance> Dac<'d, T> {
105 pub fn new_1ch(peri: impl Unborrow<Target = T> + 'd, _ch1: impl Unborrow<Target = impl DacPin<T, 1>> + 'd) -> Self { 103 pub fn new_1ch(peri: impl Peripheral<P = T> + 'd, _ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd) -> Self {
106 unborrow!(peri); 104 into_ref!(peri);
107 Self::new_inner(peri, 1) 105 Self::new_inner(peri, 1)
108 } 106 }
109 107
110 pub fn new_2ch( 108 pub fn new_2ch(
111 peri: impl Unborrow<Target = T> + 'd, 109 peri: impl Peripheral<P = T> + 'd,
112 _ch1: impl Unborrow<Target = impl DacPin<T, 1>> + 'd, 110 _ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd,
113 _ch2: impl Unborrow<Target = impl DacPin<T, 2>> + 'd, 111 _ch2: impl Peripheral<P = impl DacPin<T, 2>> + 'd,
114 ) -> Self { 112 ) -> Self {
115 unborrow!(peri); 113 into_ref!(peri);
116 Self::new_inner(peri, 2) 114 Self::new_inner(peri, 2)
117 } 115 }
118 116
119 fn new_inner(_peri: T, channels: u8) -> Self { 117 fn new_inner(peri: PeripheralRef<'d, T>, channels: u8) -> Self {
120 unsafe { 118 unsafe {
121 // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock 119 // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock
122 // configuration. 120 // configuration.
@@ -144,10 +142,7 @@ impl<'d, T: Instance> Dac<'d, T> {
144 } 142 }
145 } 143 }
146 144
147 Self { 145 Self { channels, _peri: peri }
148 channels,
149 phantom: PhantomData,
150 }
151 } 146 }
152 147
153 /// Check the channel is configured 148 /// Check the channel is configured
diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs
index f4ca93a71..e28225426 100644
--- a/embassy-stm32/src/dcmi.rs
+++ b/embassy-stm32/src/dcmi.rs
@@ -1,14 +1,13 @@
1use core::marker::PhantomData;
2use core::task::Poll; 1use core::task::Poll;
3 2
4use embassy::waitqueue::AtomicWaker; 3use embassy::waitqueue::AtomicWaker;
5use embassy_hal_common::unborrow; 4use embassy_hal_common::{into_ref, PeripheralRef};
6use futures::future::poll_fn; 5use futures::future::poll_fn;
7 6
8use crate::gpio::sealed::AFType; 7use crate::gpio::sealed::AFType;
9use crate::gpio::Speed; 8use crate::gpio::Speed;
10use crate::interrupt::{Interrupt, InterruptExt}; 9use crate::interrupt::{Interrupt, InterruptExt};
11use crate::Unborrow; 10use crate::Peripheral;
12 11
13/// The level on the VSync pin when the data is not valid on the parallel interface. 12/// The level on the VSync pin when the data is not valid on the parallel interface.
14#[derive(Clone, Copy, PartialEq)] 13#[derive(Clone, Copy, PartialEq)]
@@ -70,7 +69,7 @@ impl Default for Config {
70 69
71macro_rules! config_pins { 70macro_rules! config_pins {
72 ($($pin:ident),*) => { 71 ($($pin:ident),*) => {
73 unborrow!($($pin),*); 72 into_ref!($($pin),*);
74 // NOTE(unsafe) Exclusive access to the registers 73 // NOTE(unsafe) Exclusive access to the registers
75 critical_section::with(|_| unsafe { 74 critical_section::with(|_| unsafe {
76 $( 75 $(
@@ -82,9 +81,8 @@ macro_rules! config_pins {
82} 81}
83 82
84pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> { 83pub struct Dcmi<'d, T: Instance, Dma: FrameDma<T>> {
85 inner: T, 84 inner: PeripheralRef<'d, T>,
86 dma: Dma, 85 dma: PeripheralRef<'d, Dma>,
87 phantom: PhantomData<&'d mut T>,
88} 86}
89 87
90impl<'d, T, Dma> Dcmi<'d, T, Dma> 88impl<'d, T, Dma> Dcmi<'d, T, Dma>
@@ -93,23 +91,23 @@ where
93 Dma: FrameDma<T>, 91 Dma: FrameDma<T>,
94{ 92{
95 pub fn new_8bit( 93 pub fn new_8bit(
96 peri: impl Unborrow<Target = T> + 'd, 94 peri: impl Peripheral<P = T> + 'd,
97 dma: impl Unborrow<Target = Dma> + 'd, 95 dma: impl Peripheral<P = Dma> + 'd,
98 irq: impl Unborrow<Target = T::Interrupt> + 'd, 96 irq: impl Peripheral<P = T::Interrupt> + 'd,
99 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd, 97 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
100 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd, 98 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
101 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd, 99 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
102 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd, 100 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
103 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd, 101 d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
104 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd, 102 d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
105 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd, 103 d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
106 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd, 104 d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
107 v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd, 105 v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd,
108 h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd, 106 h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd,
109 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd, 107 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
110 config: Config, 108 config: Config,
111 ) -> Self { 109 ) -> Self {
112 unborrow!(peri, dma, irq); 110 into_ref!(peri, dma, irq);
113 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7); 111 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
114 config_pins!(v_sync, h_sync, pixclk); 112 config_pins!(v_sync, h_sync, pixclk);
115 113
@@ -117,25 +115,25 @@ where
117 } 115 }
118 116
119 pub fn new_10bit( 117 pub fn new_10bit(
120 peri: impl Unborrow<Target = T> + 'd, 118 peri: impl Peripheral<P = T> + 'd,
121 dma: impl Unborrow<Target = Dma> + 'd, 119 dma: impl Peripheral<P = Dma> + 'd,
122 irq: impl Unborrow<Target = T::Interrupt> + 'd, 120 irq: impl Peripheral<P = T::Interrupt> + 'd,
123 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd, 121 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
124 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd, 122 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
125 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd, 123 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
126 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd, 124 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
127 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd, 125 d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
128 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd, 126 d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
129 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd, 127 d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
130 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd, 128 d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
131 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd, 129 d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
132 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd, 130 d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
133 v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd, 131 v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd,
134 h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd, 132 h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd,
135 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd, 133 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
136 config: Config, 134 config: Config,
137 ) -> Self { 135 ) -> Self {
138 unborrow!(peri, dma, irq); 136 into_ref!(peri, dma, irq);
139 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); 137 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
140 config_pins!(v_sync, h_sync, pixclk); 138 config_pins!(v_sync, h_sync, pixclk);
141 139
@@ -143,27 +141,27 @@ where
143 } 141 }
144 142
145 pub fn new_12bit( 143 pub fn new_12bit(
146 peri: impl Unborrow<Target = T> + 'd, 144 peri: impl Peripheral<P = T> + 'd,
147 dma: impl Unborrow<Target = Dma> + 'd, 145 dma: impl Peripheral<P = Dma> + 'd,
148 irq: impl Unborrow<Target = T::Interrupt> + 'd, 146 irq: impl Peripheral<P = T::Interrupt> + 'd,
149 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd, 147 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
150 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd, 148 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
151 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd, 149 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
152 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd, 150 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
153 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd, 151 d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
154 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd, 152 d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
155 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd, 153 d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
156 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd, 154 d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
157 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd, 155 d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
158 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd, 156 d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
159 d10: impl Unborrow<Target = impl D10Pin<T>> + 'd, 157 d10: impl Peripheral<P = impl D10Pin<T>> + 'd,
160 d11: impl Unborrow<Target = impl D11Pin<T>> + 'd, 158 d11: impl Peripheral<P = impl D11Pin<T>> + 'd,
161 v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd, 159 v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd,
162 h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd, 160 h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd,
163 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd, 161 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
164 config: Config, 162 config: Config,
165 ) -> Self { 163 ) -> Self {
166 unborrow!(peri, dma, irq); 164 into_ref!(peri, dma, irq);
167 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); 165 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
168 config_pins!(v_sync, h_sync, pixclk); 166 config_pins!(v_sync, h_sync, pixclk);
169 167
@@ -171,29 +169,29 @@ where
171 } 169 }
172 170
173 pub fn new_14bit( 171 pub fn new_14bit(
174 peri: impl Unborrow<Target = T> + 'd, 172 peri: impl Peripheral<P = T> + 'd,
175 dma: impl Unborrow<Target = Dma> + 'd, 173 dma: impl Peripheral<P = Dma> + 'd,
176 irq: impl Unborrow<Target = T::Interrupt> + 'd, 174 irq: impl Peripheral<P = T::Interrupt> + 'd,
177 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd, 175 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
178 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd, 176 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
179 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd, 177 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
180 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd, 178 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
181 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd, 179 d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
182 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd, 180 d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
183 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd, 181 d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
184 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd, 182 d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
185 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd, 183 d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
186 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd, 184 d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
187 d10: impl Unborrow<Target = impl D10Pin<T>> + 'd, 185 d10: impl Peripheral<P = impl D10Pin<T>> + 'd,
188 d11: impl Unborrow<Target = impl D11Pin<T>> + 'd, 186 d11: impl Peripheral<P = impl D11Pin<T>> + 'd,
189 d12: impl Unborrow<Target = impl D12Pin<T>> + 'd, 187 d12: impl Peripheral<P = impl D12Pin<T>> + 'd,
190 d13: impl Unborrow<Target = impl D13Pin<T>> + 'd, 188 d13: impl Peripheral<P = impl D13Pin<T>> + 'd,
191 v_sync: impl Unborrow<Target = impl VSyncPin<T>> + 'd, 189 v_sync: impl Peripheral<P = impl VSyncPin<T>> + 'd,
192 h_sync: impl Unborrow<Target = impl HSyncPin<T>> + 'd, 190 h_sync: impl Peripheral<P = impl HSyncPin<T>> + 'd,
193 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd, 191 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
194 config: Config, 192 config: Config,
195 ) -> Self { 193 ) -> Self {
196 unborrow!(peri, dma, irq); 194 into_ref!(peri, dma, irq);
197 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); 195 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
198 config_pins!(v_sync, h_sync, pixclk); 196 config_pins!(v_sync, h_sync, pixclk);
199 197
@@ -201,21 +199,21 @@ where
201 } 199 }
202 200
203 pub fn new_es_8bit( 201 pub fn new_es_8bit(
204 peri: impl Unborrow<Target = T> + 'd, 202 peri: impl Peripheral<P = T> + 'd,
205 dma: impl Unborrow<Target = Dma> + 'd, 203 dma: impl Peripheral<P = Dma> + 'd,
206 irq: impl Unborrow<Target = T::Interrupt> + 'd, 204 irq: impl Peripheral<P = T::Interrupt> + 'd,
207 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd, 205 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
208 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd, 206 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
209 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd, 207 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
210 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd, 208 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
211 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd, 209 d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
212 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd, 210 d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
213 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd, 211 d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
214 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd, 212 d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
215 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd, 213 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
216 config: Config, 214 config: Config,
217 ) -> Self { 215 ) -> Self {
218 unborrow!(peri, dma, irq); 216 into_ref!(peri, dma, irq);
219 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7); 217 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7);
220 config_pins!(pixclk); 218 config_pins!(pixclk);
221 219
@@ -223,23 +221,23 @@ where
223 } 221 }
224 222
225 pub fn new_es_10bit( 223 pub fn new_es_10bit(
226 peri: impl Unborrow<Target = T> + 'd, 224 peri: impl Peripheral<P = T> + 'd,
227 dma: impl Unborrow<Target = Dma> + 'd, 225 dma: impl Peripheral<P = Dma> + 'd,
228 irq: impl Unborrow<Target = T::Interrupt> + 'd, 226 irq: impl Peripheral<P = T::Interrupt> + 'd,
229 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd, 227 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
230 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd, 228 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
231 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd, 229 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
232 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd, 230 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
233 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd, 231 d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
234 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd, 232 d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
235 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd, 233 d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
236 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd, 234 d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
237 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd, 235 d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
238 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd, 236 d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
239 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd, 237 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
240 config: Config, 238 config: Config,
241 ) -> Self { 239 ) -> Self {
242 unborrow!(peri, dma, irq); 240 into_ref!(peri, dma, irq);
243 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9); 241 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9);
244 config_pins!(pixclk); 242 config_pins!(pixclk);
245 243
@@ -247,25 +245,25 @@ where
247 } 245 }
248 246
249 pub fn new_es_12bit( 247 pub fn new_es_12bit(
250 peri: impl Unborrow<Target = T> + 'd, 248 peri: impl Peripheral<P = T> + 'd,
251 dma: impl Unborrow<Target = Dma> + 'd, 249 dma: impl Peripheral<P = Dma> + 'd,
252 irq: impl Unborrow<Target = T::Interrupt> + 'd, 250 irq: impl Peripheral<P = T::Interrupt> + 'd,
253 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd, 251 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
254 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd, 252 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
255 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd, 253 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
256 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd, 254 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
257 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd, 255 d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
258 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd, 256 d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
259 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd, 257 d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
260 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd, 258 d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
261 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd, 259 d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
262 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd, 260 d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
263 d10: impl Unborrow<Target = impl D10Pin<T>> + 'd, 261 d10: impl Peripheral<P = impl D10Pin<T>> + 'd,
264 d11: impl Unborrow<Target = impl D11Pin<T>> + 'd, 262 d11: impl Peripheral<P = impl D11Pin<T>> + 'd,
265 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd, 263 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
266 config: Config, 264 config: Config,
267 ) -> Self { 265 ) -> Self {
268 unborrow!(peri, dma, irq); 266 into_ref!(peri, dma, irq);
269 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11); 267 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11);
270 config_pins!(pixclk); 268 config_pins!(pixclk);
271 269
@@ -273,27 +271,27 @@ where
273 } 271 }
274 272
275 pub fn new_es_14bit( 273 pub fn new_es_14bit(
276 peri: impl Unborrow<Target = T> + 'd, 274 peri: impl Peripheral<P = T> + 'd,
277 dma: impl Unborrow<Target = Dma> + 'd, 275 dma: impl Peripheral<P = Dma> + 'd,
278 irq: impl Unborrow<Target = T::Interrupt> + 'd, 276 irq: impl Peripheral<P = T::Interrupt> + 'd,
279 d0: impl Unborrow<Target = impl D0Pin<T>> + 'd, 277 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
280 d1: impl Unborrow<Target = impl D1Pin<T>> + 'd, 278 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
281 d2: impl Unborrow<Target = impl D2Pin<T>> + 'd, 279 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
282 d3: impl Unborrow<Target = impl D3Pin<T>> + 'd, 280 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
283 d4: impl Unborrow<Target = impl D4Pin<T>> + 'd, 281 d4: impl Peripheral<P = impl D4Pin<T>> + 'd,
284 d5: impl Unborrow<Target = impl D5Pin<T>> + 'd, 282 d5: impl Peripheral<P = impl D5Pin<T>> + 'd,
285 d6: impl Unborrow<Target = impl D6Pin<T>> + 'd, 283 d6: impl Peripheral<P = impl D6Pin<T>> + 'd,
286 d7: impl Unborrow<Target = impl D7Pin<T>> + 'd, 284 d7: impl Peripheral<P = impl D7Pin<T>> + 'd,
287 d8: impl Unborrow<Target = impl D8Pin<T>> + 'd, 285 d8: impl Peripheral<P = impl D8Pin<T>> + 'd,
288 d9: impl Unborrow<Target = impl D9Pin<T>> + 'd, 286 d9: impl Peripheral<P = impl D9Pin<T>> + 'd,
289 d10: impl Unborrow<Target = impl D10Pin<T>> + 'd, 287 d10: impl Peripheral<P = impl D10Pin<T>> + 'd,
290 d11: impl Unborrow<Target = impl D11Pin<T>> + 'd, 288 d11: impl Peripheral<P = impl D11Pin<T>> + 'd,
291 d12: impl Unborrow<Target = impl D12Pin<T>> + 'd, 289 d12: impl Peripheral<P = impl D12Pin<T>> + 'd,
292 d13: impl Unborrow<Target = impl D13Pin<T>> + 'd, 290 d13: impl Peripheral<P = impl D13Pin<T>> + 'd,
293 pixclk: impl Unborrow<Target = impl PixClkPin<T>> + 'd, 291 pixclk: impl Peripheral<P = impl PixClkPin<T>> + 'd,
294 config: Config, 292 config: Config,
295 ) -> Self { 293 ) -> Self {
296 unborrow!(peri, dma, irq); 294 into_ref!(peri, dma, irq);
297 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13); 295 config_pins!(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
298 config_pins!(pixclk); 296 config_pins!(pixclk);
299 297
@@ -301,9 +299,9 @@ where
301 } 299 }
302 300
303 fn new_inner( 301 fn new_inner(
304 peri: T, 302 peri: PeripheralRef<'d, T>,
305 dma: Dma, 303 dma: PeripheralRef<'d, Dma>,
306 irq: T::Interrupt, 304 irq: PeripheralRef<'d, T::Interrupt>,
307 config: Config, 305 config: Config,
308 use_embedded_synchronization: bool, 306 use_embedded_synchronization: bool,
309 edm: u8, 307 edm: u8,
@@ -327,11 +325,7 @@ where
327 irq.unpend(); 325 irq.unpend();
328 irq.enable(); 326 irq.enable();
329 327
330 Self { 328 Self { inner: peri, dma }
331 inner: peri,
332 dma,
333 phantom: PhantomData,
334 }
335 } 329 }
336 330
337 unsafe fn on_interrupt(_: *mut ()) { 331 unsafe fn on_interrupt(_: *mut ()) {
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 87ac38ba8..cc030a93e 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -8,16 +8,15 @@ mod dmamux;
8mod gpdma; 8mod gpdma;
9 9
10use core::future::Future; 10use core::future::Future;
11use core::marker::PhantomData;
12use core::mem; 11use core::mem;
13use core::pin::Pin; 12use core::pin::Pin;
14use core::task::{Context, Poll, Waker}; 13use core::task::{Context, Poll, Waker};
15 14
16#[cfg(dmamux)] 15use embassy_hal_common::{impl_peripheral, into_ref};
17pub use dmamux::*;
18use embassy_hal_common::unborrow;
19 16
20use crate::Unborrow; 17#[cfg(dmamux)]
18pub use self::dmamux::*;
19use crate::Peripheral;
21 20
22#[cfg(feature = "unstable-pac")] 21#[cfg(feature = "unstable-pac")]
23pub mod low_level { 22pub mod low_level {
@@ -207,17 +206,19 @@ impl Default for TransferOptions {
207} 206}
208 207
209mod transfers { 208mod transfers {
209 use embassy_hal_common::PeripheralRef;
210
210 use super::*; 211 use super::*;
211 212
212 #[allow(unused)] 213 #[allow(unused)]
213 pub fn read<'a, W: Word>( 214 pub fn read<'a, W: Word>(
214 channel: impl Unborrow<Target = impl Channel> + 'a, 215 channel: impl Peripheral<P = impl Channel> + 'a,
215 request: Request, 216 request: Request,
216 reg_addr: *mut W, 217 reg_addr: *mut W,
217 buf: &'a mut [W], 218 buf: &'a mut [W],
218 ) -> impl Future<Output = ()> + 'a { 219 ) -> impl Future<Output = ()> + 'a {
219 assert!(buf.len() > 0 && buf.len() <= 0xFFFF); 220 assert!(buf.len() > 0 && buf.len() <= 0xFFFF);
220 unborrow!(channel); 221 into_ref!(channel);
221 222
222 unsafe { channel.start_read::<W>(request, reg_addr, buf, Default::default()) }; 223 unsafe { channel.start_read::<W>(request, reg_addr, buf, Default::default()) };
223 224
@@ -226,13 +227,13 @@ mod transfers {
226 227
227 #[allow(unused)] 228 #[allow(unused)]
228 pub fn write<'a, W: Word>( 229 pub fn write<'a, W: Word>(
229 channel: impl Unborrow<Target = impl Channel> + 'a, 230 channel: impl Peripheral<P = impl Channel> + 'a,
230 request: Request, 231 request: Request,
231 buf: &'a [W], 232 buf: &'a [W],
232 reg_addr: *mut W, 233 reg_addr: *mut W,
233 ) -> impl Future<Output = ()> + 'a { 234 ) -> impl Future<Output = ()> + 'a {
234 assert!(buf.len() > 0 && buf.len() <= 0xFFFF); 235 assert!(buf.len() > 0 && buf.len() <= 0xFFFF);
235 unborrow!(channel); 236 into_ref!(channel);
236 237
237 unsafe { channel.start_write::<W>(request, buf, reg_addr, Default::default()) }; 238 unsafe { channel.start_write::<W>(request, buf, reg_addr, Default::default()) };
238 239
@@ -241,13 +242,13 @@ mod transfers {
241 242
242 #[allow(unused)] 243 #[allow(unused)]
243 pub fn write_repeated<'a, W: Word>( 244 pub fn write_repeated<'a, W: Word>(
244 channel: impl Unborrow<Target = impl Channel> + 'a, 245 channel: impl Peripheral<P = impl Channel> + 'a,
245 request: Request, 246 request: Request,
246 repeated: W, 247 repeated: W,
247 count: usize, 248 count: usize,
248 reg_addr: *mut W, 249 reg_addr: *mut W,
249 ) -> impl Future<Output = ()> + 'a { 250 ) -> impl Future<Output = ()> + 'a {
250 unborrow!(channel); 251 into_ref!(channel);
251 252
252 unsafe { channel.start_write_repeated::<W>(request, repeated, count, reg_addr, Default::default()) }; 253 unsafe { channel.start_write_repeated::<W>(request, repeated, count, reg_addr, Default::default()) };
253 254
@@ -255,17 +256,13 @@ mod transfers {
255 } 256 }
256 257
257 pub(crate) struct Transfer<'a, C: Channel> { 258 pub(crate) struct Transfer<'a, C: Channel> {
258 channel: C, 259 channel: PeripheralRef<'a, C>,
259 _phantom: PhantomData<&'a mut C>,
260 } 260 }
261 261
262 impl<'a, C: Channel> Transfer<'a, C> { 262 impl<'a, C: Channel> Transfer<'a, C> {
263 pub(crate) fn new(channel: impl Unborrow<Target = C> + 'a) -> Self { 263 pub(crate) fn new(channel: impl Peripheral<P = C> + 'a) -> Self {
264 unborrow!(channel); 264 into_ref!(channel);
265 Self { 265 Self { channel }
266 channel,
267 _phantom: PhantomData,
268 }
269 } 266 }
270 } 267 }
271 268
@@ -290,17 +287,11 @@ mod transfers {
290 } 287 }
291} 288}
292 289
293pub trait Channel: sealed::Channel + Unborrow<Target = Self> + 'static {} 290pub trait Channel: sealed::Channel + Peripheral<P = Self> + 'static {}
294 291
295pub struct NoDma; 292pub struct NoDma;
296 293
297unsafe impl Unborrow for NoDma { 294impl_peripheral!(NoDma);
298 type Target = NoDma;
299
300 unsafe fn unborrow(self) -> Self::Target {
301 self
302 }
303}
304 295
305// safety: must be called only once at startup 296// safety: must be called only once at startup
306pub(crate) unsafe fn init() { 297pub(crate) unsafe fn init() {
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index 7985acc5a..5e31c32b5 100644
--- a/embassy-stm32/src/eth/v1/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -6,7 +6,7 @@ use core::task::Waker;
6 6
7use embassy::waitqueue::AtomicWaker; 7use embassy::waitqueue::AtomicWaker;
8use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 8use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
9use embassy_hal_common::unborrow; 9use embassy_hal_common::{into_ref, PeripheralRef};
10use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; 10use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
11 11
12use crate::gpio::sealed::{AFType, Pin as __GpioPin}; 12use crate::gpio::sealed::{AFType, Pin as __GpioPin};
@@ -16,7 +16,7 @@ use crate::pac::AFIO;
16#[cfg(any(eth_v1b, eth_v1c))] 16#[cfg(any(eth_v1b, eth_v1c))]
17use crate::pac::SYSCFG; 17use crate::pac::SYSCFG;
18use crate::pac::{ETH, RCC}; 18use crate::pac::{ETH, RCC};
19use crate::Unborrow; 19use crate::Peripheral;
20 20
21mod descriptors; 21mod descriptors;
22mod rx_desc; 22mod rx_desc;
@@ -36,7 +36,7 @@ impl<'d, T: Instance, const TX: usize, const RX: usize> State<'d, T, TX, RX> {
36 36
37pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> { 37pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
38 state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>, 38 state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
39 pins: [AnyPin; 9], 39 pins: [PeripheralRef<'d, AnyPin>; 9],
40 _phy: P, 40 _phy: P,
41 clock_range: Cr, 41 clock_range: Cr,
42 phy_addr: u8, 42 phy_addr: u8,
@@ -86,22 +86,22 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
86 /// safety: the returned instance is not leak-safe 86 /// safety: the returned instance is not leak-safe
87 pub unsafe fn new( 87 pub unsafe fn new(
88 state: &'d mut State<'d, T, TX, RX>, 88 state: &'d mut State<'d, T, TX, RX>,
89 peri: impl Unborrow<Target = T> + 'd, 89 peri: impl Peripheral<P = T> + 'd,
90 interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd, 90 interrupt: impl Peripheral<P = crate::interrupt::ETH> + 'd,
91 ref_clk: impl Unborrow<Target = impl RefClkPin<T>> + 'd, 91 ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd,
92 mdio: impl Unborrow<Target = impl MDIOPin<T>> + 'd, 92 mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
93 mdc: impl Unborrow<Target = impl MDCPin<T>> + 'd, 93 mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
94 crs: impl Unborrow<Target = impl CRSPin<T>> + 'd, 94 crs: impl Peripheral<P = impl CRSPin<T>> + 'd,
95 rx_d0: impl Unborrow<Target = impl RXD0Pin<T>> + 'd, 95 rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd,
96 rx_d1: impl Unborrow<Target = impl RXD1Pin<T>> + 'd, 96 rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd,
97 tx_d0: impl Unborrow<Target = impl TXD0Pin<T>> + 'd, 97 tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd,
98 tx_d1: impl Unborrow<Target = impl TXD1Pin<T>> + 'd, 98 tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd,
99 tx_en: impl Unborrow<Target = impl TXEnPin<T>> + 'd, 99 tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd,
100 phy: P, 100 phy: P,
101 mac_addr: [u8; 6], 101 mac_addr: [u8; 6],
102 phy_addr: u8, 102 phy_addr: u8,
103 ) -> Self { 103 ) -> Self {
104 unborrow!(interrupt, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); 104 into_ref!(interrupt, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
105 105
106 // Enable the necessary Clocks 106 // Enable the necessary Clocks
107 // NOTE(unsafe) We have exclusive access to the registers 107 // NOTE(unsafe) We have exclusive access to the registers
@@ -207,15 +207,15 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
207 }; 207 };
208 208
209 let pins = [ 209 let pins = [
210 ref_clk.degrade(), 210 ref_clk.map_into(),
211 mdio.degrade(), 211 mdio.map_into(),
212 mdc.degrade(), 212 mdc.map_into(),
213 crs.degrade(), 213 crs.map_into(),
214 rx_d0.degrade(), 214 rx_d0.map_into(),
215 rx_d1.degrade(), 215 rx_d1.map_into(),
216 tx_d0.degrade(), 216 tx_d0.map_into(),
217 tx_d1.degrade(), 217 tx_d1.map_into(),
218 tx_en.degrade(), 218 tx_en.map_into(),
219 ]; 219 ];
220 220
221 let mut this = Self { 221 let mut this = Self {
@@ -370,7 +370,7 @@ struct Inner<'d, T: Instance, const TX: usize, const RX: usize> {
370} 370}
371 371
372impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> { 372impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> {
373 pub fn new(_peri: impl Unborrow<Target = T> + 'd) -> Self { 373 pub fn new(_peri: impl Peripheral<P = T> + 'd) -> Self {
374 Self { 374 Self {
375 _peri: PhantomData, 375 _peri: PhantomData,
376 desc_ring: DescriptorRing::new(), 376 desc_ring: DescriptorRing::new(),
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 2b1caf992..2b4a9367b 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -4,13 +4,13 @@ use core::task::Waker;
4 4
5use embassy::waitqueue::AtomicWaker; 5use embassy::waitqueue::AtomicWaker;
6use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 6use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
7use embassy_hal_common::unborrow; 7use embassy_hal_common::{into_ref, PeripheralRef};
8use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; 8use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
9 9
10use crate::gpio::sealed::{AFType, Pin as _}; 10use crate::gpio::sealed::{AFType, Pin as _};
11use crate::gpio::{AnyPin, Speed}; 11use crate::gpio::{AnyPin, Speed};
12use crate::pac::{ETH, RCC, SYSCFG}; 12use crate::pac::{ETH, RCC, SYSCFG};
13use crate::Unborrow; 13use crate::Peripheral;
14 14
15mod descriptors; 15mod descriptors;
16use descriptors::DescriptorRing; 16use descriptors::DescriptorRing;
@@ -25,7 +25,7 @@ impl<'d, T: Instance, const TX: usize, const RX: usize> State<'d, T, TX, RX> {
25} 25}
26pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> { 26pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
27 state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>, 27 state: PeripheralMutex<'d, Inner<'d, T, TX, RX>>,
28 pins: [AnyPin; 9], 28 pins: [PeripheralRef<'d, AnyPin>; 9],
29 _phy: P, 29 _phy: P,
30 clock_range: u8, 30 clock_range: u8,
31 phy_addr: u8, 31 phy_addr: u8,
@@ -48,22 +48,22 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
48 /// safety: the returned instance is not leak-safe 48 /// safety: the returned instance is not leak-safe
49 pub unsafe fn new( 49 pub unsafe fn new(
50 state: &'d mut State<'d, T, TX, RX>, 50 state: &'d mut State<'d, T, TX, RX>,
51 peri: impl Unborrow<Target = T> + 'd, 51 peri: impl Peripheral<P = T> + 'd,
52 interrupt: impl Unborrow<Target = crate::interrupt::ETH> + 'd, 52 interrupt: impl Peripheral<P = crate::interrupt::ETH> + 'd,
53 ref_clk: impl Unborrow<Target = impl RefClkPin<T>> + 'd, 53 ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd,
54 mdio: impl Unborrow<Target = impl MDIOPin<T>> + 'd, 54 mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
55 mdc: impl Unborrow<Target = impl MDCPin<T>> + 'd, 55 mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
56 crs: impl Unborrow<Target = impl CRSPin<T>> + 'd, 56 crs: impl Peripheral<P = impl CRSPin<T>> + 'd,
57 rx_d0: impl Unborrow<Target = impl RXD0Pin<T>> + 'd, 57 rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd,
58 rx_d1: impl Unborrow<Target = impl RXD1Pin<T>> + 'd, 58 rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd,
59 tx_d0: impl Unborrow<Target = impl TXD0Pin<T>> + 'd, 59 tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd,
60 tx_d1: impl Unborrow<Target = impl TXD1Pin<T>> + 'd, 60 tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd,
61 tx_en: impl Unborrow<Target = impl TXEnPin<T>> + 'd, 61 tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd,
62 phy: P, 62 phy: P,
63 mac_addr: [u8; 6], 63 mac_addr: [u8; 6],
64 phy_addr: u8, 64 phy_addr: u8,
65 ) -> Self { 65 ) -> Self {
66 unborrow!(interrupt, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); 66 into_ref!(interrupt, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
67 67
68 // Enable the necessary Clocks 68 // Enable the necessary Clocks
69 // NOTE(unsafe) We have exclusive access to the registers 69 // NOTE(unsafe) We have exclusive access to the registers
@@ -143,15 +143,15 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
143 }; 143 };
144 144
145 let pins = [ 145 let pins = [
146 ref_clk.degrade(), 146 ref_clk.map_into(),
147 mdio.degrade(), 147 mdio.map_into(),
148 mdc.degrade(), 148 mdc.map_into(),
149 crs.degrade(), 149 crs.map_into(),
150 rx_d0.degrade(), 150 rx_d0.map_into(),
151 rx_d1.degrade(), 151 rx_d1.map_into(),
152 tx_d0.degrade(), 152 tx_d0.map_into(),
153 tx_d1.degrade(), 153 tx_d1.map_into(),
154 tx_en.degrade(), 154 tx_en.map_into(),
155 ]; 155 ];
156 156
157 let mut this = Self { 157 let mut this = Self {
@@ -316,7 +316,7 @@ struct Inner<'d, T: Instance, const TX: usize, const RX: usize> {
316} 316}
317 317
318impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> { 318impl<'d, T: Instance, const TX: usize, const RX: usize> Inner<'d, T, TX, RX> {
319 pub fn new(_peri: impl Unborrow<Target = T> + 'd) -> Self { 319 pub fn new(_peri: impl Peripheral<P = T> + 'd) -> Self {
320 Self { 320 Self {
321 _peri: PhantomData, 321 _peri: PhantomData,
322 desc_ring: DescriptorRing::new(), 322 desc_ring: DescriptorRing::new(),
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs
index 94e0e941d..3b8d9390f 100644
--- a/embassy-stm32/src/exti.rs
+++ b/embassy-stm32/src/exti.rs
@@ -4,12 +4,12 @@ use core::pin::Pin;
4use core::task::{Context, Poll}; 4use core::task::{Context, Poll};
5 5
6use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
7use embassy_hal_common::unsafe_impl_unborrow; 7use embassy_hal_common::impl_peripheral;
8 8
9use crate::gpio::{AnyPin, Input, Pin as GpioPin}; 9use crate::gpio::{AnyPin, Input, Pin as GpioPin};
10use crate::pac::exti::regs::Lines; 10use crate::pac::exti::regs::Lines;
11use crate::pac::EXTI; 11use crate::pac::EXTI;
12use crate::{interrupt, pac, peripherals, Unborrow}; 12use crate::{interrupt, pac, peripherals, Peripheral};
13 13
14const EXTI_COUNT: usize = 16; 14const EXTI_COUNT: usize = 16;
15const NEW_AW: AtomicWaker = AtomicWaker::new(); 15const NEW_AW: AtomicWaker = AtomicWaker::new();
@@ -86,7 +86,7 @@ pub struct ExtiInput<'d, T: GpioPin> {
86impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {} 86impl<'d, T: GpioPin> Unpin for ExtiInput<'d, T> {}
87 87
88impl<'d, T: GpioPin> ExtiInput<'d, T> { 88impl<'d, T: GpioPin> ExtiInput<'d, T> {
89 pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self { 89 pub fn new(pin: Input<'d, T>, _ch: impl Peripheral<P = T::ExtiChannel> + 'd) -> Self {
90 Self { pin } 90 Self { pin }
91 } 91 }
92 92
@@ -320,7 +320,7 @@ pub trait Channel: sealed::Channel + Sized {
320pub struct AnyChannel { 320pub struct AnyChannel {
321 number: u8, 321 number: u8,
322} 322}
323unsafe_impl_unborrow!(AnyChannel); 323impl_peripheral!(AnyChannel);
324impl sealed::Channel for AnyChannel {} 324impl sealed::Channel for AnyChannel {}
325impl Channel for AnyChannel { 325impl Channel for AnyChannel {
326 fn number(&self) -> usize { 326 fn number(&self) -> usize {
diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs
index 2047f70e1..5258c9b04 100644
--- a/embassy-stm32/src/flash/mod.rs
+++ b/embassy-stm32/src/flash/mod.rs
@@ -1,11 +1,9 @@
1use core::marker::PhantomData; 1use embassy_hal_common::{into_ref, PeripheralRef};
2
3use embassy_hal_common::unborrow;
4use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; 2use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
5 3
6pub use crate::pac::{ERASE_SIZE, ERASE_VALUE, FLASH_BASE, FLASH_SIZE, WRITE_SIZE}; 4pub use crate::pac::{ERASE_SIZE, ERASE_VALUE, FLASH_BASE, FLASH_SIZE, WRITE_SIZE};
7use crate::peripherals::FLASH; 5use crate::peripherals::FLASH;
8use crate::Unborrow; 6use crate::Peripheral;
9const FLASH_END: usize = FLASH_BASE + FLASH_SIZE; 7const FLASH_END: usize = FLASH_BASE + FLASH_SIZE;
10 8
11#[cfg_attr(any(flash_wl, flash_wb, flash_l0, flash_l1, flash_l4), path = "l.rs")] 9#[cfg_attr(any(flash_wl, flash_wb, flash_l0, flash_l1, flash_l4), path = "l.rs")]
@@ -16,20 +14,16 @@ const FLASH_END: usize = FLASH_BASE + FLASH_SIZE;
16mod family; 14mod family;
17 15
18pub struct Flash<'d> { 16pub struct Flash<'d> {
19 _inner: FLASH, 17 _inner: PeripheralRef<'d, FLASH>,
20 _phantom: PhantomData<&'d mut FLASH>,
21} 18}
22 19
23impl<'d> Flash<'d> { 20impl<'d> Flash<'d> {
24 pub fn new(p: impl Unborrow<Target = FLASH>) -> Self { 21 pub fn new(p: impl Peripheral<P = FLASH> + 'd) -> Self {
25 unborrow!(p); 22 into_ref!(p);
26 Self { 23 Self { _inner: p }
27 _inner: p,
28 _phantom: PhantomData,
29 }
30 } 24 }
31 25
32 pub fn unlock(p: impl Unborrow<Target = FLASH>) -> Self { 26 pub fn unlock(p: impl Peripheral<P = FLASH> + 'd) -> Self {
33 let flash = Self::new(p); 27 let flash = Self::new(p);
34 28
35 unsafe { family::unlock() }; 29 unsafe { family::unlock() };
diff --git a/embassy-stm32/src/fmc/mod.rs b/embassy-stm32/src/fmc/mod.rs
index 4f8e467d0..856a4adca 100644
--- a/embassy-stm32/src/fmc/mod.rs
+++ b/embassy-stm32/src/fmc/mod.rs
@@ -1,10 +1,10 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::unborrow; 3use embassy_hal_common::into_ref;
4 4
5use crate::gpio::sealed::AFType; 5use crate::gpio::sealed::AFType;
6use crate::gpio::{Pull, Speed}; 6use crate::gpio::{Pull, Speed};
7use crate::Unborrow; 7use crate::Peripheral;
8 8
9mod pins; 9mod pins;
10pub use pins::*; 10pub use pins::*;
@@ -39,7 +39,7 @@ where
39 39
40macro_rules! config_pins { 40macro_rules! config_pins {
41 ($($pin:ident),*) => { 41 ($($pin:ident),*) => {
42 unborrow!($($pin),*); 42 into_ref!($($pin),*);
43 $( 43 $(
44 $pin.set_as_af_pull($pin.af_num(), AFType::OutputPushPull, Pull::Up); 44 $pin.set_as_af_pull($pin.af_num(), AFType::OutputPushPull, Pull::Up);
45 $pin.set_speed(Speed::VeryHigh); 45 $pin.set_speed(Speed::VeryHigh);
@@ -57,12 +57,12 @@ macro_rules! fmc_sdram_constructor {
57 ctrl: [$(($ctrl_pin_name:ident: $ctrl_signal:ident)),*] 57 ctrl: [$(($ctrl_pin_name:ident: $ctrl_signal:ident)),*]
58 )) => { 58 )) => {
59 pub fn $name<CHIP: stm32_fmc::SdramChip>( 59 pub fn $name<CHIP: stm32_fmc::SdramChip>(
60 _instance: impl Unborrow<Target = T> + 'd, 60 _instance: impl Peripheral<P = T> + 'd,
61 $($addr_pin_name: impl Unborrow<Target = impl $addr_signal<T>> + 'd),*, 61 $($addr_pin_name: impl Peripheral<P = impl $addr_signal<T>> + 'd),*,
62 $($ba_pin_name: impl Unborrow<Target = impl $ba_signal<T>> + 'd),*, 62 $($ba_pin_name: impl Peripheral<P = impl $ba_signal<T>> + 'd),*,
63 $($d_pin_name: impl Unborrow<Target = impl $d_signal<T>> + 'd),*, 63 $($d_pin_name: impl Peripheral<P = impl $d_signal<T>> + 'd),*,
64 $($nbl_pin_name: impl Unborrow<Target = impl $nbl_signal<T>> + 'd),*, 64 $($nbl_pin_name: impl Peripheral<P = impl $nbl_signal<T>> + 'd),*,
65 $($ctrl_pin_name: impl Unborrow<Target = impl $ctrl_signal<T>> + 'd),*, 65 $($ctrl_pin_name: impl Peripheral<P = impl $ctrl_signal<T>> + 'd),*,
66 chip: CHIP 66 chip: CHIP
67 ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> { 67 ) -> stm32_fmc::Sdram<Fmc<'d, T>, CHIP> {
68 68
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 1059ebf86..3c4cdb887 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -1,11 +1,10 @@
1#![macro_use] 1#![macro_use]
2use core::convert::Infallible; 2use core::convert::Infallible;
3use core::marker::PhantomData;
4 3
5use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; 4use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
6 5
7use crate::pac::gpio::{self, vals}; 6use crate::pac::gpio::{self, vals};
8use crate::{pac, peripherals, Unborrow}; 7use crate::{pac, peripherals, Peripheral};
9 8
10/// GPIO flexible pin. 9/// GPIO flexible pin.
11/// 10///
@@ -13,8 +12,7 @@ use crate::{pac, peripherals, Unborrow};
13/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output 12/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
14/// mode. 13/// mode.
15pub struct Flex<'d, T: Pin> { 14pub struct Flex<'d, T: Pin> {
16 pub(crate) pin: T, 15 pub(crate) pin: PeripheralRef<'d, T>,
17 phantom: PhantomData<&'d mut T>,
18} 16}
19 17
20impl<'d, T: Pin> Flex<'d, T> { 18impl<'d, T: Pin> Flex<'d, T> {
@@ -24,13 +22,10 @@ impl<'d, T: Pin> Flex<'d, T> {
24 /// before the pin is put into output mode. 22 /// before the pin is put into output mode.
25 /// 23 ///
26 #[inline] 24 #[inline]
27 pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self { 25 pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
28 unborrow!(pin); 26 into_ref!(pin);
29 // Pin will be in disconnected state. 27 // Pin will be in disconnected state.
30 Self { 28 Self { pin }
31 pin,
32 phantom: PhantomData,
33 }
34 } 29 }
35 30
36 /// Put the pin into input mode. 31 /// Put the pin into input mode.
@@ -285,7 +280,7 @@ pub struct Input<'d, T: Pin> {
285 280
286impl<'d, T: Pin> Input<'d, T> { 281impl<'d, T: Pin> Input<'d, T> {
287 #[inline] 282 #[inline]
288 pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { 283 pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
289 let mut pin = Flex::new(pin); 284 let mut pin = Flex::new(pin);
290 pin.set_as_input(pull); 285 pin.set_as_input(pull);
291 Self { pin } 286 Self { pin }
@@ -340,7 +335,7 @@ pub struct Output<'d, T: Pin> {
340 335
341impl<'d, T: Pin> Output<'d, T> { 336impl<'d, T: Pin> Output<'d, T> {
342 #[inline] 337 #[inline]
343 pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, speed: Speed) -> Self { 338 pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, speed: Speed) -> Self {
344 let mut pin = Flex::new(pin); 339 let mut pin = Flex::new(pin);
345 match initial_output { 340 match initial_output {
346 Level::High => pin.set_high(), 341 Level::High => pin.set_high(),
@@ -400,7 +395,7 @@ pub struct OutputOpenDrain<'d, T: Pin> {
400 395
401impl<'d, T: Pin> OutputOpenDrain<'d, T> { 396impl<'d, T: Pin> OutputOpenDrain<'d, T> {
402 #[inline] 397 #[inline]
403 pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self { 398 pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, speed: Speed, pull: Pull) -> Self {
404 let mut pin = Flex::new(pin); 399 let mut pin = Flex::new(pin);
405 400
406 match initial_output { 401 match initial_output {
@@ -626,7 +621,7 @@ pub(crate) mod sealed {
626 } 621 }
627} 622}
628 623
629pub trait Pin: sealed::Pin + Sized + 'static { 624pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
630 #[cfg(feature = "exti")] 625 #[cfg(feature = "exti")]
631 type ExtiChannel: crate::exti::Channel; 626 type ExtiChannel: crate::exti::Channel;
632 627
@@ -673,7 +668,7 @@ impl AnyPin {
673 } 668 }
674} 669}
675 670
676unsafe_impl_unborrow!(AnyPin); 671impl_peripheral!(AnyPin);
677impl Pin for AnyPin { 672impl Pin for AnyPin {
678 #[cfg(feature = "exti")] 673 #[cfg(feature = "exti")]
679 type ExtiChannel = crate::exti::AnyChannel; 674 type ExtiChannel = crate::exti::AnyChannel;
@@ -699,6 +694,12 @@ foreach_pin!(
699 $port_num * 16 + $pin_num 694 $port_num * 16 + $pin_num
700 } 695 }
701 } 696 }
697
698 impl From<peripherals::$pin_name> for AnyPin {
699 fn from(x: peripherals::$pin_name) -> Self {
700 x.degrade()
701 }
702 }
702 }; 703 };
703); 704);
704 705
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 65c918780..613815a9c 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -1,13 +1,13 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_embedded_hal::SetConfig; 3use embassy_embedded_hal::SetConfig;
4use embassy_hal_common::unborrow; 4use embassy_hal_common::into_ref;
5 5
6use crate::gpio::sealed::AFType; 6use crate::gpio::sealed::AFType;
7use crate::i2c::{Error, Instance, SclPin, SdaPin}; 7use crate::i2c::{Error, Instance, SclPin, SdaPin};
8use crate::pac::i2c; 8use crate::pac::i2c;
9use crate::time::Hertz; 9use crate::time::Hertz;
10use crate::Unborrow; 10use crate::Peripheral;
11 11
12pub struct State {} 12pub struct State {}
13 13
@@ -23,12 +23,12 @@ pub struct I2c<'d, T: Instance> {
23 23
24impl<'d, T: Instance> I2c<'d, T> { 24impl<'d, T: Instance> I2c<'d, T> {
25 pub fn new( 25 pub fn new(
26 _peri: impl Unborrow<Target = T> + 'd, 26 _peri: impl Peripheral<P = T> + 'd,
27 scl: impl Unborrow<Target = impl SclPin<T>> + 'd, 27 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
28 sda: impl Unborrow<Target = impl SdaPin<T>> + 'd, 28 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
29 freq: Hertz, 29 freq: Hertz,
30 ) -> Self { 30 ) -> Self {
31 unborrow!(scl, sda); 31 into_ref!(scl, sda);
32 32
33 T::enable(); 33 T::enable();
34 T::reset(); 34 T::reset();
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 108ea7e34..dec92cc88 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -1,12 +1,11 @@
1use core::cmp; 1use core::cmp;
2use core::marker::PhantomData;
3use core::task::Poll; 2use core::task::Poll;
4 3
5use atomic_polyfill::{AtomicUsize, Ordering}; 4use atomic_polyfill::{AtomicUsize, Ordering};
6use embassy::waitqueue::AtomicWaker; 5use embassy::waitqueue::AtomicWaker;
7use embassy_embedded_hal::SetConfig; 6use embassy_embedded_hal::SetConfig;
8use embassy_hal_common::drop::OnDrop; 7use embassy_hal_common::drop::OnDrop;
9use embassy_hal_common::unborrow; 8use embassy_hal_common::{into_ref, PeripheralRef};
10use futures::future::poll_fn; 9use futures::future::poll_fn;
11 10
12use crate::dma::NoDma; 11use crate::dma::NoDma;
@@ -15,7 +14,7 @@ use crate::i2c::{Error, Instance, SclPin, SdaPin};
15use crate::interrupt::InterruptExt; 14use crate::interrupt::InterruptExt;
16use crate::pac::i2c; 15use crate::pac::i2c;
17use crate::time::Hertz; 16use crate::time::Hertz;
18use crate::Unborrow; 17use crate::Peripheral;
19 18
20pub struct State { 19pub struct State {
21 waker: AtomicWaker, 20 waker: AtomicWaker,
@@ -32,23 +31,23 @@ impl State {
32} 31}
33 32
34pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> { 33pub struct I2c<'d, T: Instance, TXDMA = NoDma, RXDMA = NoDma> {
35 phantom: PhantomData<&'d mut T>, 34 _peri: PeripheralRef<'d, T>,
36 tx_dma: TXDMA, 35 tx_dma: PeripheralRef<'d, TXDMA>,
37 #[allow(dead_code)] 36 #[allow(dead_code)]
38 rx_dma: RXDMA, 37 rx_dma: PeripheralRef<'d, RXDMA>,
39} 38}
40 39
41impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { 40impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
42 pub fn new( 41 pub fn new(
43 _peri: impl Unborrow<Target = T> + 'd, 42 peri: impl Peripheral<P = T> + 'd,
44 scl: impl Unborrow<Target = impl SclPin<T>> + 'd, 43 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
45 sda: impl Unborrow<Target = impl SdaPin<T>> + 'd, 44 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
46 irq: impl Unborrow<Target = T::Interrupt> + 'd, 45 irq: impl Peripheral<P = T::Interrupt> + 'd,
47 tx_dma: impl Unborrow<Target = TXDMA> + 'd, 46 tx_dma: impl Peripheral<P = TXDMA> + 'd,
48 rx_dma: impl Unborrow<Target = RXDMA> + 'd, 47 rx_dma: impl Peripheral<P = RXDMA> + 'd,
49 freq: Hertz, 48 freq: Hertz,
50 ) -> Self { 49 ) -> Self {
51 unborrow!(irq, scl, sda, tx_dma, rx_dma); 50 into_ref!(peri, irq, scl, sda, tx_dma, rx_dma);
52 51
53 T::enable(); 52 T::enable();
54 T::reset(); 53 T::reset();
@@ -88,7 +87,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
88 irq.enable(); 87 irq.enable();
89 88
90 Self { 89 Self {
91 phantom: PhantomData, 90 _peri: peri,
92 tx_dma, 91 tx_dma,
93 rx_dma, 92 rx_dma,
94 } 93 }
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 8b8168589..78025f3db 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -75,7 +75,7 @@ pub(crate) mod _generated {
75// Reexports 75// Reexports
76pub use _generated::{peripherals, Peripherals}; 76pub use _generated::{peripherals, Peripherals};
77pub use embassy_cortex_m::executor; 77pub use embassy_cortex_m::executor;
78pub use embassy_hal_common::{unborrow, Unborrow}; 78pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
79pub use embassy_macros::cortex_m_interrupt as interrupt; 79pub use embassy_macros::cortex_m_interrupt as interrupt;
80#[cfg(feature = "unstable-pac")] 80#[cfg(feature = "unstable-pac")]
81pub use stm32_metapac as pac; 81pub use stm32_metapac as pac;
diff --git a/embassy-stm32/src/pwm/simple_pwm.rs b/embassy-stm32/src/pwm/simple_pwm.rs
index 60aa110c7..7b2cdbc01 100644
--- a/embassy-stm32/src/pwm/simple_pwm.rs
+++ b/embassy-stm32/src/pwm/simple_pwm.rs
@@ -1,21 +1,18 @@
1use core::marker::PhantomData; 1use embassy_hal_common::{into_ref, PeripheralRef};
2
3use embassy_hal_common::unborrow;
4 2
5use super::*; 3use super::*;
6#[allow(unused_imports)] 4#[allow(unused_imports)]
7use crate::gpio::sealed::{AFType, Pin}; 5use crate::gpio::sealed::{AFType, Pin};
8use crate::time::Hertz; 6use crate::time::Hertz;
9use crate::Unborrow; 7use crate::Peripheral;
10 8
11pub struct SimplePwm<'d, T> { 9pub struct SimplePwm<'d, T> {
12 phantom: PhantomData<&'d mut T>, 10 inner: PeripheralRef<'d, T>,
13 inner: T,
14} 11}
15 12
16macro_rules! config_pins { 13macro_rules! config_pins {
17 ($($pin:ident),*) => { 14 ($($pin:ident),*) => {
18 unborrow!($($pin),*); 15 into_ref!($($pin),*);
19 // NOTE(unsafe) Exclusive access to the registers 16 // NOTE(unsafe) Exclusive access to the registers
20 critical_section::with(|_| unsafe { 17 critical_section::with(|_| unsafe {
21 $( 18 $(
@@ -30,8 +27,8 @@ macro_rules! config_pins {
30 27
31impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { 28impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
32 pub fn new_1ch( 29 pub fn new_1ch(
33 tim: impl Unborrow<Target = T> + 'd, 30 tim: impl Peripheral<P = T> + 'd,
34 ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, 31 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
35 freq: Hertz, 32 freq: Hertz,
36 ) -> Self { 33 ) -> Self {
37 Self::new_inner(tim, freq, move || { 34 Self::new_inner(tim, freq, move || {
@@ -40,9 +37,9 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
40 } 37 }
41 38
42 pub fn new_2ch( 39 pub fn new_2ch(
43 tim: impl Unborrow<Target = T> + 'd, 40 tim: impl Peripheral<P = T> + 'd,
44 ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, 41 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
45 ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd, 42 ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
46 freq: Hertz, 43 freq: Hertz,
47 ) -> Self { 44 ) -> Self {
48 Self::new_inner(tim, freq, move || { 45 Self::new_inner(tim, freq, move || {
@@ -51,10 +48,10 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
51 } 48 }
52 49
53 pub fn new_3ch( 50 pub fn new_3ch(
54 tim: impl Unborrow<Target = T> + 'd, 51 tim: impl Peripheral<P = T> + 'd,
55 ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, 52 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
56 ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd, 53 ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
57 ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd, 54 ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd,
58 freq: Hertz, 55 freq: Hertz,
59 ) -> Self { 56 ) -> Self {
60 Self::new_inner(tim, freq, move || { 57 Self::new_inner(tim, freq, move || {
@@ -63,11 +60,11 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
63 } 60 }
64 61
65 pub fn new_4ch( 62 pub fn new_4ch(
66 tim: impl Unborrow<Target = T> + 'd, 63 tim: impl Peripheral<P = T> + 'd,
67 ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, 64 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
68 ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd, 65 ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
69 ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd, 66 ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd,
70 ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd, 67 ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd,
71 freq: Hertz, 68 freq: Hertz,
72 ) -> Self { 69 ) -> Self {
73 Self::new_inner(tim, freq, move || { 70 Self::new_inner(tim, freq, move || {
@@ -75,18 +72,15 @@ impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
75 }) 72 })
76 } 73 }
77 74
78 fn new_inner(tim: impl Unborrow<Target = T> + 'd, freq: Hertz, configure_pins: impl FnOnce()) -> Self { 75 fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, configure_pins: impl FnOnce()) -> Self {
79 unborrow!(tim); 76 into_ref!(tim);
80 77
81 T::enable(); 78 T::enable();
82 <T as crate::rcc::sealed::RccPeripheral>::reset(); 79 <T as crate::rcc::sealed::RccPeripheral>::reset();
83 80
84 configure_pins(); 81 configure_pins();
85 82
86 let mut this = Self { 83 let mut this = Self { inner: tim };
87 inner: tim,
88 phantom: PhantomData,
89 };
90 84
91 this.inner.set_frequency(freq); 85 this.inner.set_frequency(freq);
92 this.inner.start(); 86 this.inner.start();
diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs
index 6b1014312..0185f7ae8 100644
--- a/embassy-stm32/src/rcc/h7.rs
+++ b/embassy-stm32/src/rcc/h7.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::unborrow; 3use embassy_hal_common::into_ref;
4pub use pll::PllConfig; 4pub use pll::PllConfig;
5use stm32_metapac::rcc::vals::{Mco1, Mco2}; 5use stm32_metapac::rcc::vals::{Mco1, Mco2};
6 6
@@ -10,7 +10,7 @@ use crate::pac::rcc::vals::{Adcsel, Ckpersel, Dppre, Hpre, Hsidiv, Pllsrc, Sw, T
10use crate::pac::{PWR, RCC, SYSCFG}; 10use crate::pac::{PWR, RCC, SYSCFG};
11use crate::rcc::{set_freqs, Clocks}; 11use crate::rcc::{set_freqs, Clocks};
12use crate::time::Hertz; 12use crate::time::Hertz;
13use crate::{peripherals, Unborrow}; 13use crate::{peripherals, Peripheral};
14 14
15/// HSI speed 15/// HSI speed
16pub const HSI_FREQ: Hertz = Hertz(64_000_000); 16pub const HSI_FREQ: Hertz = Hertz(64_000_000);
@@ -385,12 +385,12 @@ pub struct Mco<'d, T: McoInstance> {
385 385
386impl<'d, T: McoInstance> Mco<'d, T> { 386impl<'d, T: McoInstance> Mco<'d, T> {
387 pub fn new( 387 pub fn new(
388 _peri: impl Unborrow<Target = T> + 'd, 388 _peri: impl Peripheral<P = T> + 'd,
389 pin: impl Unborrow<Target = impl McoPin<T>> + 'd, 389 pin: impl Peripheral<P = impl McoPin<T>> + 'd,
390 source: impl McoSource<Raw = T::Source>, 390 source: impl McoSource<Raw = T::Source>,
391 prescaler: McoClock, 391 prescaler: McoClock,
392 ) -> Self { 392 ) -> Self {
393 unborrow!(pin); 393 into_ref!(pin);
394 394
395 critical_section::with(|_| unsafe { 395 critical_section::with(|_| unsafe {
396 T::apply_clock_settings(source.into_raw(), prescaler.into_raw()); 396 T::apply_clock_settings(source.into_raw(), prescaler.into_raw());
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index 5b3558c92..2b0ee7131 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -1,14 +1,13 @@
1#![macro_use] 1#![macro_use]
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;
9use rand_core::{CryptoRng, RngCore}; 8use rand_core::{CryptoRng, RngCore};
10 9
11use crate::{pac, peripherals, Unborrow}; 10use crate::{pac, peripherals, Peripheral};
12 11
13pub(crate) static RNG_WAKER: AtomicWaker = AtomicWaker::new(); 12pub(crate) static RNG_WAKER: AtomicWaker = AtomicWaker::new();
14 13
@@ -19,19 +18,15 @@ pub enum Error {
19} 18}
20 19
21pub struct Rng<'d, T: Instance> { 20pub struct Rng<'d, T: Instance> {
22 _inner: T, 21 _inner: PeripheralRef<'d, T>,
23 _phantom: PhantomData<&'d mut T>,
24} 22}
25 23
26impl<'d, T: Instance> Rng<'d, T> { 24impl<'d, T: Instance> Rng<'d, T> {
27 pub fn new(inner: impl Unborrow<Target = T> + 'd) -> Self { 25 pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self {
28 T::enable(); 26 T::enable();
29 T::reset(); 27 T::reset();
30 unborrow!(inner); 28 into_ref!(inner);
31 let mut random = Self { 29 let mut random = Self { _inner: inner };
32 _inner: inner,
33 _phantom: PhantomData,
34 };
35 random.reset(); 30 random.reset();
36 random 31 random
37 } 32 }
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index d94509748..b9dff8faf 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -1,23 +1,22 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::default::Default; 3use core::default::Default;
4use core::marker::PhantomData;
5use core::task::Poll; 4use core::task::Poll;
6 5
7use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
8use embassy_hal_common::drop::OnDrop; 7use embassy_hal_common::drop::OnDrop;
9use embassy_hal_common::unborrow; 8use embassy_hal_common::{into_ref, PeripheralRef};
10use futures::future::poll_fn; 9use futures::future::poll_fn;
11use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; 10use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
12 11
13use crate::dma::NoDma; 12use crate::dma::NoDma;
14use crate::gpio::sealed::AFType; 13use crate::gpio::sealed::{AFType, Pin};
15use crate::gpio::{Pull, Speed}; 14use crate::gpio::{AnyPin, Pull, Speed};
16use crate::interrupt::{Interrupt, InterruptExt}; 15use crate::interrupt::{Interrupt, InterruptExt};
17use crate::pac::sdmmc::Sdmmc as RegBlock; 16use crate::pac::sdmmc::Sdmmc as RegBlock;
18use crate::rcc::RccPeripheral; 17use crate::rcc::RccPeripheral;
19use crate::time::Hertz; 18use crate::time::Hertz;
20use crate::{peripherals, Unborrow}; 19use crate::{peripherals, Peripheral};
21 20
22/// The signalling scheme used on the SDMMC bus 21/// The signalling scheme used on the SDMMC bus
23#[non_exhaustive] 22#[non_exhaustive]
@@ -176,12 +175,19 @@ impl Default for Config {
176} 175}
177 176
178/// Sdmmc device 177/// Sdmmc device
179pub struct Sdmmc<'d, T: Instance, P: Pins<T>, Dma = NoDma> { 178pub struct Sdmmc<'d, T: Instance, Dma = NoDma> {
180 sdmmc: PhantomData<&'d mut T>, 179 _peri: PeripheralRef<'d, T>,
181 pins: P, 180 irq: PeripheralRef<'d, T::Interrupt>,
182 irq: T::Interrupt, 181 dma: PeripheralRef<'d, Dma>,
182
183 clk: PeripheralRef<'d, AnyPin>,
184 cmd: PeripheralRef<'d, AnyPin>,
185 d0: PeripheralRef<'d, AnyPin>,
186 d1: Option<PeripheralRef<'d, AnyPin>>,
187 d2: Option<PeripheralRef<'d, AnyPin>>,
188 d3: Option<PeripheralRef<'d, AnyPin>>,
189
183 config: Config, 190 config: Config,
184 dma: Dma,
185 /// Current clock to card 191 /// Current clock to card
186 clock: Hertz, 192 clock: Hertz,
187 /// Current signalling scheme to card 193 /// Current signalling scheme to card
@@ -191,16 +197,99 @@ pub struct Sdmmc<'d, T: Instance, P: Pins<T>, Dma = NoDma> {
191} 197}
192 198
193#[cfg(sdmmc_v1)] 199#[cfg(sdmmc_v1)]
194impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> { 200impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
195 pub fn new( 201 pub fn new_1bit(
196 _peripheral: impl Unborrow<Target = T> + 'd, 202 sdmmc: impl Peripheral<P = T> + 'd,
197 pins: impl Unborrow<Target = P> + 'd, 203 irq: impl Peripheral<P = T::Interrupt> + 'd,
198 irq: impl Unborrow<Target = T::Interrupt> + 'd, 204 dma: impl Peripheral<P = Dma> + 'd,
205 clk: impl Peripheral<P = impl CkPin<T>> + 'd,
206 cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
207 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
199 config: Config, 208 config: Config,
200 dma: impl Unborrow<Target = Dma> + 'd,
201 ) -> Self { 209 ) -> Self {
202 unborrow!(irq, pins, dma); 210 into_ref!(clk, cmd, d0);
203 pins.configure(); 211
212 critical_section::with(|_| unsafe {
213 clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
214 cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
215 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
216
217 clk.set_speed(Speed::VeryHigh);
218 cmd.set_speed(Speed::VeryHigh);
219 d0.set_speed(Speed::VeryHigh);
220 });
221
222 Self::new_inner(
223 sdmmc,
224 irq,
225 dma,
226 clk.map_into(),
227 cmd.map_into(),
228 d0.map_into(),
229 None,
230 None,
231 None,
232 config,
233 )
234 }
235
236 pub fn new_4bit(
237 sdmmc: impl Peripheral<P = T> + 'd,
238 irq: impl Peripheral<P = T::Interrupt> + 'd,
239 dma: impl Peripheral<P = Dma> + 'd,
240 clk: impl Peripheral<P = impl CkPin<T>> + 'd,
241 cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
242 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
243 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
244 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
245 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
246 config: Config,
247 ) -> Self {
248 into_ref!(clk, cmd, d0, d1, d2, d3);
249
250 critical_section::with(|_| unsafe {
251 clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
252 cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
253 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
254 d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up);
255 d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up);
256 d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up);
257
258 clk.set_speed(Speed::VeryHigh);
259 cmd.set_speed(Speed::VeryHigh);
260 d0.set_speed(Speed::VeryHigh);
261 d1.set_speed(Speed::VeryHigh);
262 d2.set_speed(Speed::VeryHigh);
263 d3.set_speed(Speed::VeryHigh);
264 });
265
266 Self::new_inner(
267 sdmmc,
268 irq,
269 dma,
270 clk.map_into(),
271 cmd.map_into(),
272 d0.map_into(),
273 Some(d1.map_into()),
274 Some(d2.map_into()),
275 Some(d3.map_into()),
276 config,
277 )
278 }
279
280 fn new_inner(
281 sdmmc: impl Peripheral<P = T> + 'd,
282 irq: impl Peripheral<P = T::Interrupt> + 'd,
283 dma: impl Peripheral<P = Dma> + 'd,
284 clk: PeripheralRef<'d, AnyPin>,
285 cmd: PeripheralRef<'d, AnyPin>,
286 d0: PeripheralRef<'d, AnyPin>,
287 d1: Option<PeripheralRef<'d, AnyPin>>,
288 d2: Option<PeripheralRef<'d, AnyPin>>,
289 d3: Option<PeripheralRef<'d, AnyPin>>,
290 config: Config,
291 ) -> Self {
292 into_ref!(sdmmc, irq, dma);
204 293
205 T::enable(); 294 T::enable();
206 T::reset(); 295 T::reset();
@@ -213,11 +302,18 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
213 irq.enable(); 302 irq.enable();
214 303
215 Self { 304 Self {
216 sdmmc: PhantomData, 305 _peri: sdmmc,
217 pins,
218 irq, 306 irq,
219 config,
220 dma, 307 dma,
308
309 clk,
310 cmd,
311 d0,
312 d1,
313 d2,
314 d3,
315
316 config,
221 clock, 317 clock,
222 signalling: Default::default(), 318 signalling: Default::default(),
223 card: None, 319 card: None,
@@ -226,15 +322,94 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
226} 322}
227 323
228#[cfg(sdmmc_v2)] 324#[cfg(sdmmc_v2)]
229impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> { 325impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
230 pub fn new( 326 pub fn new_1bit(
231 _peripheral: impl Unborrow<Target = T> + 'd, 327 sdmmc: impl Peripheral<P = T> + 'd,
232 pins: impl Unborrow<Target = P> + 'd, 328 irq: impl Peripheral<P = T::Interrupt> + 'd,
233 irq: impl Unborrow<Target = T::Interrupt> + 'd, 329 clk: impl Peripheral<P = impl CkPin<T>> + 'd,
330 cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
331 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
332 config: Config,
333 ) -> Self {
334 into_ref!(clk, cmd, d0);
335
336 critical_section::with(|_| unsafe {
337 clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
338 cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
339 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
340
341 clk.set_speed(Speed::VeryHigh);
342 cmd.set_speed(Speed::VeryHigh);
343 d0.set_speed(Speed::VeryHigh);
344 });
345
346 Self::new_inner(
347 sdmmc,
348 irq,
349 clk.map_into(),
350 cmd.map_into(),
351 d0.map_into(),
352 None,
353 None,
354 None,
355 config,
356 )
357 }
358
359 pub fn new_4bit(
360 sdmmc: impl Peripheral<P = T> + 'd,
361 irq: impl Peripheral<P = T::Interrupt> + 'd,
362 clk: impl Peripheral<P = impl CkPin<T>> + 'd,
363 cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
364 d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
365 d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
366 d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
367 d3: impl Peripheral<P = impl D3Pin<T>> + 'd,
368 config: Config,
369 ) -> Self {
370 into_ref!(clk, cmd, d0, d1, d2, d3);
371
372 critical_section::with(|_| unsafe {
373 clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
374 cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
375 d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
376 d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up);
377 d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up);
378 d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up);
379
380 clk.set_speed(Speed::VeryHigh);
381 cmd.set_speed(Speed::VeryHigh);
382 d0.set_speed(Speed::VeryHigh);
383 d1.set_speed(Speed::VeryHigh);
384 d2.set_speed(Speed::VeryHigh);
385 d3.set_speed(Speed::VeryHigh);
386 });
387
388 Self::new_inner(
389 sdmmc,
390 irq,
391 clk.map_into(),
392 cmd.map_into(),
393 d0.map_into(),
394 Some(d1.map_into()),
395 Some(d2.map_into()),
396 Some(d3.map_into()),
397 config,
398 )
399 }
400
401 fn new_inner(
402 sdmmc: impl Peripheral<P = T> + 'd,
403 irq: impl Peripheral<P = T::Interrupt> + 'd,
404 clk: PeripheralRef<'d, AnyPin>,
405 cmd: PeripheralRef<'d, AnyPin>,
406 d0: PeripheralRef<'d, AnyPin>,
407 d1: Option<PeripheralRef<'d, AnyPin>>,
408 d2: Option<PeripheralRef<'d, AnyPin>>,
409 d3: Option<PeripheralRef<'d, AnyPin>>,
234 config: Config, 410 config: Config,
235 ) -> Self { 411 ) -> Self {
236 unborrow!(irq, pins); 412 into_ref!(sdmmc, irq);
237 pins.configure();
238 413
239 T::enable(); 414 T::enable();
240 T::reset(); 415 T::reset();
@@ -247,11 +422,18 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
247 irq.enable(); 422 irq.enable();
248 423
249 Self { 424 Self {
250 sdmmc: PhantomData, 425 _peri: sdmmc,
251 pins,
252 irq, 426 irq,
427 dma: NoDma.into_ref(),
428
429 clk,
430 cmd,
431 d0,
432 d1,
433 d2,
434 d3,
435
253 config, 436 config,
254 dma: NoDma,
255 clock, 437 clock,
256 signalling: Default::default(), 438 signalling: Default::default(),
257 card: None, 439 card: None,
@@ -259,23 +441,28 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
259 } 441 }
260} 442}
261 443
262impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> { 444impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
263 #[inline(always)] 445 #[inline(always)]
264 pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> { 446 pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> {
265 let inner = T::inner(); 447 let inner = T::inner();
266 let freq = freq.into(); 448 let freq = freq.into();
267 449
450 let bus_width = match self.d3.is_some() {
451 true => BusWidth::Four,
452 false => BusWidth::One,
453 };
454
268 inner 455 inner
269 .init_card( 456 .init_card(
270 freq, 457 freq,
271 P::BUSWIDTH, 458 bus_width,
272 &mut self.card, 459 &mut self.card,
273 &mut self.signalling, 460 &mut self.signalling,
274 T::frequency(), 461 T::frequency(),
275 &mut self.clock, 462 &mut self.clock,
276 T::state(), 463 T::state(),
277 self.config.data_transfer_timeout, 464 self.config.data_transfer_timeout,
278 &mut self.dma, 465 &mut *self.dma,
279 ) 466 )
280 .await 467 .await
281 } 468 }
@@ -295,7 +482,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
295 card_capacity, 482 card_capacity,
296 state, 483 state,
297 self.config.data_transfer_timeout, 484 self.config.data_transfer_timeout,
298 &mut self.dma, 485 &mut *self.dma,
299 ) 486 )
300 .await 487 .await
301 } 488 }
@@ -314,7 +501,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
314 card, 501 card,
315 state, 502 state,
316 self.config.data_transfer_timeout, 503 self.config.data_transfer_timeout,
317 &mut self.dma, 504 &mut *self.dma,
318 ) 505 )
319 .await 506 .await
320 } 507 }
@@ -345,12 +532,26 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
345 } 532 }
346} 533}
347 534
348impl<'d, T: Instance, P: Pins<T>, Dma> Drop for Sdmmc<'d, T, P, Dma> { 535impl<'d, T: Instance, Dma> Drop for Sdmmc<'d, T, Dma> {
349 fn drop(&mut self) { 536 fn drop(&mut self) {
350 self.irq.disable(); 537 self.irq.disable();
351 let inner = T::inner(); 538 let inner = T::inner();
352 unsafe { inner.on_drop() }; 539 unsafe { inner.on_drop() };
353 self.pins.deconfigure(); 540
541 critical_section::with(|_| unsafe {
542 self.clk.set_as_disconnected();
543 self.cmd.set_as_disconnected();
544 self.d0.set_as_disconnected();
545 if let Some(x) = &mut self.d1 {
546 x.set_as_disconnected();
547 }
548 if let Some(x) = &mut self.d2 {
549 x.set_as_disconnected();
550 }
551 if let Some(x) = &mut self.d3 {
552 x.set_as_disconnected();
553 }
554 });
354 } 555 }
355} 556}
356 557
@@ -1296,114 +1497,6 @@ cfg_if::cfg_if! {
1296 } 1497 }
1297} 1498}
1298 1499
1299pub trait Pins<T: Instance>: sealed::Pins<T> + 'static {
1300 const BUSWIDTH: BusWidth;
1301
1302 fn configure(&mut self);
1303 fn deconfigure(&mut self);
1304}
1305
1306impl<T, CLK, CMD, D0, D1, D2, D3> sealed::Pins<T> for (CLK, CMD, D0, D1, D2, D3)
1307where
1308 T: Instance,
1309 CLK: CkPin<T>,
1310 CMD: CmdPin<T>,
1311 D0: D0Pin<T>,
1312 D1: D1Pin<T>,
1313 D2: D2Pin<T>,
1314 D3: D3Pin<T>,
1315{
1316}
1317
1318impl<T, CLK, CMD, D0> sealed::Pins<T> for (CLK, CMD, D0)
1319where
1320 T: Instance,
1321 CLK: CkPin<T>,
1322 CMD: CmdPin<T>,
1323 D0: D0Pin<T>,
1324{
1325}
1326
1327impl<T, CLK, CMD, D0, D1, D2, D3> Pins<T> for (CLK, CMD, D0, D1, D2, D3)
1328where
1329 T: Instance,
1330 CLK: CkPin<T>,
1331 CMD: CmdPin<T>,
1332 D0: D0Pin<T>,
1333 D1: D1Pin<T>,
1334 D2: D2Pin<T>,
1335 D3: D3Pin<T>,
1336{
1337 const BUSWIDTH: BusWidth = BusWidth::Four;
1338
1339 fn configure(&mut self) {
1340 let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self;
1341
1342 critical_section::with(|_| unsafe {
1343 clk_pin.set_as_af_pull(clk_pin.af_num(), AFType::OutputPushPull, Pull::None);
1344 cmd_pin.set_as_af_pull(cmd_pin.af_num(), AFType::OutputPushPull, Pull::Up);
1345 d0_pin.set_as_af_pull(d0_pin.af_num(), AFType::OutputPushPull, Pull::Up);
1346 d1_pin.set_as_af_pull(d1_pin.af_num(), AFType::OutputPushPull, Pull::Up);
1347 d2_pin.set_as_af_pull(d2_pin.af_num(), AFType::OutputPushPull, Pull::Up);
1348 d3_pin.set_as_af_pull(d3_pin.af_num(), AFType::OutputPushPull, Pull::Up);
1349
1350 clk_pin.set_speed(Speed::VeryHigh);
1351 cmd_pin.set_speed(Speed::VeryHigh);
1352 d0_pin.set_speed(Speed::VeryHigh);
1353 d1_pin.set_speed(Speed::VeryHigh);
1354 d2_pin.set_speed(Speed::VeryHigh);
1355 d3_pin.set_speed(Speed::VeryHigh);
1356 });
1357 }
1358
1359 fn deconfigure(&mut self) {
1360 let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self;
1361
1362 critical_section::with(|_| unsafe {
1363 clk_pin.set_as_disconnected();
1364 cmd_pin.set_as_disconnected();
1365 d0_pin.set_as_disconnected();
1366 d1_pin.set_as_disconnected();
1367 d2_pin.set_as_disconnected();
1368 d3_pin.set_as_disconnected();
1369 });
1370 }
1371}
1372
1373impl<T, CLK, CMD, D0> Pins<T> for (CLK, CMD, D0)
1374where
1375 T: Instance,
1376 CLK: CkPin<T>,
1377 CMD: CmdPin<T>,
1378 D0: D0Pin<T>,
1379{
1380 const BUSWIDTH: BusWidth = BusWidth::One;
1381
1382 fn configure(&mut self) {
1383 let (clk_pin, cmd_pin, d0_pin) = self;
1384
1385 critical_section::with(|_| unsafe {
1386 clk_pin.set_as_af_pull(clk_pin.af_num(), AFType::OutputPushPull, Pull::None);
1387 cmd_pin.set_as_af_pull(cmd_pin.af_num(), AFType::OutputPushPull, Pull::Up);
1388 d0_pin.set_as_af_pull(d0_pin.af_num(), AFType::OutputPushPull, Pull::Up);
1389
1390 clk_pin.set_speed(Speed::VeryHigh);
1391 cmd_pin.set_speed(Speed::VeryHigh);
1392 d0_pin.set_speed(Speed::VeryHigh);
1393 });
1394 }
1395
1396 fn deconfigure(&mut self) {
1397 let (clk_pin, cmd_pin, d0_pin) = self;
1398
1399 critical_section::with(|_| unsafe {
1400 clk_pin.set_as_disconnected();
1401 cmd_pin.set_as_disconnected();
1402 d0_pin.set_as_disconnected();
1403 });
1404 }
1405}
1406
1407foreach_peripheral!( 1500foreach_peripheral!(
1408 (sdmmc, $inst:ident) => { 1501 (sdmmc, $inst:ident) => {
1409 impl sealed::Instance for peripherals::$inst { 1502 impl sealed::Instance for peripherals::$inst {
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index a02f4492f..26fb392ef 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -1,10 +1,9 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::marker::PhantomData;
4use core::ptr; 3use core::ptr;
5 4
6use embassy_embedded_hal::SetConfig; 5use embassy_embedded_hal::SetConfig;
7use embassy_hal_common::unborrow; 6use embassy_hal_common::{into_ref, PeripheralRef};
8pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 7pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
9use futures::future::join; 8use futures::future::join;
10 9
@@ -15,7 +14,7 @@ use crate::gpio::AnyPin;
15use crate::pac::spi::{regs, vals, Spi as Regs}; 14use crate::pac::spi::{regs, vals, Spi as Regs};
16use crate::rcc::RccPeripheral; 15use crate::rcc::RccPeripheral;
17use crate::time::Hertz; 16use crate::time::Hertz;
18use crate::{peripherals, Unborrow}; 17use crate::{peripherals, Peripheral};
19 18
20#[derive(Debug)] 19#[derive(Debug)]
21#[cfg_attr(feature = "defmt", derive(defmt::Format))] 20#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -73,27 +72,27 @@ impl Config {
73} 72}
74 73
75pub struct Spi<'d, T: Instance, Tx, Rx> { 74pub struct Spi<'d, T: Instance, Tx, Rx> {
76 sck: Option<AnyPin>, 75 _peri: PeripheralRef<'d, T>,
77 mosi: Option<AnyPin>, 76 sck: Option<PeripheralRef<'d, AnyPin>>,
78 miso: Option<AnyPin>, 77 mosi: Option<PeripheralRef<'d, AnyPin>>,
79 txdma: Tx, 78 miso: Option<PeripheralRef<'d, AnyPin>>,
80 rxdma: Rx, 79 txdma: PeripheralRef<'d, Tx>,
80 rxdma: PeripheralRef<'d, Rx>,
81 current_word_size: WordSize, 81 current_word_size: WordSize,
82 phantom: PhantomData<&'d mut T>,
83} 82}
84 83
85impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 84impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
86 pub fn new( 85 pub fn new(
87 peri: impl Unborrow<Target = T> + 'd, 86 peri: impl Peripheral<P = T> + 'd,
88 sck: impl Unborrow<Target = impl SckPin<T>> + 'd, 87 sck: impl Peripheral<P = impl SckPin<T>> + 'd,
89 mosi: impl Unborrow<Target = impl MosiPin<T>> + 'd, 88 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd,
90 miso: impl Unborrow<Target = impl MisoPin<T>> + 'd, 89 miso: impl Peripheral<P = impl MisoPin<T>> + 'd,
91 txdma: impl Unborrow<Target = Tx> + 'd, 90 txdma: impl Peripheral<P = Tx> + 'd,
92 rxdma: impl Unborrow<Target = Rx> + 'd, 91 rxdma: impl Peripheral<P = Rx> + 'd,
93 freq: Hertz, 92 freq: Hertz,
94 config: Config, 93 config: Config,
95 ) -> Self { 94 ) -> Self {
96 unborrow!(sck, mosi, miso); 95 into_ref!(peri, sck, mosi, miso);
97 unsafe { 96 unsafe {
98 sck.set_as_af(sck.af_num(), AFType::OutputPushPull); 97 sck.set_as_af(sck.af_num(), AFType::OutputPushPull);
99 #[cfg(any(spi_v2, spi_v3, spi_v4))] 98 #[cfg(any(spi_v2, spi_v3, spi_v4))]
@@ -108,9 +107,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
108 107
109 Self::new_inner( 108 Self::new_inner(
110 peri, 109 peri,
111 Some(sck.degrade()), 110 Some(sck.map_into()),
112 Some(mosi.degrade()), 111 Some(mosi.map_into()),
113 Some(miso.degrade()), 112 Some(miso.map_into()),
114 txdma, 113 txdma,
115 rxdma, 114 rxdma,
116 freq, 115 freq,
@@ -119,15 +118,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
119 } 118 }
120 119
121 pub fn new_rxonly( 120 pub fn new_rxonly(
122 peri: impl Unborrow<Target = T> + 'd, 121 peri: impl Peripheral<P = T> + 'd,
123 sck: impl Unborrow<Target = impl SckPin<T>> + 'd, 122 sck: impl Peripheral<P = impl SckPin<T>> + 'd,
124 miso: impl Unborrow<Target = impl MisoPin<T>> + 'd, 123 miso: impl Peripheral<P = impl MisoPin<T>> + 'd,
125 txdma: impl Unborrow<Target = Tx> + 'd, // TODO remove 124 txdma: impl Peripheral<P = Tx> + 'd, // TODO remove
126 rxdma: impl Unborrow<Target = Rx> + 'd, 125 rxdma: impl Peripheral<P = Rx> + 'd,
127 freq: Hertz, 126 freq: Hertz,
128 config: Config, 127 config: Config,
129 ) -> Self { 128 ) -> Self {
130 unborrow!(sck, miso); 129 into_ref!(sck, miso);
131 unsafe { 130 unsafe {
132 sck.set_as_af(sck.af_num(), AFType::OutputPushPull); 131 sck.set_as_af(sck.af_num(), AFType::OutputPushPull);
133 #[cfg(any(spi_v2, spi_v3, spi_v4))] 132 #[cfg(any(spi_v2, spi_v3, spi_v4))]
@@ -139,9 +138,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
139 138
140 Self::new_inner( 139 Self::new_inner(
141 peri, 140 peri,
142 Some(sck.degrade()), 141 Some(sck.map_into()),
143 None, 142 None,
144 Some(miso.degrade()), 143 Some(miso.map_into()),
145 txdma, 144 txdma,
146 rxdma, 145 rxdma,
147 freq, 146 freq,
@@ -150,15 +149,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
150 } 149 }
151 150
152 pub fn new_txonly( 151 pub fn new_txonly(
153 peri: impl Unborrow<Target = T> + 'd, 152 peri: impl Peripheral<P = T> + 'd,
154 sck: impl Unborrow<Target = impl SckPin<T>> + 'd, 153 sck: impl Peripheral<P = impl SckPin<T>> + 'd,
155 mosi: impl Unborrow<Target = impl MosiPin<T>> + 'd, 154 mosi: impl Peripheral<P = impl MosiPin<T>> + 'd,
156 txdma: impl Unborrow<Target = Tx> + 'd, 155 txdma: impl Peripheral<P = Tx> + 'd,
157 rxdma: impl Unborrow<Target = Rx> + 'd, // TODO remove 156 rxdma: impl Peripheral<P = Rx> + 'd, // TODO remove
158 freq: Hertz, 157 freq: Hertz,
159 config: Config, 158 config: Config,
160 ) -> Self { 159 ) -> Self {
161 unborrow!(sck, mosi); 160 into_ref!(sck, mosi);
162 unsafe { 161 unsafe {
163 sck.set_as_af(sck.af_num(), AFType::OutputPushPull); 162 sck.set_as_af(sck.af_num(), AFType::OutputPushPull);
164 #[cfg(any(spi_v2, spi_v3, spi_v4))] 163 #[cfg(any(spi_v2, spi_v3, spi_v4))]
@@ -170,8 +169,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
170 169
171 Self::new_inner( 170 Self::new_inner(
172 peri, 171 peri,
173 Some(sck.degrade()), 172 Some(sck.map_into()),
174 Some(mosi.degrade()), 173 Some(mosi.map_into()),
175 None, 174 None,
176 txdma, 175 txdma,
177 rxdma, 176 rxdma,
@@ -181,16 +180,16 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
181 } 180 }
182 181
183 fn new_inner( 182 fn new_inner(
184 _peri: impl Unborrow<Target = T> + 'd, 183 peri: impl Peripheral<P = T> + 'd,
185 sck: Option<AnyPin>, 184 sck: Option<PeripheralRef<'d, AnyPin>>,
186 mosi: Option<AnyPin>, 185 mosi: Option<PeripheralRef<'d, AnyPin>>,
187 miso: Option<AnyPin>, 186 miso: Option<PeripheralRef<'d, AnyPin>>,
188 txdma: impl Unborrow<Target = Tx> + 'd, 187 txdma: impl Peripheral<P = Tx> + 'd,
189 rxdma: impl Unborrow<Target = Rx> + 'd, 188 rxdma: impl Peripheral<P = Rx> + 'd,
190 freq: Hertz, 189 freq: Hertz,
191 config: Config, 190 config: Config,
192 ) -> Self { 191 ) -> Self {
193 unborrow!(txdma, rxdma); 192 into_ref!(peri, txdma, rxdma);
194 193
195 let pclk = T::frequency(); 194 let pclk = T::frequency();
196 let br = compute_baud_rate(pclk, freq.into()); 195 let br = compute_baud_rate(pclk, freq.into());
@@ -280,13 +279,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
280 } 279 }
281 280
282 Self { 281 Self {
282 _peri: peri,
283 sck, 283 sck,
284 mosi, 284 mosi,
285 miso, 285 miso,
286 txdma, 286 txdma,
287 rxdma, 287 rxdma,
288 current_word_size: WordSize::EightBit, 288 current_word_size: WordSize::EightBit,
289 phantom: PhantomData,
290 } 289 }
291 } 290 }
292 291
@@ -995,7 +994,7 @@ pub trait Word: Copy + 'static + sealed::Word + Default + crate::dma::Word {}
995impl Word for u8 {} 994impl Word for u8 {}
996impl Word for u16 {} 995impl Word for u16 {}
997 996
998pub trait Instance: sealed::Instance + RccPeripheral {} 997pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
999pin_trait!(SckPin, Instance); 998pin_trait!(SckPin, Instance);
1000pin_trait!(MosiPin, Instance); 999pin_trait!(MosiPin, Instance);
1001pin_trait!(MisoPin, Instance); 1000pin_trait!(MisoPin, Instance);
diff --git a/embassy-stm32/src/subghz/mod.rs b/embassy-stm32/src/subghz/mod.rs
index ce513ec63..f02fc140f 100644
--- a/embassy-stm32/src/subghz/mod.rs
+++ b/embassy-stm32/src/subghz/mod.rs
@@ -83,7 +83,7 @@ use crate::peripherals::SUBGHZSPI;
83use crate::rcc::sealed::RccPeripheral; 83use crate::rcc::sealed::RccPeripheral;
84use crate::spi::{BitOrder, Config as SpiConfig, MisoPin, MosiPin, SckPin, Spi, MODE_0}; 84use crate::spi::{BitOrder, Config as SpiConfig, MisoPin, MosiPin, SckPin, Spi, MODE_0};
85use crate::time::Hertz; 85use crate::time::Hertz;
86use crate::{pac, Unborrow}; 86use crate::{pac, Peripheral};
87 87
88/// Passthrough for SPI errors (for now) 88/// Passthrough for SPI errors (for now)
89pub type Error = crate::spi::Error; 89pub type Error = crate::spi::Error;
@@ -211,12 +211,12 @@ impl<'d, Tx, Rx> SubGhz<'d, Tx, Rx> {
211 /// This will reset the radio and the SPI bus, and enable the peripheral 211 /// This will reset the radio and the SPI bus, and enable the peripheral
212 /// clock. 212 /// clock.
213 pub fn new( 213 pub fn new(
214 peri: impl Unborrow<Target = SUBGHZSPI> + 'd, 214 peri: impl Peripheral<P = SUBGHZSPI> + 'd,
215 sck: impl Unborrow<Target = impl SckPin<SUBGHZSPI>> + 'd, 215 sck: impl Peripheral<P = impl SckPin<SUBGHZSPI>> + 'd,
216 mosi: impl Unborrow<Target = impl MosiPin<SUBGHZSPI>> + 'd, 216 mosi: impl Peripheral<P = impl MosiPin<SUBGHZSPI>> + 'd,
217 miso: impl Unborrow<Target = impl MisoPin<SUBGHZSPI>> + 'd, 217 miso: impl Peripheral<P = impl MisoPin<SUBGHZSPI>> + 'd,
218 txdma: impl Unborrow<Target = Tx> + 'd, 218 txdma: impl Peripheral<P = Tx> + 'd,
219 rxdma: impl Unborrow<Target = Rx> + 'd, 219 rxdma: impl Peripheral<P = Rx> + 'd,
220 ) -> Self { 220 ) -> Self {
221 Self::pulse_radio_reset(); 221 Self::pulse_radio_reset();
222 222
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index c4703cff2..4e47ef73d 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -39,11 +39,11 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
39 pub fn new( 39 pub fn new(
40 state: &'d mut State<'d, T>, 40 state: &'d mut State<'d, T>,
41 _uart: Uart<'d, T, NoDma, NoDma>, 41 _uart: Uart<'d, T, NoDma, NoDma>,
42 irq: impl Unborrow<Target = T::Interrupt> + 'd, 42 irq: impl Peripheral<P = T::Interrupt> + 'd,
43 tx_buffer: &'d mut [u8], 43 tx_buffer: &'d mut [u8],
44 rx_buffer: &'d mut [u8], 44 rx_buffer: &'d mut [u8],
45 ) -> BufferedUart<'d, T> { 45 ) -> BufferedUart<'d, T> {
46 unborrow!(irq); 46 into_ref!(irq);
47 47
48 let r = T::regs(); 48 let r = T::regs();
49 unsafe { 49 unsafe {
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index a893e4b80..ca75bab41 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -2,14 +2,14 @@
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5use embassy_hal_common::unborrow; 5use embassy_hal_common::{into_ref, PeripheralRef};
6 6
7use crate::dma::NoDma; 7use crate::dma::NoDma;
8use crate::gpio::sealed::AFType; 8use crate::gpio::sealed::AFType;
9use crate::interrupt::Interrupt; 9use crate::interrupt::Interrupt;
10use crate::pac::usart::{regs, vals}; 10use crate::pac::usart::{regs, vals};
11use crate::rcc::RccPeripheral; 11use crate::rcc::RccPeripheral;
12use crate::{peripherals, Unborrow}; 12use crate::{peripherals, Peripheral};
13 13
14#[derive(Clone, Copy, PartialEq, Eq, Debug)] 14#[derive(Clone, Copy, PartialEq, Eq, Debug)]
15pub enum DataBits { 15pub enum DataBits {
@@ -72,23 +72,22 @@ pub enum Error {
72} 72}
73 73
74pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> { 74pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
75 phantom: PhantomData<&'d mut T>,
76 tx: UartTx<'d, T, TxDma>, 75 tx: UartTx<'d, T, TxDma>,
77 rx: UartRx<'d, T, RxDma>, 76 rx: UartRx<'d, T, RxDma>,
78} 77}
79 78
80pub struct UartTx<'d, T: Instance, TxDma = NoDma> { 79pub struct UartTx<'d, T: Instance, TxDma = NoDma> {
81 phantom: PhantomData<&'d mut T>, 80 phantom: PhantomData<&'d mut T>,
82 tx_dma: TxDma, 81 tx_dma: PeripheralRef<'d, TxDma>,
83} 82}
84 83
85pub struct UartRx<'d, T: Instance, RxDma = NoDma> { 84pub struct UartRx<'d, T: Instance, RxDma = NoDma> {
86 phantom: PhantomData<&'d mut T>, 85 phantom: PhantomData<&'d mut T>,
87 rx_dma: RxDma, 86 rx_dma: PeripheralRef<'d, RxDma>,
88} 87}
89 88
90impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> { 89impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> {
91 fn new(tx_dma: TxDma) -> Self { 90 fn new(tx_dma: PeripheralRef<'d, TxDma>) -> Self {
92 Self { 91 Self {
93 tx_dma, 92 tx_dma,
94 phantom: PhantomData, 93 phantom: PhantomData,
@@ -134,7 +133,7 @@ impl<'d, T: Instance, TxDma> UartTx<'d, T, TxDma> {
134} 133}
135 134
136impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> { 135impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> {
137 fn new(rx_dma: RxDma) -> Self { 136 fn new(rx_dma: PeripheralRef<'d, RxDma>) -> Self {
138 Self { 137 Self {
139 rx_dma, 138 rx_dma,
140 phantom: PhantomData, 139 phantom: PhantomData,
@@ -190,14 +189,14 @@ impl<'d, T: Instance, RxDma> UartRx<'d, T, RxDma> {
190 189
191impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { 190impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
192 pub fn new( 191 pub fn new(
193 _inner: impl Unborrow<Target = T> + 'd, 192 _inner: impl Peripheral<P = T> + 'd,
194 rx: impl Unborrow<Target = impl RxPin<T>> + 'd, 193 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
195 tx: impl Unborrow<Target = impl TxPin<T>> + 'd, 194 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
196 tx_dma: impl Unborrow<Target = TxDma> + 'd, 195 tx_dma: impl Peripheral<P = TxDma> + 'd,
197 rx_dma: impl Unborrow<Target = RxDma> + 'd, 196 rx_dma: impl Peripheral<P = RxDma> + 'd,
198 config: Config, 197 config: Config,
199 ) -> Self { 198 ) -> Self {
200 unborrow!(_inner, rx, tx, tx_dma, rx_dma); 199 into_ref!(_inner, rx, tx, tx_dma, rx_dma);
201 200
202 T::enable(); 201 T::enable();
203 T::reset(); 202 T::reset();
@@ -234,7 +233,6 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
234 } 233 }
235 234
236 Self { 235 Self {
237 phantom: PhantomData,
238 tx: UartTx::new(tx_dma), 236 tx: UartTx::new(tx_dma),
239 rx: UartRx::new(rx_dma), 237 rx: UartRx::new(rx_dma),
240 } 238 }
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 4633ff00c..11ef75954 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -7,7 +7,7 @@ use core::task::Poll;
7use atomic_polyfill::{AtomicBool, AtomicU8}; 7use atomic_polyfill::{AtomicBool, AtomicU8};
8use embassy::time::{block_for, Duration}; 8use embassy::time::{block_for, Duration};
9use embassy::waitqueue::AtomicWaker; 9use embassy::waitqueue::AtomicWaker;
10use embassy_hal_common::unborrow; 10use embassy_hal_common::into_ref;
11use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported}; 11use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported};
12use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection}; 12use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
13use futures::future::poll_fn; 13use futures::future::poll_fn;
@@ -20,7 +20,7 @@ use crate::gpio::sealed::AFType;
20use crate::interrupt::InterruptExt; 20use crate::interrupt::InterruptExt;
21use crate::pac::usb::regs; 21use crate::pac::usb::regs;
22use crate::rcc::sealed::RccPeripheral; 22use crate::rcc::sealed::RccPeripheral;
23use crate::{pac, Unborrow}; 23use crate::{pac, Peripheral};
24 24
25const EP_COUNT: usize = 8; 25const EP_COUNT: usize = 8;
26 26
@@ -125,12 +125,12 @@ pub struct Driver<'d, T: Instance> {
125 125
126impl<'d, T: Instance> Driver<'d, T> { 126impl<'d, T: Instance> Driver<'d, T> {
127 pub fn new( 127 pub fn new(
128 _usb: impl Unborrow<Target = T> + 'd, 128 _usb: impl Peripheral<P = T> + 'd,
129 irq: impl Unborrow<Target = T::Interrupt> + 'd, 129 irq: impl Peripheral<P = T::Interrupt> + 'd,
130 dp: impl Unborrow<Target = impl DpPin<T>> + 'd, 130 dp: impl Peripheral<P = impl DpPin<T>> + 'd,
131 dm: impl Unborrow<Target = impl DmPin<T>> + 'd, 131 dm: impl Peripheral<P = impl DmPin<T>> + 'd,
132 ) -> Self { 132 ) -> Self {
133 unborrow!(irq, dp, dm); 133 into_ref!(irq, dp, dm);
134 irq.set_handler(Self::on_interrupt); 134 irq.set_handler(Self::on_interrupt);
135 irq.unpend(); 135 irq.unpend();
136 irq.enable(); 136 irq.enable();
diff --git a/embassy-stm32/src/usb_otg.rs b/embassy-stm32/src/usb_otg.rs
index 581754135..f7faf12a8 100644
--- a/embassy-stm32/src/usb_otg.rs
+++ b/embassy-stm32/src/usb_otg.rs
@@ -1,14 +1,14 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::unborrow; 3use embassy_hal_common::into_ref;
4 4
5use crate::gpio::sealed::AFType; 5use crate::gpio::sealed::AFType;
6use crate::rcc::RccPeripheral; 6use crate::rcc::RccPeripheral;
7use crate::{peripherals, Unborrow}; 7use crate::{peripherals, Peripheral};
8 8
9macro_rules! config_ulpi_pins { 9macro_rules! config_ulpi_pins {
10 ($($pin:ident),*) => { 10 ($($pin:ident),*) => {
11 unborrow!($($pin),*); 11 into_ref!($($pin),*);
12 // NOTE(unsafe) Exclusive access to the registers 12 // NOTE(unsafe) Exclusive access to the registers
13 critical_section::with(|_| unsafe { 13 critical_section::with(|_| unsafe {
14 $( 14 $(
@@ -43,11 +43,11 @@ pub struct UsbOtg<'d, T: Instance> {
43impl<'d, T: Instance> UsbOtg<'d, T> { 43impl<'d, T: Instance> UsbOtg<'d, T> {
44 /// Initializes USB OTG peripheral with internal Full-Speed PHY 44 /// Initializes USB OTG peripheral with internal Full-Speed PHY
45 pub fn new_fs( 45 pub fn new_fs(
46 _peri: impl Unborrow<Target = T> + 'd, 46 _peri: impl Peripheral<P = T> + 'd,
47 dp: impl Unborrow<Target = impl DpPin<T>> + 'd, 47 dp: impl Peripheral<P = impl DpPin<T>> + 'd,
48 dm: impl Unborrow<Target = impl DmPin<T>> + 'd, 48 dm: impl Peripheral<P = impl DmPin<T>> + 'd,
49 ) -> Self { 49 ) -> Self {
50 unborrow!(dp, dm); 50 into_ref!(dp, dm);
51 51
52 unsafe { 52 unsafe {
53 dp.set_as_af(dp.af_num(), AFType::OutputPushPull); 53 dp.set_as_af(dp.af_num(), AFType::OutputPushPull);
@@ -62,19 +62,19 @@ impl<'d, T: Instance> UsbOtg<'d, T> {
62 62
63 /// Initializes USB OTG peripheral with external High-Speed PHY 63 /// Initializes USB OTG peripheral with external High-Speed PHY
64 pub fn new_hs_ulpi( 64 pub fn new_hs_ulpi(
65 _peri: impl Unborrow<Target = T> + 'd, 65 _peri: impl Peripheral<P = T> + 'd,
66 ulpi_clk: impl Unborrow<Target = impl UlpiClkPin<T>> + 'd, 66 ulpi_clk: impl Peripheral<P = impl UlpiClkPin<T>> + 'd,
67 ulpi_dir: impl Unborrow<Target = impl UlpiDirPin<T>> + 'd, 67 ulpi_dir: impl Peripheral<P = impl UlpiDirPin<T>> + 'd,
68 ulpi_nxt: impl Unborrow<Target = impl UlpiNxtPin<T>> + 'd, 68 ulpi_nxt: impl Peripheral<P = impl UlpiNxtPin<T>> + 'd,
69 ulpi_stp: impl Unborrow<Target = impl UlpiStpPin<T>> + 'd, 69 ulpi_stp: impl Peripheral<P = impl UlpiStpPin<T>> + 'd,
70 ulpi_d0: impl Unborrow<Target = impl UlpiD0Pin<T>> + 'd, 70 ulpi_d0: impl Peripheral<P = impl UlpiD0Pin<T>> + 'd,
71 ulpi_d1: impl Unborrow<Target = impl UlpiD1Pin<T>> + 'd, 71 ulpi_d1: impl Peripheral<P = impl UlpiD1Pin<T>> + 'd,
72 ulpi_d2: impl Unborrow<Target = impl UlpiD2Pin<T>> + 'd, 72 ulpi_d2: impl Peripheral<P = impl UlpiD2Pin<T>> + 'd,
73 ulpi_d3: impl Unborrow<Target = impl UlpiD3Pin<T>> + 'd, 73 ulpi_d3: impl Peripheral<P = impl UlpiD3Pin<T>> + 'd,
74 ulpi_d4: impl Unborrow<Target = impl UlpiD4Pin<T>> + 'd, 74 ulpi_d4: impl Peripheral<P = impl UlpiD4Pin<T>> + 'd,
75 ulpi_d5: impl Unborrow<Target = impl UlpiD5Pin<T>> + 'd, 75 ulpi_d5: impl Peripheral<P = impl UlpiD5Pin<T>> + 'd,
76 ulpi_d6: impl Unborrow<Target = impl UlpiD6Pin<T>> + 'd, 76 ulpi_d6: impl Peripheral<P = impl UlpiD6Pin<T>> + 'd,
77 ulpi_d7: impl Unborrow<Target = impl UlpiD7Pin<T>> + 'd, 77 ulpi_d7: impl Peripheral<P = impl UlpiD7Pin<T>> + 'd,
78 ) -> Self { 78 ) -> Self {
79 config_ulpi_pins!( 79 config_ulpi_pins!(
80 ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp, ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4, ulpi_d5, ulpi_d6, 80 ulpi_clk, ulpi_dir, ulpi_nxt, ulpi_stp, ulpi_d0, ulpi_d1, ulpi_d2, ulpi_d3, ulpi_d4, ulpi_d5, ulpi_d6,
diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs
index c4b2609b1..85176eefc 100644
--- a/embassy-stm32/src/wdg/mod.rs
+++ b/embassy-stm32/src/wdg/mod.rs
@@ -1,6 +1,6 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_hal_common::{unborrow, Unborrow}; 3use embassy_hal_common::{into_ref, Peripheral};
4use stm32_metapac::iwdg::vals::{Key, Pr}; 4use stm32_metapac::iwdg::vals::{Key, Pr};
5 5
6use crate::rcc::LSI_FREQ; 6use crate::rcc::LSI_FREQ;
@@ -27,8 +27,8 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> {
27 /// 27 ///
28 /// [Self] has to be started with [Self::unleash()]. 28 /// [Self] has to be started with [Self::unleash()].
29 /// Once timer expires, MCU will be reset. To prevent this, timer must be reloaded by repeatedly calling [Self::pet()] within timeout interval. 29 /// Once timer expires, MCU will be reset. To prevent this, timer must be reloaded by repeatedly calling [Self::pet()] within timeout interval.
30 pub fn new(_instance: impl Unborrow<Target = T> + 'd, timeout_us: u32) -> Self { 30 pub fn new(_instance: impl Peripheral<P = T> + 'd, timeout_us: u32) -> Self {
31 unborrow!(_instance); 31 into_ref!(_instance);
32 32
33 // Find lowest prescaler value, which makes watchdog period longer or equal to timeout. 33 // Find lowest prescaler value, which makes watchdog period longer or equal to timeout.
34 // This iterates from 4 (2^2) to 256 (2^8). 34 // This iterates from 4 (2^2) to 256 (2^8).
diff --git a/examples/stm32f4/src/bin/sdmmc.rs b/examples/stm32f4/src/bin/sdmmc.rs
index 665670261..752ad57bf 100644
--- a/examples/stm32f4/src/bin/sdmmc.rs
+++ b/examples/stm32f4/src/bin/sdmmc.rs
@@ -21,12 +21,17 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
21 21
22 let irq = interrupt::take!(SDIO); 22 let irq = interrupt::take!(SDIO);
23 23
24 let mut sdmmc = Sdmmc::new( 24 let mut sdmmc = Sdmmc::new_4bit(
25 p.SDIO, 25 p.SDIO,
26 (p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
27 irq, 26 irq,
28 Default::default(),
29 p.DMA2_CH3, 27 p.DMA2_CH3,
28 p.PC12,
29 p.PD2,
30 p.PC8,
31 p.PC9,
32 p.PC10,
33 p.PC11,
34 Default::default(),
30 ); 35 );
31 36
32 // Should print 400kHz for initialization 37 // Should print 400kHz for initialization
diff --git a/examples/stm32f7/src/bin/sdmmc.rs b/examples/stm32f7/src/bin/sdmmc.rs
index 011e1fd95..be1c2b152 100644
--- a/examples/stm32f7/src/bin/sdmmc.rs
+++ b/examples/stm32f7/src/bin/sdmmc.rs
@@ -21,12 +21,17 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
21 21
22 let irq = interrupt::take!(SDMMC1); 22 let irq = interrupt::take!(SDMMC1);
23 23
24 let mut sdmmc = Sdmmc::new( 24 let mut sdmmc = Sdmmc::new_4bit(
25 p.SDMMC1, 25 p.SDMMC1,
26 (p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
27 irq, 26 irq,
28 Default::default(),
29 p.DMA2_CH3, 27 p.DMA2_CH3,
28 p.PC12,
29 p.PD2,
30 p.PC8,
31 p.PC9,
32 p.PC10,
33 p.PC11,
34 Default::default(),
30 ); 35 );
31 36
32 // Should print 400kHz for initialization 37 // Should print 400kHz for initialization
diff --git a/examples/stm32h7/src/bin/low_level_timer_api.rs b/examples/stm32h7/src/bin/low_level_timer_api.rs
index fc19d84e4..d7c6da5bd 100644
--- a/examples/stm32h7/src/bin/low_level_timer_api.rs
+++ b/examples/stm32h7/src/bin/low_level_timer_api.rs
@@ -2,8 +2,6 @@
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use core::marker::PhantomData;
6
7use defmt::*; 5use defmt::*;
8use embassy::executor::Spawner; 6use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer}; 7use embassy::time::{Duration, Timer};
@@ -11,7 +9,7 @@ use embassy_stm32::gpio::low_level::AFType;
11use embassy_stm32::gpio::Speed; 9use embassy_stm32::gpio::Speed;
12use embassy_stm32::pwm::*; 10use embassy_stm32::pwm::*;
13use embassy_stm32::time::{khz, mhz, Hertz}; 11use embassy_stm32::time::{khz, mhz, Hertz};
14use embassy_stm32::{unborrow, Config, Peripherals, Unborrow}; 12use embassy_stm32::{into_ref, Config, Peripheral, PeripheralRef, Peripherals};
15use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
16 14
17pub fn config() -> Config { 15pub fn config() -> Config {
@@ -49,20 +47,19 @@ async fn main(_spawner: Spawner, p: Peripherals) {
49 } 47 }
50} 48}
51pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> { 49pub struct SimplePwm32<'d, T: CaptureCompare32bitInstance> {
52 phantom: PhantomData<&'d mut T>, 50 inner: PeripheralRef<'d, T>,
53 inner: T,
54} 51}
55 52
56impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> { 53impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
57 pub fn new( 54 pub fn new(
58 tim: impl Unborrow<Target = T> + 'd, 55 tim: impl Peripheral<P = T> + 'd,
59 ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd, 56 ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd,
60 ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd, 57 ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd,
61 ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd, 58 ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd,
62 ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd, 59 ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd,
63 freq: Hertz, 60 freq: Hertz,
64 ) -> Self { 61 ) -> Self {
65 unborrow!(tim, ch1, ch2, ch3, ch4); 62 into_ref!(tim, ch1, ch2, ch3, ch4);
66 63
67 T::enable(); 64 T::enable();
68 <T as embassy_stm32::rcc::low_level::RccPeripheral>::reset(); 65 <T as embassy_stm32::rcc::low_level::RccPeripheral>::reset();
@@ -78,10 +75,7 @@ impl<'d, T: CaptureCompare32bitInstance> SimplePwm32<'d, T> {
78 ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull); 75 ch4.set_as_af(ch1.af_num(), AFType::OutputPushPull);
79 } 76 }
80 77
81 let mut this = Self { 78 let mut this = Self { inner: tim };
82 inner: tim,
83 phantom: PhantomData,
84 };
85 79
86 this.set_freq(freq); 80 this.set_freq(freq);
87 this.inner.start(); 81 this.inner.start();
diff --git a/examples/stm32h7/src/bin/sdmmc.rs b/examples/stm32h7/src/bin/sdmmc.rs
index 787f700ae..163807d86 100644
--- a/examples/stm32h7/src/bin/sdmmc.rs
+++ b/examples/stm32h7/src/bin/sdmmc.rs
@@ -21,10 +21,15 @@ async fn main(_spawner: Spawner, p: Peripherals) -> ! {
21 21
22 let irq = interrupt::take!(SDMMC1); 22 let irq = interrupt::take!(SDMMC1);
23 23
24 let mut sdmmc = Sdmmc::new( 24 let mut sdmmc = Sdmmc::new_4bit(
25 p.SDMMC1, 25 p.SDMMC1,
26 (p.PC12, p.PD2, p.PC8, p.PC9, p.PC10, p.PC11),
27 irq, 26 irq,
27 p.PC12,
28 p.PD2,
29 p.PC8,
30 p.PC9,
31 p.PC10,
32 p.PC11,
28 Default::default(), 33 Default::default(),
29 ); 34 );
30 35