aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-03-26 16:01:37 +0100
committerDario Nieuwenhuis <[email protected]>2025-03-27 15:18:06 +0100
commitd41eeeae79388f219bf6a84e2f7bde9f6b532516 (patch)
tree678b6fc732216e529dc38e6f65b72a309917ac32 /embassy-rp/src
parent9edf5b7f049f95742b60b041e4443967d8a6b708 (diff)
Remove Peripheral trait, rename PeripheralRef->Peri.
Diffstat (limited to 'embassy-rp/src')
-rw-r--r--embassy-rp/src/adc.rs30
-rw-r--r--embassy-rp/src/bootsel.rs21
-rw-r--r--embassy-rp/src/clocks.rs25
-rw-r--r--embassy-rp/src/dma.rs33
-rw-r--r--embassy-rp/src/flash.rs15
-rw-r--r--embassy-rp/src/gpio.rs41
-rw-r--r--embassy-rp/src/i2c.rs34
-rw-r--r--embassy-rp/src/i2c_slave.rs11
-rw-r--r--embassy-rp/src/lib.rs2
-rw-r--r--embassy-rp/src/multicore.rs4
-rw-r--r--embassy-rp/src/pio/mod.rs18
-rw-r--r--embassy-rp/src/pio_programs/hd44780.rs24
-rw-r--r--embassy-rp/src/pio_programs/i2s.rs39
-rw-r--r--embassy-rp/src/pio_programs/onewire.rs3
-rw-r--r--embassy-rp/src/pio_programs/pwm.rs4
-rw-r--r--embassy-rp/src/pio_programs/rotary_encoder.rs5
-rw-r--r--embassy-rp/src/pio_programs/stepper.rs9
-rw-r--r--embassy-rp/src/pio_programs/uart.rs45
-rw-r--r--embassy-rp/src/pio_programs/ws2812.rs15
-rw-r--r--embassy-rp/src/pwm.rs80
-rw-r--r--embassy-rp/src/rtc/mod.rs10
-rw-r--r--embassy-rp/src/spi.rs136
-rw-r--r--embassy-rp/src/trng.rs10
-rw-r--r--embassy-rp/src/uart/buffered.rs66
-rw-r--r--embassy-rp/src/uart/mod.rs168
-rw-r--r--embassy-rp/src/usb.rs7
-rw-r--r--embassy-rp/src/watchdog.rs4
27 files changed, 362 insertions, 497 deletions
diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs
index 8defb5231..ba9ec732d 100644
--- a/embassy-rp/src/adc.rs
+++ b/embassy-rp/src/adc.rs
@@ -5,7 +5,6 @@ use core::mem;
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::{into_ref, PeripheralRef};
9use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
10 9
11use crate::gpio::{self, AnyPin, Pull, SealedPin as GpioPin}; 10use crate::gpio::{self, AnyPin, Pull, SealedPin as GpioPin};
@@ -13,7 +12,7 @@ use crate::interrupt::typelevel::Binding;
13use crate::interrupt::InterruptExt; 12use crate::interrupt::InterruptExt;
14use crate::pac::dma::vals::TreqSel; 13use crate::pac::dma::vals::TreqSel;
15use crate::peripherals::{ADC, ADC_TEMP_SENSOR}; 14use crate::peripherals::{ADC, ADC_TEMP_SENSOR};
16use crate::{dma, interrupt, pac, peripherals, Peripheral, RegExt}; 15use crate::{dma, interrupt, pac, peripherals, Peri, RegExt};
17 16
18static WAKER: AtomicWaker = AtomicWaker::new(); 17static WAKER: AtomicWaker = AtomicWaker::new();
19 18
@@ -23,8 +22,8 @@ static WAKER: AtomicWaker = AtomicWaker::new();
23pub struct Config {} 22pub struct Config {}
24 23
25enum Source<'p> { 24enum Source<'p> {
26 Pin(PeripheralRef<'p, AnyPin>), 25 Pin(Peri<'p, AnyPin>),
27 TempSensor(PeripheralRef<'p, ADC_TEMP_SENSOR>), 26 TempSensor(Peri<'p, ADC_TEMP_SENSOR>),
28} 27}
29 28
30/// ADC channel. 29/// ADC channel.
@@ -32,8 +31,7 @@ pub struct Channel<'p>(Source<'p>);
32 31
33impl<'p> Channel<'p> { 32impl<'p> Channel<'p> {
34 /// Create a new ADC channel from pin with the provided [Pull] configuration. 33 /// Create a new ADC channel from pin with the provided [Pull] configuration.
35 pub fn new_pin(pin: impl Peripheral<P = impl AdcPin + 'p> + 'p, pull: Pull) -> Self { 34 pub fn new_pin(pin: Peri<'p, impl AdcPin + 'p>, pull: Pull) -> Self {
36 into_ref!(pin);
37 pin.pad_ctrl().modify(|w| { 35 pin.pad_ctrl().modify(|w| {
38 #[cfg(feature = "_rp235x")] 36 #[cfg(feature = "_rp235x")]
39 w.set_iso(false); 37 w.set_iso(false);
@@ -47,14 +45,14 @@ impl<'p> Channel<'p> {
47 w.set_pue(pull == Pull::Up); 45 w.set_pue(pull == Pull::Up);
48 w.set_pde(pull == Pull::Down); 46 w.set_pde(pull == Pull::Down);
49 }); 47 });
50 Self(Source::Pin(pin.map_into())) 48 Self(Source::Pin(pin.into()))
51 } 49 }
52 50
53 /// Create a new ADC channel for the internal temperature sensor. 51 /// Create a new ADC channel for the internal temperature sensor.
54 pub fn new_temp_sensor(s: impl Peripheral<P = ADC_TEMP_SENSOR> + 'p) -> Self { 52 pub fn new_temp_sensor(s: Peri<'p, ADC_TEMP_SENSOR>) -> Self {
55 let r = pac::ADC; 53 let r = pac::ADC;
56 r.cs().write_set(|w| w.set_ts_en(true)); 54 r.cs().write_set(|w| w.set_ts_en(true));
57 Self(Source::TempSensor(s.into_ref())) 55 Self(Source::TempSensor(s))
58 } 56 }
59 57
60 fn channel(&self) -> u8 { 58 fn channel(&self) -> u8 {
@@ -190,7 +188,7 @@ impl<'d, M: Mode> Adc<'d, M> {
190impl<'d> Adc<'d, Async> { 188impl<'d> Adc<'d, Async> {
191 /// Create ADC driver in async mode. 189 /// Create ADC driver in async mode.
192 pub fn new( 190 pub fn new(
193 _inner: impl Peripheral<P = ADC> + 'd, 191 _inner: Peri<'d, ADC>,
194 _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>, 192 _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>,
195 _config: Config, 193 _config: Config,
196 ) -> Self { 194 ) -> Self {
@@ -240,7 +238,7 @@ impl<'d> Adc<'d, Async> {
240 buf: &mut [W], 238 buf: &mut [W],
241 fcs_err: bool, 239 fcs_err: bool,
242 div: u16, 240 div: u16,
243 dma: impl Peripheral<P = impl dma::Channel>, 241 dma: Peri<'_, impl dma::Channel>,
244 ) -> Result<(), Error> { 242 ) -> Result<(), Error> {
245 #[cfg(feature = "rp2040")] 243 #[cfg(feature = "rp2040")]
246 let mut rrobin = 0_u8; 244 let mut rrobin = 0_u8;
@@ -321,7 +319,7 @@ impl<'d> Adc<'d, Async> {
321 ch: &mut [Channel<'_>], 319 ch: &mut [Channel<'_>],
322 buf: &mut [S], 320 buf: &mut [S],
323 div: u16, 321 div: u16,
324 dma: impl Peripheral<P = impl dma::Channel>, 322 dma: Peri<'_, impl dma::Channel>,
325 ) -> Result<(), Error> { 323 ) -> Result<(), Error> {
326 self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma) 324 self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma)
327 .await 325 .await
@@ -337,7 +335,7 @@ impl<'d> Adc<'d, Async> {
337 ch: &mut [Channel<'_>], 335 ch: &mut [Channel<'_>],
338 buf: &mut [Sample], 336 buf: &mut [Sample],
339 div: u16, 337 div: u16,
340 dma: impl Peripheral<P = impl dma::Channel>, 338 dma: Peri<'_, impl dma::Channel>,
341 ) { 339 ) {
342 // errors are reported in individual samples 340 // errors are reported in individual samples
343 let _ = self 341 let _ = self
@@ -360,7 +358,7 @@ impl<'d> Adc<'d, Async> {
360 ch: &mut Channel<'_>, 358 ch: &mut Channel<'_>,
361 buf: &mut [S], 359 buf: &mut [S],
362 div: u16, 360 div: u16,
363 dma: impl Peripheral<P = impl dma::Channel>, 361 dma: Peri<'_, impl dma::Channel>,
364 ) -> Result<(), Error> { 362 ) -> Result<(), Error> {
365 self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma) 363 self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma)
366 .await 364 .await
@@ -375,7 +373,7 @@ impl<'d> Adc<'d, Async> {
375 ch: &mut Channel<'_>, 373 ch: &mut Channel<'_>,
376 buf: &mut [Sample], 374 buf: &mut [Sample],
377 div: u16, 375 div: u16,
378 dma: impl Peripheral<P = impl dma::Channel>, 376 dma: Peri<'_, impl dma::Channel>,
379 ) { 377 ) {
380 // errors are reported in individual samples 378 // errors are reported in individual samples
381 let _ = self 379 let _ = self
@@ -392,7 +390,7 @@ impl<'d> Adc<'d, Async> {
392 390
393impl<'d> Adc<'d, Blocking> { 391impl<'d> Adc<'d, Blocking> {
394 /// Create ADC driver in blocking mode. 392 /// Create ADC driver in blocking mode.
395 pub fn new_blocking(_inner: impl Peripheral<P = ADC> + 'd, _config: Config) -> Self { 393 pub fn new_blocking(_inner: Peri<'d, ADC>, _config: Config) -> Self {
396 Self::setup(); 394 Self::setup();
397 395
398 Self { phantom: PhantomData } 396 Self { phantom: PhantomData }
diff --git a/embassy-rp/src/bootsel.rs b/embassy-rp/src/bootsel.rs
index d24ce7bd8..14f9e46aa 100644
--- a/embassy-rp/src/bootsel.rs
+++ b/embassy-rp/src/bootsel.rs
@@ -8,20 +8,19 @@
8//! This module provides functionality to poll BOOTSEL from an embassy application. 8//! This module provides functionality to poll BOOTSEL from an embassy application.
9 9
10use crate::flash::in_ram; 10use crate::flash::in_ram;
11use crate::Peri;
11 12
12impl crate::peripherals::BOOTSEL { 13/// Reads the BOOTSEL button. Returns true if the button is pressed.
13 /// Polls the BOOTSEL button. Returns true if the button is pressed. 14///
14 /// 15/// Reading isn't cheap, as this function waits for core 1 to finish it's current
15 /// Polling isn't cheap, as this function waits for core 1 to finish it's current 16/// task and for any DMAs from flash to complete
16 /// task and for any DMAs from flash to complete 17pub fn is_bootsel_pressed(_p: Peri<'_, crate::peripherals::BOOTSEL>) -> bool {
17 pub fn is_pressed(&mut self) -> bool { 18 let mut cs_status = Default::default();
18 let mut cs_status = Default::default();
19 19
20 unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0"); 20 unsafe { in_ram(|| cs_status = ram_helpers::read_cs_status()) }.expect("Must be called from Core 0");
21 21
22 // bootsel is active low, so invert 22 // bootsel is active low, so invert
23 !cs_status.infrompad() 23 !cs_status.infrompad()
24 }
25} 24}
26 25
27mod ram_helpers { 26mod ram_helpers {
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs
index 705dde62a..67aa5e540 100644
--- a/embassy-rp/src/clocks.rs
+++ b/embassy-rp/src/clocks.rs
@@ -7,13 +7,12 @@ use core::marker::PhantomData;
7use core::sync::atomic::AtomicU16; 7use core::sync::atomic::AtomicU16;
8use core::sync::atomic::{AtomicU32, Ordering}; 8use core::sync::atomic::{AtomicU32, Ordering};
9 9
10use embassy_hal_internal::{into_ref, PeripheralRef};
11use pac::clocks::vals::*; 10use pac::clocks::vals::*;
12 11
13use crate::gpio::{AnyPin, SealedPin}; 12use crate::gpio::{AnyPin, SealedPin};
14#[cfg(feature = "rp2040")] 13#[cfg(feature = "rp2040")]
15use crate::pac::common::{Reg, RW}; 14use crate::pac::common::{Reg, RW};
16use crate::{pac, reset, Peripheral}; 15use crate::{pac, reset, Peri};
17 16
18// NOTE: all gpin handling is commented out for future reference. 17// NOTE: all gpin handling is commented out for future reference.
19// gpin is not usually safe to use during the boot init() call, so it won't 18// gpin is not usually safe to use during the boot init() call, so it won't
@@ -200,8 +199,8 @@ impl ClockConfig {
200 199
201 // pub fn bind_gpin<P: GpinPin>(&mut self, gpin: Gpin<'static, P>, hz: u32) { 200 // pub fn bind_gpin<P: GpinPin>(&mut self, gpin: Gpin<'static, P>, hz: u32) {
202 // match P::NR { 201 // match P::NR {
203 // 0 => self.gpin0 = Some((hz, gpin.map_into())), 202 // 0 => self.gpin0 = Some((hz, gpin.into())),
204 // 1 => self.gpin1 = Some((hz, gpin.map_into())), 203 // 1 => self.gpin1 = Some((hz, gpin.into())),
205 // _ => unreachable!(), 204 // _ => unreachable!(),
206 // } 205 // }
207 // // pin is now provisionally bound. if the config is applied it must be forgotten, 206 // // pin is now provisionally bound. if the config is applied it must be forgotten,
@@ -845,15 +844,13 @@ impl_gpinpin!(PIN_22, 22, 1);
845 844
846/// General purpose clock input driver. 845/// General purpose clock input driver.
847pub struct Gpin<'d, T: GpinPin> { 846pub struct Gpin<'d, T: GpinPin> {
848 gpin: PeripheralRef<'d, AnyPin>, 847 gpin: Peri<'d, AnyPin>,
849 _phantom: PhantomData<T>, 848 _phantom: PhantomData<T>,
850} 849}
851 850
852impl<'d, T: GpinPin> Gpin<'d, T> { 851impl<'d, T: GpinPin> Gpin<'d, T> {
853 /// Create new gpin driver. 852 /// Create new gpin driver.
854 pub fn new(gpin: impl Peripheral<P = T> + 'd) -> Self { 853 pub fn new(gpin: Peri<'d, T>) -> Self {
855 into_ref!(gpin);
856
857 #[cfg(feature = "rp2040")] 854 #[cfg(feature = "rp2040")]
858 gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08)); 855 gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08));
859 856
@@ -867,14 +864,10 @@ impl<'d, T: GpinPin> Gpin<'d, T> {
867 }); 864 });
868 865
869 Gpin { 866 Gpin {
870 gpin: gpin.map_into(), 867 gpin: gpin.into(),
871 _phantom: PhantomData, 868 _phantom: PhantomData,
872 } 869 }
873 } 870 }
874
875 // fn map_into(self) -> Gpin<'d, AnyPin> {
876 // unsafe { core::mem::transmute(self) }
877 // }
878} 871}
879 872
880impl<'d, T: GpinPin> Drop for Gpin<'d, T> { 873impl<'d, T: GpinPin> Drop for Gpin<'d, T> {
@@ -936,14 +929,12 @@ pub enum GpoutSrc {
936 929
937/// General purpose clock output driver. 930/// General purpose clock output driver.
938pub struct Gpout<'d, T: GpoutPin> { 931pub struct Gpout<'d, T: GpoutPin> {
939 gpout: PeripheralRef<'d, T>, 932 gpout: Peri<'d, T>,
940} 933}
941 934
942impl<'d, T: GpoutPin> Gpout<'d, T> { 935impl<'d, T: GpoutPin> Gpout<'d, T> {
943 /// Create new general purpose clock output. 936 /// Create new general purpose clock output.
944 pub fn new(gpout: impl Peripheral<P = T> + 'd) -> Self { 937 pub fn new(gpout: Peri<'d, T>) -> Self {
945 into_ref!(gpout);
946
947 #[cfg(feature = "rp2040")] 938 #[cfg(feature = "rp2040")]
948 gpout.gpio().ctrl().write(|w| w.set_funcsel(0x08)); 939 gpout.gpio().ctrl().write(|w| w.set_funcsel(0x08));
949 940
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs
index 2edcfdf5b..d31d1e159 100644
--- a/embassy-rp/src/dma.rs
+++ b/embassy-rp/src/dma.rs
@@ -4,7 +4,7 @@ use core::pin::Pin;
4use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; 7use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9use pac::dma::vals::DataSize; 9use pac::dma::vals::DataSize;
10 10
@@ -42,7 +42,7 @@ pub(crate) unsafe fn init() {
42/// 42///
43/// SAFETY: Slice must point to a valid location reachable by DMA. 43/// SAFETY: Slice must point to a valid location reachable by DMA.
44pub unsafe fn read<'a, C: Channel, W: Word>( 44pub unsafe fn read<'a, C: Channel, W: Word>(
45 ch: impl Peripheral<P = C> + 'a, 45 ch: Peri<'a, C>,
46 from: *const W, 46 from: *const W,
47 to: *mut [W], 47 to: *mut [W],
48 dreq: vals::TreqSel, 48 dreq: vals::TreqSel,
@@ -63,7 +63,7 @@ pub unsafe fn read<'a, C: Channel, W: Word>(
63/// 63///
64/// SAFETY: Slice must point to a valid location reachable by DMA. 64/// SAFETY: Slice must point to a valid location reachable by DMA.
65pub unsafe fn write<'a, C: Channel, W: Word>( 65pub unsafe fn write<'a, C: Channel, W: Word>(
66 ch: impl Peripheral<P = C> + 'a, 66 ch: Peri<'a, C>,
67 from: *const [W], 67 from: *const [W],
68 to: *mut W, 68 to: *mut W,
69 dreq: vals::TreqSel, 69 dreq: vals::TreqSel,
@@ -87,7 +87,7 @@ static mut DUMMY: u32 = 0;
87/// 87///
88/// SAFETY: Slice must point to a valid location reachable by DMA. 88/// SAFETY: Slice must point to a valid location reachable by DMA.
89pub unsafe fn write_repeated<'a, C: Channel, W: Word>( 89pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
90 ch: impl Peripheral<P = C> + 'a, 90 ch: Peri<'a, C>,
91 to: *mut W, 91 to: *mut W,
92 len: usize, 92 len: usize,
93 dreq: vals::TreqSel, 93 dreq: vals::TreqSel,
@@ -107,11 +107,7 @@ pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
107/// DMA copy between slices. 107/// DMA copy between slices.
108/// 108///
109/// SAFETY: Slices must point to locations reachable by DMA. 109/// SAFETY: Slices must point to locations reachable by DMA.
110pub unsafe fn copy<'a, C: Channel, W: Word>( 110pub unsafe fn copy<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: &[W], to: &mut [W]) -> Transfer<'a, C> {
111 ch: impl Peripheral<P = C> + 'a,
112 from: &[W],
113 to: &mut [W],
114) -> Transfer<'a, C> {
115 let from_len = from.len(); 111 let from_len = from.len();
116 let to_len = to.len(); 112 let to_len = to.len();
117 assert_eq!(from_len, to_len); 113 assert_eq!(from_len, to_len);
@@ -128,7 +124,7 @@ pub unsafe fn copy<'a, C: Channel, W: Word>(
128} 124}
129 125
130fn copy_inner<'a, C: Channel>( 126fn copy_inner<'a, C: Channel>(
131 ch: impl Peripheral<P = C> + 'a, 127 ch: Peri<'a, C>,
132 from: *const u32, 128 from: *const u32,
133 to: *mut u32, 129 to: *mut u32,
134 len: usize, 130 len: usize,
@@ -137,8 +133,6 @@ fn copy_inner<'a, C: Channel>(
137 incr_write: bool, 133 incr_write: bool,
138 dreq: vals::TreqSel, 134 dreq: vals::TreqSel,
139) -> Transfer<'a, C> { 135) -> Transfer<'a, C> {
140 into_ref!(ch);
141
142 let p = ch.regs(); 136 let p = ch.regs();
143 137
144 p.read_addr().write_value(from as u32); 138 p.read_addr().write_value(from as u32);
@@ -171,13 +165,11 @@ fn copy_inner<'a, C: Channel>(
171/// DMA transfer driver. 165/// DMA transfer driver.
172#[must_use = "futures do nothing unless you `.await` or poll them"] 166#[must_use = "futures do nothing unless you `.await` or poll them"]
173pub struct Transfer<'a, C: Channel> { 167pub struct Transfer<'a, C: Channel> {
174 channel: PeripheralRef<'a, C>, 168 channel: Peri<'a, C>,
175} 169}
176 170
177impl<'a, C: Channel> Transfer<'a, C> { 171impl<'a, C: Channel> Transfer<'a, C> {
178 pub(crate) fn new(channel: impl Peripheral<P = C> + 'a) -> Self { 172 pub(crate) fn new(channel: Peri<'a, C>) -> Self {
179 into_ref!(channel);
180
181 Self { channel } 173 Self { channel }
182 } 174 }
183} 175}
@@ -219,7 +211,7 @@ trait SealedWord {}
219 211
220/// DMA channel interface. 212/// DMA channel interface.
221#[allow(private_bounds)] 213#[allow(private_bounds)]
222pub trait Channel: Peripheral<P = Self> + SealedChannel + Into<AnyChannel> + Sized + 'static { 214pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static {
223 /// Channel number. 215 /// Channel number.
224 fn number(&self) -> u8; 216 fn number(&self) -> u8;
225 217
@@ -227,11 +219,6 @@ pub trait Channel: Peripheral<P = Self> + SealedChannel + Into<AnyChannel> + Siz
227 fn regs(&self) -> pac::dma::Channel { 219 fn regs(&self) -> pac::dma::Channel {
228 pac::DMA.ch(self.number() as _) 220 pac::DMA.ch(self.number() as _)
229 } 221 }
230
231 /// Convert into type-erased [AnyChannel].
232 fn degrade(self) -> AnyChannel {
233 AnyChannel { number: self.number() }
234 }
235} 222}
236 223
237/// DMA word. 224/// DMA word.
@@ -287,7 +274,7 @@ macro_rules! channel {
287 274
288 impl From<peripherals::$name> for crate::dma::AnyChannel { 275 impl From<peripherals::$name> for crate::dma::AnyChannel {
289 fn from(val: peripherals::$name) -> Self { 276 fn from(val: peripherals::$name) -> Self {
290 crate::dma::Channel::degrade(val) 277 Self { number: val.number() }
291 } 278 }
292 } 279 }
293 }; 280 };
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs
index fbc8b35ec..b30cbdd36 100644
--- a/embassy-rp/src/flash.rs
+++ b/embassy-rp/src/flash.rs
@@ -4,7 +4,7 @@ use core::marker::PhantomData;
4use core::pin::Pin; 4use core::pin::Pin;
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 7use embassy_hal_internal::{Peri, PeripheralType};
8use embedded_storage::nor_flash::{ 8use embedded_storage::nor_flash::{
9 check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, 9 check_erase, check_read, check_write, ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind,
10 ReadNorFlash, 10 ReadNorFlash,
@@ -114,7 +114,7 @@ impl<'a, 'd, T: Instance, const FLASH_SIZE: usize> Drop for BackgroundRead<'a, '
114 114
115/// Flash driver. 115/// Flash driver.
116pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> { 116pub struct Flash<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> {
117 dma: Option<PeripheralRef<'d, AnyChannel>>, 117 dma: Option<Peri<'d, AnyChannel>>,
118 phantom: PhantomData<(&'d mut T, M)>, 118 phantom: PhantomData<(&'d mut T, M)>,
119} 119}
120 120
@@ -253,7 +253,7 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> Flash<'d, T, M, FLASH_SI
253 253
254impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> { 254impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE> {
255 /// Create a new flash driver in blocking mode. 255 /// Create a new flash driver in blocking mode.
256 pub fn new_blocking(_flash: impl Peripheral<P = T> + 'd) -> Self { 256 pub fn new_blocking(_flash: Peri<'d, T>) -> Self {
257 Self { 257 Self {
258 dma: None, 258 dma: None,
259 phantom: PhantomData, 259 phantom: PhantomData,
@@ -263,10 +263,9 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Blocking, FLASH_SIZE
263 263
264impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> { 264impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
265 /// Create a new flash driver in async mode. 265 /// Create a new flash driver in async mode.
266 pub fn new(_flash: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = impl Channel> + 'd) -> Self { 266 pub fn new(_flash: Peri<'d, T>, dma: Peri<'d, impl Channel>) -> Self {
267 into_ref!(dma);
268 Self { 267 Self {
269 dma: Some(dma.map_into()), 268 dma: Some(dma.into()),
270 phantom: PhantomData, 269 phantom: PhantomData,
271 } 270 }
272 } 271 }
@@ -316,7 +315,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, Async, FLASH_SIZE> {
316 const XIP_AUX_BASE: *const u32 = 0x50500000 as *const _; 315 const XIP_AUX_BASE: *const u32 = 0x50500000 as *const _;
317 let transfer = unsafe { 316 let transfer = unsafe {
318 crate::dma::read( 317 crate::dma::read(
319 self.dma.as_mut().unwrap(), 318 self.dma.as_mut().unwrap().reborrow(),
320 XIP_AUX_BASE, 319 XIP_AUX_BASE,
321 data, 320 data,
322 pac::dma::vals::TreqSel::XIP_STREAM, 321 pac::dma::vals::TreqSel::XIP_STREAM,
@@ -965,7 +964,7 @@ trait SealedMode {}
965 964
966/// Flash instance. 965/// Flash instance.
967#[allow(private_bounds)] 966#[allow(private_bounds)]
968pub trait Instance: SealedInstance {} 967pub trait Instance: SealedInstance + PeripheralType {}
969/// Flash mode. 968/// Flash mode.
970#[allow(private_bounds)] 969#[allow(private_bounds)]
971pub trait Mode: SealedMode {} 970pub trait Mode: SealedMode {}
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index 111e03356..af0837f6a 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -5,13 +5,13 @@ use core::future::Future;
5use core::pin::Pin as FuturePin; 5use core::pin::Pin as FuturePin;
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; 8use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::interrupt::InterruptExt; 11use crate::interrupt::InterruptExt;
12use crate::pac::common::{Reg, RW}; 12use crate::pac::common::{Reg, RW};
13use crate::pac::SIO; 13use crate::pac::SIO;
14use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; 14use crate::{interrupt, pac, peripherals, RegExt};
15 15
16#[cfg(any(feature = "rp2040", feature = "rp235xa"))] 16#[cfg(any(feature = "rp2040", feature = "rp235xa"))]
17pub(crate) const BANK0_PIN_COUNT: usize = 30; 17pub(crate) const BANK0_PIN_COUNT: usize = 30;
@@ -115,7 +115,7 @@ pub struct Input<'d> {
115impl<'d> Input<'d> { 115impl<'d> Input<'d> {
116 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration. 116 /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
117 #[inline] 117 #[inline]
118 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self { 118 pub fn new(pin: Peri<'d, impl Pin>, pull: Pull) -> Self {
119 let mut pin = Flex::new(pin); 119 let mut pin = Flex::new(pin);
120 pin.set_as_input(); 120 pin.set_as_input();
121 pin.set_pull(pull); 121 pin.set_pull(pull);
@@ -266,11 +266,11 @@ fn IO_IRQ_QSPI() {
266 266
267#[must_use = "futures do nothing unless you `.await` or poll them"] 267#[must_use = "futures do nothing unless you `.await` or poll them"]
268struct InputFuture<'d> { 268struct InputFuture<'d> {
269 pin: PeripheralRef<'d, AnyPin>, 269 pin: Peri<'d, AnyPin>,
270} 270}
271 271
272impl<'d> InputFuture<'d> { 272impl<'d> InputFuture<'d> {
273 fn new(pin: PeripheralRef<'d, AnyPin>, level: InterruptTrigger) -> Self { 273 fn new(pin: Peri<'d, AnyPin>, level: InterruptTrigger) -> Self {
274 let pin_group = (pin.pin() % 8) as usize; 274 let pin_group = (pin.pin() % 8) as usize;
275 // first, clear the INTR register bits. without this INTR will still 275 // first, clear the INTR register bits. without this INTR will still
276 // contain reports of previous edges, causing the IRQ to fire early 276 // contain reports of previous edges, causing the IRQ to fire early
@@ -359,7 +359,7 @@ pub struct Output<'d> {
359impl<'d> Output<'d> { 359impl<'d> Output<'d> {
360 /// Create GPIO output driver for a [Pin] with the provided [Level]. 360 /// Create GPIO output driver for a [Pin] with the provided [Level].
361 #[inline] 361 #[inline]
362 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { 362 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
363 let mut pin = Flex::new(pin); 363 let mut pin = Flex::new(pin);
364 match initial_output { 364 match initial_output {
365 Level::High => pin.set_high(), 365 Level::High => pin.set_high(),
@@ -440,7 +440,7 @@ pub struct OutputOpenDrain<'d> {
440impl<'d> OutputOpenDrain<'d> { 440impl<'d> OutputOpenDrain<'d> {
441 /// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level]. 441 /// Create GPIO output driver for a [Pin] in open drain mode with the provided [Level].
442 #[inline] 442 #[inline]
443 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level) -> Self { 443 pub fn new(pin: Peri<'d, impl Pin>, initial_output: Level) -> Self {
444 let mut pin = Flex::new(pin); 444 let mut pin = Flex::new(pin);
445 pin.set_low(); 445 pin.set_low();
446 match initial_output { 446 match initial_output {
@@ -581,7 +581,7 @@ impl<'d> OutputOpenDrain<'d> {
581/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output 581/// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
582/// mode. 582/// mode.
583pub struct Flex<'d> { 583pub struct Flex<'d> {
584 pin: PeripheralRef<'d, AnyPin>, 584 pin: Peri<'d, AnyPin>,
585} 585}
586 586
587impl<'d> Flex<'d> { 587impl<'d> Flex<'d> {
@@ -590,9 +590,7 @@ impl<'d> Flex<'d> {
590 /// The pin remains disconnected. The initial output level is unspecified, but can be changed 590 /// The pin remains disconnected. The initial output level is unspecified, but can be changed
591 /// before the pin is put into output mode. 591 /// before the pin is put into output mode.
592 #[inline] 592 #[inline]
593 pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self { 593 pub fn new(pin: Peri<'d, impl Pin>) -> Self {
594 into_ref!(pin);
595
596 pin.pad_ctrl().write(|w| { 594 pin.pad_ctrl().write(|w| {
597 #[cfg(feature = "_rp235x")] 595 #[cfg(feature = "_rp235x")]
598 w.set_iso(false); 596 w.set_iso(false);
@@ -606,7 +604,7 @@ impl<'d> Flex<'d> {
606 w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIOB_PROC_0 as _); 604 w.set_funcsel(pac::io::vals::Gpio0ctrlFuncsel::SIOB_PROC_0 as _);
607 }); 605 });
608 606
609 Self { pin: pin.map_into() } 607 Self { pin: pin.into() }
610 } 608 }
611 609
612 #[inline] 610 #[inline]
@@ -829,7 +827,7 @@ impl<'d> Drop for Flex<'d> {
829 827
830/// Dormant wake driver. 828/// Dormant wake driver.
831pub struct DormantWake<'w> { 829pub struct DormantWake<'w> {
832 pin: PeripheralRef<'w, AnyPin>, 830 pin: Peri<'w, AnyPin>,
833 cfg: DormantWakeConfig, 831 cfg: DormantWakeConfig,
834} 832}
835 833
@@ -919,14 +917,7 @@ pub(crate) trait SealedPin: Sized {
919 917
920/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin]. 918/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
921#[allow(private_bounds)] 919#[allow(private_bounds)]
922pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static { 920pub trait Pin: PeripheralType + Into<AnyPin> + SealedPin + Sized + 'static {
923 /// Degrade to a generic pin struct
924 fn degrade(self) -> AnyPin {
925 AnyPin {
926 pin_bank: self.pin_bank(),
927 }
928 }
929
930 /// Returns the pin number within a bank 921 /// Returns the pin number within a bank
931 #[inline] 922 #[inline]
932 fn pin(&self) -> u8 { 923 fn pin(&self) -> u8 {
@@ -951,8 +942,8 @@ impl AnyPin {
951 /// # Safety 942 /// # Safety
952 /// 943 ///
953 /// You must ensure that you’re only using one instance of this type at a time. 944 /// You must ensure that you’re only using one instance of this type at a time.
954 pub unsafe fn steal(pin_bank: u8) -> Self { 945 pub unsafe fn steal(pin_bank: u8) -> Peri<'static, Self> {
955 Self { pin_bank } 946 Peri::new_unchecked(Self { pin_bank })
956 } 947 }
957} 948}
958 949
@@ -979,7 +970,9 @@ macro_rules! impl_pin {
979 970
980 impl From<peripherals::$name> for crate::gpio::AnyPin { 971 impl From<peripherals::$name> for crate::gpio::AnyPin {
981 fn from(val: peripherals::$name) -> Self { 972 fn from(val: peripherals::$name) -> Self {
982 crate::gpio::Pin::degrade(val) 973 Self {
974 pin_bank: val.pin_bank(),
975 }
983 } 976 }
984 } 977 }
985 }; 978 };
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs
index 3a2ee666c..adc38b73d 100644
--- a/embassy-rp/src/i2c.rs
+++ b/embassy-rp/src/i2c.rs
@@ -5,13 +5,13 @@ use core::future;
5use core::marker::PhantomData; 5use core::marker::PhantomData;
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::{into_ref, PeripheralRef}; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use pac::i2c; 10use pac::i2c;
11 11
12use crate::gpio::AnyPin; 12use crate::gpio::AnyPin;
13use crate::interrupt::typelevel::{Binding, Interrupt}; 13use crate::interrupt::typelevel::{Binding, Interrupt};
14use crate::{interrupt, pac, peripherals, Peripheral}; 14use crate::{interrupt, pac, peripherals};
15 15
16/// I2C error abort reason 16/// I2C error abort reason
17#[derive(Debug, PartialEq, Eq, Clone, Copy)] 17#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -83,28 +83,25 @@ pub struct I2c<'d, T: Instance, M: Mode> {
83impl<'d, T: Instance> I2c<'d, T, Blocking> { 83impl<'d, T: Instance> I2c<'d, T, Blocking> {
84 /// Create a new driver instance in blocking mode. 84 /// Create a new driver instance in blocking mode.
85 pub fn new_blocking( 85 pub fn new_blocking(
86 peri: impl Peripheral<P = T> + 'd, 86 peri: Peri<'d, T>,
87 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 87 scl: Peri<'d, impl SclPin<T>>,
88 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 88 sda: Peri<'d, impl SdaPin<T>>,
89 config: Config, 89 config: Config,
90 ) -> Self { 90 ) -> Self {
91 into_ref!(scl, sda); 91 Self::new_inner(peri, scl.into(), sda.into(), config)
92 Self::new_inner(peri, scl.map_into(), sda.map_into(), config)
93 } 92 }
94} 93}
95 94
96impl<'d, T: Instance> I2c<'d, T, Async> { 95impl<'d, T: Instance> I2c<'d, T, Async> {
97 /// Create a new driver instance in async mode. 96 /// Create a new driver instance in async mode.
98 pub fn new_async( 97 pub fn new_async(
99 peri: impl Peripheral<P = T> + 'd, 98 peri: Peri<'d, T>,
100 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 99 scl: Peri<'d, impl SclPin<T>>,
101 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 100 sda: Peri<'d, impl SdaPin<T>>,
102 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 101 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
103 config: Config, 102 config: Config,
104 ) -> Self { 103 ) -> Self {
105 into_ref!(scl, sda); 104 let i2c = Self::new_inner(peri, scl.into(), sda.into(), config);
106
107 let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config);
108 105
109 let r = T::regs(); 106 let r = T::regs();
110 107
@@ -378,14 +375,7 @@ where
378} 375}
379 376
380impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { 377impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
381 fn new_inner( 378 fn new_inner(_peri: Peri<'d, T>, scl: Peri<'d, AnyPin>, sda: Peri<'d, AnyPin>, config: Config) -> Self {
382 _peri: impl Peripheral<P = T> + 'd,
383 scl: PeripheralRef<'d, AnyPin>,
384 sda: PeripheralRef<'d, AnyPin>,
385 config: Config,
386 ) -> Self {
387 into_ref!(_peri);
388
389 let reset = T::reset(); 379 let reset = T::reset();
390 crate::reset::reset(reset); 380 crate::reset::reset(reset);
391 crate::reset::unreset_wait(reset); 381 crate::reset::unreset_wait(reset);
@@ -804,7 +794,7 @@ impl_mode!(Async);
804 794
805/// I2C instance. 795/// I2C instance.
806#[allow(private_bounds)] 796#[allow(private_bounds)]
807pub trait Instance: SealedInstance { 797pub trait Instance: SealedInstance + PeripheralType {
808 /// Interrupt for this peripheral. 798 /// Interrupt for this peripheral.
809 type Interrupt: interrupt::typelevel::Interrupt; 799 type Interrupt: interrupt::typelevel::Interrupt;
810} 800}
diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs
index d17b11d14..d420030d8 100644
--- a/embassy-rp/src/i2c_slave.rs
+++ b/embassy-rp/src/i2c_slave.rs
@@ -3,12 +3,11 @@ use core::future;
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_internal::into_ref;
7use pac::i2c; 6use pac::i2c;
8 7
9use crate::i2c::{set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE}; 8use crate::i2c::{set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE};
10use crate::interrupt::typelevel::{Binding, Interrupt}; 9use crate::interrupt::typelevel::{Binding, Interrupt};
11use crate::{pac, Peripheral}; 10use crate::{pac, Peri};
12 11
13/// I2C error 12/// I2C error
14#[derive(Debug, PartialEq, Eq, Clone, Copy)] 13#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -87,14 +86,12 @@ pub struct I2cSlave<'d, T: Instance> {
87impl<'d, T: Instance> I2cSlave<'d, T> { 86impl<'d, T: Instance> I2cSlave<'d, T> {
88 /// Create a new instance. 87 /// Create a new instance.
89 pub fn new( 88 pub fn new(
90 _peri: impl Peripheral<P = T> + 'd, 89 _peri: Peri<'d, T>,
91 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 90 scl: Peri<'d, impl SclPin<T>>,
92 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 91 sda: Peri<'d, impl SdaPin<T>>,
93 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 92 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
94 config: Config, 93 config: Config,
95 ) -> Self { 94 ) -> Self {
96 into_ref!(_peri, scl, sda);
97
98 assert!(config.addr != 0); 95 assert!(config.addr != 0);
99 96
100 // Configure SCL & SDA pins 97 // Configure SCL & SDA pins
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index de60af890..35099d07b 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -54,7 +54,7 @@ pub mod pio;
54pub(crate) mod relocate; 54pub(crate) mod relocate;
55 55
56// Reexports 56// Reexports
57pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 57pub use embassy_hal_internal::{Peri, PeripheralType};
58#[cfg(feature = "unstable-pac")] 58#[cfg(feature = "unstable-pac")]
59pub use rp_pac as pac; 59pub use rp_pac as pac;
60#[cfg(not(feature = "unstable-pac"))] 60#[cfg(not(feature = "unstable-pac"))]
diff --git a/embassy-rp/src/multicore.rs b/embassy-rp/src/multicore.rs
index 1450505b9..d10b6837c 100644
--- a/embassy-rp/src/multicore.rs
+++ b/embassy-rp/src/multicore.rs
@@ -51,7 +51,7 @@ use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
51 51
52use crate::interrupt::InterruptExt; 52use crate::interrupt::InterruptExt;
53use crate::peripherals::CORE1; 53use crate::peripherals::CORE1;
54use crate::{gpio, install_stack_guard, interrupt, pac}; 54use crate::{gpio, install_stack_guard, interrupt, pac, Peri};
55 55
56const PAUSE_TOKEN: u32 = 0xDEADBEEF; 56const PAUSE_TOKEN: u32 = 0xDEADBEEF;
57const RESUME_TOKEN: u32 = !0xDEADBEEF; 57const RESUME_TOKEN: u32 = !0xDEADBEEF;
@@ -139,7 +139,7 @@ unsafe fn SIO_IRQ_FIFO() {
139} 139}
140 140
141/// Spawn a function on this core 141/// Spawn a function on this core
142pub fn spawn_core1<F, const SIZE: usize>(_core1: CORE1, stack: &'static mut Stack<SIZE>, entry: F) 142pub fn spawn_core1<F, const SIZE: usize>(_core1: Peri<'static, CORE1>, stack: &'static mut Stack<SIZE>, entry: F)
143where 143where
144 F: FnOnce() -> bad::Never + Send + 'static, 144 F: FnOnce() -> bad::Never + Send + 'static,
145{ 145{
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs
index fd09d4bba..ec698d99c 100644
--- a/embassy-rp/src/pio/mod.rs
+++ b/embassy-rp/src/pio/mod.rs
@@ -6,7 +6,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use atomic_polyfill::{AtomicU64, AtomicU8}; 8use atomic_polyfill::{AtomicU64, AtomicU8};
9use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 9use embassy_hal_internal::{Peri, PeripheralType};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11use fixed::types::extra::U8; 11use fixed::types::extra::U8;
12use fixed::FixedU32; 12use fixed::FixedU32;
@@ -235,7 +235,7 @@ impl<'a, 'd, PIO: Instance> Drop for IrqFuture<'a, 'd, PIO> {
235 235
236/// Type representing a PIO pin. 236/// Type representing a PIO pin.
237pub struct Pin<'l, PIO: Instance> { 237pub struct Pin<'l, PIO: Instance> {
238 pin: PeripheralRef<'l, AnyPin>, 238 pin: Peri<'l, AnyPin>,
239 pio: PhantomData<PIO>, 239 pio: PhantomData<PIO>,
240} 240}
241 241
@@ -360,7 +360,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
360 /// Prepare DMA transfer from RX FIFO. 360 /// Prepare DMA transfer from RX FIFO.
361 pub fn dma_pull<'a, C: Channel, W: Word>( 361 pub fn dma_pull<'a, C: Channel, W: Word>(
362 &'a mut self, 362 &'a mut self,
363 ch: PeripheralRef<'a, C>, 363 ch: Peri<'a, C>,
364 data: &'a mut [W], 364 data: &'a mut [W],
365 bswap: bool, 365 bswap: bool,
366 ) -> Transfer<'a, C> { 366 ) -> Transfer<'a, C> {
@@ -451,7 +451,7 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineTx<'d, PIO, SM> {
451 /// Prepare a DMA transfer to TX FIFO. 451 /// Prepare a DMA transfer to TX FIFO.
452 pub fn dma_push<'a, C: Channel, W: Word>( 452 pub fn dma_push<'a, C: Channel, W: Word>(
453 &'a mut self, 453 &'a mut self,
454 ch: PeripheralRef<'a, C>, 454 ch: Peri<'a, C>,
455 data: &'a [W], 455 data: &'a [W],
456 bswap: bool, 456 bswap: bool,
457 ) -> Transfer<'a, C> { 457 ) -> Transfer<'a, C> {
@@ -1147,9 +1147,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
1147 /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`Common`] *and* 1147 /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`Common`] *and*
1148 /// all [`StateMachine`]s for this block have been dropped. **Other members 1148 /// all [`StateMachine`]s for this block have been dropped. **Other members
1149 /// of [`Pio`] do not keep pin registrations alive.** 1149 /// of [`Pio`] do not keep pin registrations alive.**
1150 pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> { 1150 pub fn make_pio_pin(&mut self, pin: Peri<'d, impl PioPin + 'd>) -> Pin<'d, PIO> {
1151 into_ref!(pin);
1152
1153 // enable the outputs 1151 // enable the outputs
1154 pin.pad_ctrl().write(|w| w.set_od(false)); 1152 pin.pad_ctrl().write(|w| w.set_od(false));
1155 // especially important on the 235x, where IE defaults to 0 1153 // especially important on the 235x, where IE defaults to 0
@@ -1171,7 +1169,7 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
1171 // we can be relaxed about this because we're &mut here and nothing is cached 1169 // we can be relaxed about this because we're &mut here and nothing is cached
1172 PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed); 1170 PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed);
1173 Pin { 1171 Pin {
1174 pin: pin.into_ref().map_into(), 1172 pin: pin.into(),
1175 pio: PhantomData::default(), 1173 pio: PhantomData::default(),
1176 } 1174 }
1177 } 1175 }
@@ -1304,7 +1302,7 @@ pub struct Pio<'d, PIO: Instance> {
1304 1302
1305impl<'d, PIO: Instance> Pio<'d, PIO> { 1303impl<'d, PIO: Instance> Pio<'d, PIO> {
1306 /// Create a new instance of a PIO peripheral. 1304 /// Create a new instance of a PIO peripheral.
1307 pub fn new(_pio: impl Peripheral<P = PIO> + 'd, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self { 1305 pub fn new(_pio: Peri<'d, PIO>, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self {
1308 PIO::state().users.store(5, Ordering::Release); 1306 PIO::state().users.store(5, Ordering::Release);
1309 PIO::state().used_pins.store(0, Ordering::Release); 1307 PIO::state().used_pins.store(0, Ordering::Release);
1310 PIO::Interrupt::unpend(); 1308 PIO::Interrupt::unpend();
@@ -1389,7 +1387,7 @@ trait SealedInstance {
1389 1387
1390/// PIO instance. 1388/// PIO instance.
1391#[allow(private_bounds)] 1389#[allow(private_bounds)]
1392pub trait Instance: SealedInstance + Sized + Unpin { 1390pub trait Instance: SealedInstance + PeripheralType + Sized + Unpin {
1393 /// Interrupt for this peripheral. 1391 /// Interrupt for this peripheral.
1394 type Interrupt: crate::interrupt::typelevel::Interrupt; 1392 type Interrupt: crate::interrupt::typelevel::Interrupt;
1395} 1393}
diff --git a/embassy-rp/src/pio_programs/hd44780.rs b/embassy-rp/src/pio_programs/hd44780.rs
index 6997b91f3..5846a8027 100644
--- a/embassy-rp/src/pio_programs/hd44780.rs
+++ b/embassy-rp/src/pio_programs/hd44780.rs
@@ -5,7 +5,7 @@ use crate::pio::{
5 Common, Config, Direction, FifoJoin, Instance, Irq, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, 5 Common, Config, Direction, FifoJoin, Instance, Irq, LoadedProgram, PioPin, ShiftConfig, ShiftDirection,
6 StateMachine, 6 StateMachine,
7}; 7};
8use crate::{into_ref, Peripheral, PeripheralRef}; 8use crate::Peri;
9 9
10/// This struct represents a HD44780 program that takes command words (<wait:24> <command:4> <0:4>) 10/// This struct represents a HD44780 program that takes command words (<wait:24> <command:4> <0:4>)
11pub struct PioHD44780CommandWordProgram<'a, PIO: Instance> { 11pub struct PioHD44780CommandWordProgram<'a, PIO: Instance> {
@@ -99,7 +99,7 @@ impl<'a, PIO: Instance> PioHD44780CommandSequenceProgram<'a, PIO> {
99 99
100/// Pio backed HD44780 driver 100/// Pio backed HD44780 driver
101pub struct PioHD44780<'l, P: Instance, const S: usize> { 101pub struct PioHD44780<'l, P: Instance, const S: usize> {
102 dma: PeripheralRef<'l, AnyChannel>, 102 dma: Peri<'l, AnyChannel>,
103 sm: StateMachine<'l, P, S>, 103 sm: StateMachine<'l, P, S>,
104 104
105 buf: [u8; 40], 105 buf: [u8; 40],
@@ -111,19 +111,17 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
111 common: &mut Common<'l, P>, 111 common: &mut Common<'l, P>,
112 mut sm: StateMachine<'l, P, S>, 112 mut sm: StateMachine<'l, P, S>,
113 mut irq: Irq<'l, P, S>, 113 mut irq: Irq<'l, P, S>,
114 dma: impl Peripheral<P = impl Channel> + 'l, 114 mut dma: Peri<'l, impl Channel>,
115 rs: impl PioPin, 115 rs: Peri<'l, impl PioPin>,
116 rw: impl PioPin, 116 rw: Peri<'l, impl PioPin>,
117 e: impl PioPin, 117 e: Peri<'l, impl PioPin>,
118 db4: impl PioPin, 118 db4: Peri<'l, impl PioPin>,
119 db5: impl PioPin, 119 db5: Peri<'l, impl PioPin>,
120 db6: impl PioPin, 120 db6: Peri<'l, impl PioPin>,
121 db7: impl PioPin, 121 db7: Peri<'l, impl PioPin>,
122 word_prg: &PioHD44780CommandWordProgram<'l, P>, 122 word_prg: &PioHD44780CommandWordProgram<'l, P>,
123 seq_prg: &PioHD44780CommandSequenceProgram<'l, P>, 123 seq_prg: &PioHD44780CommandSequenceProgram<'l, P>,
124 ) -> PioHD44780<'l, P, S> { 124 ) -> PioHD44780<'l, P, S> {
125 into_ref!(dma);
126
127 let rs = common.make_pio_pin(rs); 125 let rs = common.make_pio_pin(rs);
128 let rw = common.make_pio_pin(rw); 126 let rw = common.make_pio_pin(rw);
129 let e = common.make_pio_pin(e); 127 let e = common.make_pio_pin(e);
@@ -176,7 +174,7 @@ impl<'l, P: Instance, const S: usize> PioHD44780<'l, P, S> {
176 sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1], false).await; 174 sm.tx().dma_push(dma.reborrow(), &[0x81u8, 0x0f, 1], false).await;
177 175
178 Self { 176 Self {
179 dma: dma.map_into(), 177 dma: dma.into(),
180 sm, 178 sm,
181 buf: [0x20; 40], 179 buf: [0x20; 40],
182 } 180 }
diff --git a/embassy-rp/src/pio_programs/i2s.rs b/embassy-rp/src/pio_programs/i2s.rs
index 17e321405..b967f0160 100644
--- a/embassy-rp/src/pio_programs/i2s.rs
+++ b/embassy-rp/src/pio_programs/i2s.rs
@@ -6,16 +6,16 @@ use crate::dma::{AnyChannel, Channel, Transfer};
6use crate::pio::{ 6use crate::pio::{
7 Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, 7 Common, Config, Direction, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine,
8}; 8};
9use crate::{into_ref, Peripheral, PeripheralRef}; 9use crate::Peri;
10 10
11/// This struct represents an i2s output driver program 11/// This struct represents an i2s output driver program
12pub struct PioI2sOutProgram<'a, PIO: Instance> { 12pub struct PioI2sOutProgram<'d, PIO: Instance> {
13 prg: LoadedProgram<'a, PIO>, 13 prg: LoadedProgram<'d, PIO>,
14} 14}
15 15
16impl<'a, PIO: Instance> PioI2sOutProgram<'a, PIO> { 16impl<'d, PIO: Instance> PioI2sOutProgram<'d, PIO> {
17 /// Load the program into the given pio 17 /// Load the program into the given pio
18 pub fn new(common: &mut Common<'a, PIO>) -> Self { 18 pub fn new(common: &mut Common<'d, PIO>) -> Self {
19 let prg = pio::pio_asm!( 19 let prg = pio::pio_asm!(
20 ".side_set 2", 20 ".side_set 2",
21 " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock 21 " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock
@@ -37,27 +37,25 @@ impl<'a, PIO: Instance> PioI2sOutProgram<'a, PIO> {
37} 37}
38 38
39/// Pio backed I2s output driver 39/// Pio backed I2s output driver
40pub struct PioI2sOut<'a, P: Instance, const S: usize> { 40pub struct PioI2sOut<'d, P: Instance, const S: usize> {
41 dma: PeripheralRef<'a, AnyChannel>, 41 dma: Peri<'d, AnyChannel>,
42 sm: StateMachine<'a, P, S>, 42 sm: StateMachine<'d, P, S>,
43} 43}
44 44
45impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> { 45impl<'d, P: Instance, const S: usize> PioI2sOut<'d, P, S> {
46 /// Configure a state machine to output I2s 46 /// Configure a state machine to output I2s
47 pub fn new( 47 pub fn new(
48 common: &mut Common<'a, P>, 48 common: &mut Common<'d, P>,
49 mut sm: StateMachine<'a, P, S>, 49 mut sm: StateMachine<'d, P, S>,
50 dma: impl Peripheral<P = impl Channel> + 'a, 50 dma: Peri<'d, impl Channel>,
51 data_pin: impl PioPin, 51 data_pin: Peri<'d, impl PioPin>,
52 bit_clock_pin: impl PioPin, 52 bit_clock_pin: Peri<'d, impl PioPin>,
53 lr_clock_pin: impl PioPin, 53 lr_clock_pin: Peri<'d, impl PioPin>,
54 sample_rate: u32, 54 sample_rate: u32,
55 bit_depth: u32, 55 bit_depth: u32,
56 channels: u32, 56 channels: u32,
57 program: &PioI2sOutProgram<'a, P>, 57 program: &PioI2sOutProgram<'d, P>,
58 ) -> Self { 58 ) -> Self {
59 into_ref!(dma);
60
61 let data_pin = common.make_pio_pin(data_pin); 59 let data_pin = common.make_pio_pin(data_pin);
62 let bit_clock_pin = common.make_pio_pin(bit_clock_pin); 60 let bit_clock_pin = common.make_pio_pin(bit_clock_pin);
63 let left_right_clock_pin = common.make_pio_pin(lr_clock_pin); 61 let left_right_clock_pin = common.make_pio_pin(lr_clock_pin);
@@ -82,10 +80,7 @@ impl<'a, P: Instance, const S: usize> PioI2sOut<'a, P, S> {
82 80
83 sm.set_enable(true); 81 sm.set_enable(true);
84 82
85 Self { 83 Self { dma: dma.into(), sm }
86 dma: dma.map_into(),
87 sm,
88 }
89 } 84 }
90 85
91 /// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer. 86 /// Return an in-prograss dma transfer future. Awaiting it will guarentee a complete transfer.
diff --git a/embassy-rp/src/pio_programs/onewire.rs b/embassy-rp/src/pio_programs/onewire.rs
index 040333e76..00783aab0 100644
--- a/embassy-rp/src/pio_programs/onewire.rs
+++ b/embassy-rp/src/pio_programs/onewire.rs
@@ -1,6 +1,7 @@
1//! OneWire pio driver 1//! OneWire pio driver
2 2
3use crate::pio::{Common, Config, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine}; 3use crate::pio::{Common, Config, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine};
4use crate::Peri;
4 5
5/// This struct represents an onewire driver program 6/// This struct represents an onewire driver program
6pub struct PioOneWireProgram<'a, PIO: Instance> { 7pub struct PioOneWireProgram<'a, PIO: Instance> {
@@ -69,7 +70,7 @@ impl<'d, PIO: Instance, const SM: usize> PioOneWire<'d, PIO, SM> {
69 pub fn new( 70 pub fn new(
70 common: &mut Common<'d, PIO>, 71 common: &mut Common<'d, PIO>,
71 mut sm: StateMachine<'d, PIO, SM>, 72 mut sm: StateMachine<'d, PIO, SM>,
72 pin: impl PioPin, 73 pin: Peri<'d, impl PioPin>,
73 program: &PioOneWireProgram<'d, PIO>, 74 program: &PioOneWireProgram<'d, PIO>,
74 ) -> Self { 75 ) -> Self {
75 let pin = common.make_pio_pin(pin); 76 let pin = common.make_pio_pin(pin);
diff --git a/embassy-rp/src/pio_programs/pwm.rs b/embassy-rp/src/pio_programs/pwm.rs
index 01ffe012a..f0f837bc5 100644
--- a/embassy-rp/src/pio_programs/pwm.rs
+++ b/embassy-rp/src/pio_programs/pwm.rs
@@ -4,9 +4,9 @@ use core::time::Duration;
4 4
5use pio::InstructionOperands; 5use pio::InstructionOperands;
6 6
7use crate::clocks;
8use crate::gpio::Level; 7use crate::gpio::Level;
9use crate::pio::{Common, Config, Direction, Instance, LoadedProgram, Pin, PioPin, StateMachine}; 8use crate::pio::{Common, Config, Direction, Instance, LoadedProgram, Pin, PioPin, StateMachine};
9use crate::{clocks, Peri};
10 10
11/// This converts the duration provided into the number of cycles the PIO needs to run to make it take the same time 11/// This converts the duration provided into the number of cycles the PIO needs to run to make it take the same time
12fn to_pio_cycles(duration: Duration) -> u32 { 12fn to_pio_cycles(duration: Duration) -> u32 {
@@ -52,7 +52,7 @@ impl<'d, T: Instance, const SM: usize> PioPwm<'d, T, SM> {
52 pub fn new( 52 pub fn new(
53 pio: &mut Common<'d, T>, 53 pio: &mut Common<'d, T>,
54 mut sm: StateMachine<'d, T, SM>, 54 mut sm: StateMachine<'d, T, SM>,
55 pin: impl PioPin, 55 pin: Peri<'d, impl PioPin>,
56 program: &PioPwmProgram<'d, T>, 56 program: &PioPwmProgram<'d, T>,
57 ) -> Self { 57 ) -> Self {
58 let pin = pio.make_pio_pin(pin); 58 let pin = pio.make_pio_pin(pin);
diff --git a/embassy-rp/src/pio_programs/rotary_encoder.rs b/embassy-rp/src/pio_programs/rotary_encoder.rs
index f2fb02aca..e520da8a3 100644
--- a/embassy-rp/src/pio_programs/rotary_encoder.rs
+++ b/embassy-rp/src/pio_programs/rotary_encoder.rs
@@ -6,6 +6,7 @@ use crate::gpio::Pull;
6use crate::pio::{ 6use crate::pio::{
7 Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, 7 Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine,
8}; 8};
9use crate::Peri;
9 10
10/// This struct represents an Encoder program loaded into pio instruction memory. 11/// This struct represents an Encoder program loaded into pio instruction memory.
11pub struct PioEncoderProgram<'a, PIO: Instance> { 12pub struct PioEncoderProgram<'a, PIO: Instance> {
@@ -33,8 +34,8 @@ impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
33 pub fn new( 34 pub fn new(
34 pio: &mut Common<'d, T>, 35 pio: &mut Common<'d, T>,
35 mut sm: StateMachine<'d, T, SM>, 36 mut sm: StateMachine<'d, T, SM>,
36 pin_a: impl PioPin, 37 pin_a: Peri<'d, impl PioPin>,
37 pin_b: impl PioPin, 38 pin_b: Peri<'d, impl PioPin>,
38 program: &PioEncoderProgram<'d, T>, 39 program: &PioEncoderProgram<'d, T>,
39 ) -> Self { 40 ) -> Self {
40 let mut pin_a = pio.make_pio_pin(pin_a); 41 let mut pin_a = pio.make_pio_pin(pin_a);
diff --git a/embassy-rp/src/pio_programs/stepper.rs b/embassy-rp/src/pio_programs/stepper.rs
index c8f74167d..495191659 100644
--- a/embassy-rp/src/pio_programs/stepper.rs
+++ b/embassy-rp/src/pio_programs/stepper.rs
@@ -7,6 +7,7 @@ use fixed::types::extra::U8;
7use fixed::FixedU32; 7use fixed::FixedU32;
8 8
9use crate::pio::{Common, Config, Direction, Instance, Irq, LoadedProgram, PioPin, StateMachine}; 9use crate::pio::{Common, Config, Direction, Instance, Irq, LoadedProgram, PioPin, StateMachine};
10use crate::Peri;
10 11
11/// This struct represents a Stepper driver program loaded into pio instruction memory. 12/// This struct represents a Stepper driver program loaded into pio instruction memory.
12pub struct PioStepperProgram<'a, PIO: Instance> { 13pub struct PioStepperProgram<'a, PIO: Instance> {
@@ -50,10 +51,10 @@ impl<'d, T: Instance, const SM: usize> PioStepper<'d, T, SM> {
50 pio: &mut Common<'d, T>, 51 pio: &mut Common<'d, T>,
51 mut sm: StateMachine<'d, T, SM>, 52 mut sm: StateMachine<'d, T, SM>,
52 irq: Irq<'d, T, SM>, 53 irq: Irq<'d, T, SM>,
53 pin0: impl PioPin, 54 pin0: Peri<'d, impl PioPin>,
54 pin1: impl PioPin, 55 pin1: Peri<'d, impl PioPin>,
55 pin2: impl PioPin, 56 pin2: Peri<'d, impl PioPin>,
56 pin3: impl PioPin, 57 pin3: Peri<'d, impl PioPin>,
57 program: &PioStepperProgram<'d, T>, 58 program: &PioStepperProgram<'d, T>,
58 ) -> Self { 59 ) -> Self {
59 let pin0 = pio.make_pio_pin(pin0); 60 let pin0 = pio.make_pio_pin(pin0);
diff --git a/embassy-rp/src/pio_programs/uart.rs b/embassy-rp/src/pio_programs/uart.rs
index 641daca61..04e39a571 100644
--- a/embassy-rp/src/pio_programs/uart.rs
+++ b/embassy-rp/src/pio_programs/uart.rs
@@ -10,15 +10,16 @@ use crate::gpio::Level;
10use crate::pio::{ 10use crate::pio::{
11 Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine, 11 Common, Config, Direction as PioDirection, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine,
12}; 12};
13use crate::Peri;
13 14
14/// This struct represents a uart tx program loaded into pio instruction memory. 15/// This struct represents a uart tx program loaded into pio instruction memory.
15pub struct PioUartTxProgram<'a, PIO: Instance> { 16pub struct PioUartTxProgram<'d, PIO: Instance> {
16 prg: LoadedProgram<'a, PIO>, 17 prg: LoadedProgram<'d, PIO>,
17} 18}
18 19
19impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> { 20impl<'d, PIO: Instance> PioUartTxProgram<'d, PIO> {
20 /// Load the uart tx program into the given pio 21 /// Load the uart tx program into the given pio
21 pub fn new(common: &mut Common<'a, PIO>) -> Self { 22 pub fn new(common: &mut Common<'d, PIO>) -> Self {
22 let prg = pio::pio_asm!( 23 let prg = pio::pio_asm!(
23 r#" 24 r#"
24 .side_set 1 opt 25 .side_set 1 opt
@@ -41,18 +42,18 @@ impl<'a, PIO: Instance> PioUartTxProgram<'a, PIO> {
41} 42}
42 43
43/// PIO backed Uart transmitter 44/// PIO backed Uart transmitter
44pub struct PioUartTx<'a, PIO: Instance, const SM: usize> { 45pub struct PioUartTx<'d, PIO: Instance, const SM: usize> {
45 sm_tx: StateMachine<'a, PIO, SM>, 46 sm_tx: StateMachine<'d, PIO, SM>,
46} 47}
47 48
48impl<'a, PIO: Instance, const SM: usize> PioUartTx<'a, PIO, SM> { 49impl<'d, PIO: Instance, const SM: usize> PioUartTx<'d, PIO, SM> {
49 /// Configure a pio state machine to use the loaded tx program. 50 /// Configure a pio state machine to use the loaded tx program.
50 pub fn new( 51 pub fn new(
51 baud: u32, 52 baud: u32,
52 common: &mut Common<'a, PIO>, 53 common: &mut Common<'d, PIO>,
53 mut sm_tx: StateMachine<'a, PIO, SM>, 54 mut sm_tx: StateMachine<'d, PIO, SM>,
54 tx_pin: impl PioPin, 55 tx_pin: Peri<'d, impl PioPin>,
55 program: &PioUartTxProgram<'a, PIO>, 56 program: &PioUartTxProgram<'d, PIO>,
56 ) -> Self { 57 ) -> Self {
57 let tx_pin = common.make_pio_pin(tx_pin); 58 let tx_pin = common.make_pio_pin(tx_pin);
58 sm_tx.set_pins(Level::High, &[&tx_pin]); 59 sm_tx.set_pins(Level::High, &[&tx_pin]);
@@ -92,13 +93,13 @@ impl<PIO: Instance, const SM: usize> Write for PioUartTx<'_, PIO, SM> {
92} 93}
93 94
94/// This struct represents a Uart Rx program loaded into pio instruction memory. 95/// This struct represents a Uart Rx program loaded into pio instruction memory.
95pub struct PioUartRxProgram<'a, PIO: Instance> { 96pub struct PioUartRxProgram<'d, PIO: Instance> {
96 prg: LoadedProgram<'a, PIO>, 97 prg: LoadedProgram<'d, PIO>,
97} 98}
98 99
99impl<'a, PIO: Instance> PioUartRxProgram<'a, PIO> { 100impl<'d, PIO: Instance> PioUartRxProgram<'d, PIO> {
100 /// Load the uart rx program into the given pio 101 /// Load the uart rx program into the given pio
101 pub fn new(common: &mut Common<'a, PIO>) -> Self { 102 pub fn new(common: &mut Common<'d, PIO>) -> Self {
102 let prg = pio::pio_asm!( 103 let prg = pio::pio_asm!(
103 r#" 104 r#"
104 ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and 105 ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
@@ -130,18 +131,18 @@ impl<'a, PIO: Instance> PioUartRxProgram<'a, PIO> {
130} 131}
131 132
132/// PIO backed Uart reciever 133/// PIO backed Uart reciever
133pub struct PioUartRx<'a, PIO: Instance, const SM: usize> { 134pub struct PioUartRx<'d, PIO: Instance, const SM: usize> {
134 sm_rx: StateMachine<'a, PIO, SM>, 135 sm_rx: StateMachine<'d, PIO, SM>,
135} 136}
136 137
137impl<'a, PIO: Instance, const SM: usize> PioUartRx<'a, PIO, SM> { 138impl<'d, PIO: Instance, const SM: usize> PioUartRx<'d, PIO, SM> {
138 /// Configure a pio state machine to use the loaded rx program. 139 /// Configure a pio state machine to use the loaded rx program.
139 pub fn new( 140 pub fn new(
140 baud: u32, 141 baud: u32,
141 common: &mut Common<'a, PIO>, 142 common: &mut Common<'d, PIO>,
142 mut sm_rx: StateMachine<'a, PIO, SM>, 143 mut sm_rx: StateMachine<'d, PIO, SM>,
143 rx_pin: impl PioPin, 144 rx_pin: Peri<'d, impl PioPin>,
144 program: &PioUartRxProgram<'a, PIO>, 145 program: &PioUartRxProgram<'d, PIO>,
145 ) -> Self { 146 ) -> Self {
146 let mut cfg = Config::default(); 147 let mut cfg = Config::default();
147 cfg.use_program(&program.prg, &[]); 148 cfg.use_program(&program.prg, &[]);
diff --git a/embassy-rp/src/pio_programs/ws2812.rs b/embassy-rp/src/pio_programs/ws2812.rs
index 2462a64e6..578937e11 100644
--- a/embassy-rp/src/pio_programs/ws2812.rs
+++ b/embassy-rp/src/pio_programs/ws2812.rs
@@ -9,7 +9,7 @@ use crate::dma::{AnyChannel, Channel};
9use crate::pio::{ 9use crate::pio::{
10 Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine, 10 Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftConfig, ShiftDirection, StateMachine,
11}; 11};
12use crate::{into_ref, Peripheral, PeripheralRef}; 12use crate::Peri;
13 13
14const T1: u8 = 2; // start bit 14const T1: u8 = 2; // start bit
15const T2: u8 = 5; // data bit 15const T2: u8 = 5; // data bit
@@ -53,7 +53,7 @@ impl<'a, PIO: Instance> PioWs2812Program<'a, PIO> {
53/// Pio backed ws2812 driver 53/// Pio backed ws2812 driver
54/// Const N is the number of ws2812 leds attached to this pin 54/// Const N is the number of ws2812 leds attached to this pin
55pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize> { 55pub struct PioWs2812<'d, P: Instance, const S: usize, const N: usize> {
56 dma: PeripheralRef<'d, AnyChannel>, 56 dma: Peri<'d, AnyChannel>,
57 sm: StateMachine<'d, P, S>, 57 sm: StateMachine<'d, P, S>,
58} 58}
59 59
@@ -62,12 +62,10 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> {
62 pub fn new( 62 pub fn new(
63 pio: &mut Common<'d, P>, 63 pio: &mut Common<'d, P>,
64 mut sm: StateMachine<'d, P, S>, 64 mut sm: StateMachine<'d, P, S>,
65 dma: impl Peripheral<P = impl Channel> + 'd, 65 dma: Peri<'d, impl Channel>,
66 pin: impl PioPin, 66 pin: Peri<'d, impl PioPin>,
67 program: &PioWs2812Program<'d, P>, 67 program: &PioWs2812Program<'d, P>,
68 ) -> Self { 68 ) -> Self {
69 into_ref!(dma);
70
71 // Setup sm0 69 // Setup sm0
72 let mut cfg = Config::default(); 70 let mut cfg = Config::default();
73 71
@@ -95,10 +93,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> PioWs2812<'d, P, S, N> {
95 sm.set_config(&cfg); 93 sm.set_config(&cfg);
96 sm.set_enable(true); 94 sm.set_enable(true);
97 95
98 Self { 96 Self { dma: dma.into(), sm }
99 dma: dma.map_into(),
100 sm,
101 }
102 } 97 }
103 98
104 /// Write a buffer of [smart_leds::RGB8] to the ws2812 string 99 /// Write a buffer of [smart_leds::RGB8] to the ws2812 string
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs
index 4fb8ade12..f631402a2 100644
--- a/embassy-rp/src/pwm.rs
+++ b/embassy-rp/src/pwm.rs
@@ -1,6 +1,6 @@
1//! Pulse Width Modulation (PWM) 1//! Pulse Width Modulation (PWM)
2 2
3use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 3use embassy_hal_internal::{Peri, PeripheralType};
4pub use embedded_hal_1::pwm::SetDutyCycle; 4pub use embedded_hal_1::pwm::SetDutyCycle;
5use embedded_hal_1::pwm::{Error, ErrorKind, ErrorType}; 5use embedded_hal_1::pwm::{Error, ErrorKind, ErrorType};
6use fixed::traits::ToFixed; 6use fixed::traits::ToFixed;
@@ -99,8 +99,8 @@ impl Error for PwmError {
99 99
100/// PWM driver. 100/// PWM driver.
101pub struct Pwm<'d> { 101pub struct Pwm<'d> {
102 pin_a: Option<PeripheralRef<'d, AnyPin>>, 102 pin_a: Option<Peri<'d, AnyPin>>,
103 pin_b: Option<PeripheralRef<'d, AnyPin>>, 103 pin_b: Option<Peri<'d, AnyPin>>,
104 slice: usize, 104 slice: usize,
105} 105}
106 106
@@ -131,8 +131,8 @@ impl<'d> SetDutyCycle for Pwm<'d> {
131impl<'d> Pwm<'d> { 131impl<'d> Pwm<'d> {
132 fn new_inner( 132 fn new_inner(
133 slice: usize, 133 slice: usize,
134 a: Option<PeripheralRef<'d, AnyPin>>, 134 a: Option<Peri<'d, AnyPin>>,
135 b: Option<PeripheralRef<'d, AnyPin>>, 135 b: Option<Peri<'d, AnyPin>>,
136 b_pull: Pull, 136 b_pull: Pull,
137 config: Config, 137 config: Config,
138 divmode: Divmode, 138 divmode: Divmode,
@@ -171,60 +171,34 @@ impl<'d> Pwm<'d> {
171 171
172 /// Create PWM driver without any configured pins. 172 /// Create PWM driver without any configured pins.
173 #[inline] 173 #[inline]
174 pub fn new_free<T: Slice>(slice: impl Peripheral<P = T> + 'd, config: Config) -> Self { 174 pub fn new_free<T: Slice>(slice: Peri<'d, T>, config: Config) -> Self {
175 into_ref!(slice);
176 Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV) 175 Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV)
177 } 176 }
178 177
179 /// Create PWM driver with a single 'a' pin as output. 178 /// Create PWM driver with a single 'a' pin as output.
180 #[inline] 179 #[inline]
181 pub fn new_output_a<T: Slice>( 180 pub fn new_output_a<T: Slice>(slice: Peri<'d, T>, a: Peri<'d, impl ChannelAPin<T>>, config: Config) -> Self {
182 slice: impl Peripheral<P = T> + 'd, 181 Self::new_inner(slice.number(), Some(a.into()), None, Pull::None, config, Divmode::DIV)
183 a: impl Peripheral<P = impl ChannelAPin<T>> + 'd,
184 config: Config,
185 ) -> Self {
186 into_ref!(slice, a);
187 Self::new_inner(
188 slice.number(),
189 Some(a.map_into()),
190 None,
191 Pull::None,
192 config,
193 Divmode::DIV,
194 )
195 } 182 }
196 183
197 /// Create PWM driver with a single 'b' pin as output. 184 /// Create PWM driver with a single 'b' pin as output.
198 #[inline] 185 #[inline]
199 pub fn new_output_b<T: Slice>( 186 pub fn new_output_b<T: Slice>(slice: Peri<'d, T>, b: Peri<'d, impl ChannelBPin<T>>, config: Config) -> Self {
200 slice: impl Peripheral<P = T> + 'd, 187 Self::new_inner(slice.number(), None, Some(b.into()), Pull::None, config, Divmode::DIV)
201 b: impl Peripheral<P = impl ChannelBPin<T>> + 'd,
202 config: Config,
203 ) -> Self {
204 into_ref!(slice, b);
205 Self::new_inner(
206 slice.number(),
207 None,
208 Some(b.map_into()),
209 Pull::None,
210 config,
211 Divmode::DIV,
212 )
213 } 188 }
214 189
215 /// Create PWM driver with a 'a' and 'b' pins as output. 190 /// Create PWM driver with a 'a' and 'b' pins as output.
216 #[inline] 191 #[inline]
217 pub fn new_output_ab<T: Slice>( 192 pub fn new_output_ab<T: Slice>(
218 slice: impl Peripheral<P = T> + 'd, 193 slice: Peri<'d, T>,
219 a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, 194 a: Peri<'d, impl ChannelAPin<T>>,
220 b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, 195 b: Peri<'d, impl ChannelBPin<T>>,
221 config: Config, 196 config: Config,
222 ) -> Self { 197 ) -> Self {
223 into_ref!(slice, a, b);
224 Self::new_inner( 198 Self::new_inner(
225 slice.number(), 199 slice.number(),
226 Some(a.map_into()), 200 Some(a.into()),
227 Some(b.map_into()), 201 Some(b.into()),
228 Pull::None, 202 Pull::None,
229 config, 203 config,
230 Divmode::DIV, 204 Divmode::DIV,
@@ -234,31 +208,29 @@ impl<'d> Pwm<'d> {
234 /// Create PWM driver with a single 'b' as input pin. 208 /// Create PWM driver with a single 'b' as input pin.
235 #[inline] 209 #[inline]
236 pub fn new_input<T: Slice>( 210 pub fn new_input<T: Slice>(
237 slice: impl Peripheral<P = T> + 'd, 211 slice: Peri<'d, T>,
238 b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, 212 b: Peri<'d, impl ChannelBPin<T>>,
239 b_pull: Pull, 213 b_pull: Pull,
240 mode: InputMode, 214 mode: InputMode,
241 config: Config, 215 config: Config,
242 ) -> Self { 216 ) -> Self {
243 into_ref!(slice, b); 217 Self::new_inner(slice.number(), None, Some(b.into()), b_pull, config, mode.into())
244 Self::new_inner(slice.number(), None, Some(b.map_into()), b_pull, config, mode.into())
245 } 218 }
246 219
247 /// Create PWM driver with a 'a' and 'b' pins in the desired input mode. 220 /// Create PWM driver with a 'a' and 'b' pins in the desired input mode.
248 #[inline] 221 #[inline]
249 pub fn new_output_input<T: Slice>( 222 pub fn new_output_input<T: Slice>(
250 slice: impl Peripheral<P = T> + 'd, 223 slice: Peri<'d, T>,
251 a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, 224 a: Peri<'d, impl ChannelAPin<T>>,
252 b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, 225 b: Peri<'d, impl ChannelBPin<T>>,
253 b_pull: Pull, 226 b_pull: Pull,
254 mode: InputMode, 227 mode: InputMode,
255 config: Config, 228 config: Config,
256 ) -> Self { 229 ) -> Self {
257 into_ref!(slice, a, b);
258 Self::new_inner( 230 Self::new_inner(
259 slice.number(), 231 slice.number(),
260 Some(a.map_into()), 232 Some(a.into()),
261 Some(b.map_into()), 233 Some(b.into()),
262 b_pull, 234 b_pull,
263 config, 235 config,
264 mode.into(), 236 mode.into(),
@@ -373,8 +345,8 @@ impl<'d> Pwm<'d> {
373} 345}
374 346
375enum PwmChannelPin<'d> { 347enum PwmChannelPin<'d> {
376 A(PeripheralRef<'d, AnyPin>), 348 A(Peri<'d, AnyPin>),
377 B(PeripheralRef<'d, AnyPin>), 349 B(Peri<'d, AnyPin>),
378} 350}
379 351
380/// Single channel of Pwm driver. 352/// Single channel of Pwm driver.
@@ -498,7 +470,7 @@ trait SealedSlice {}
498 470
499/// PWM Slice. 471/// PWM Slice.
500#[allow(private_bounds)] 472#[allow(private_bounds)]
501pub trait Slice: Peripheral<P = Self> + SealedSlice + Sized + 'static { 473pub trait Slice: PeripheralType + SealedSlice + Sized + 'static {
502 /// Slice number. 474 /// Slice number.
503 fn number(&self) -> usize; 475 fn number(&self) -> usize;
504} 476}
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs
index 2ce7ac645..63cf91d28 100644
--- a/embassy-rp/src/rtc/mod.rs
+++ b/embassy-rp/src/rtc/mod.rs
@@ -1,7 +1,7 @@
1//! RTC driver. 1//! RTC driver.
2mod filter; 2mod filter;
3 3
4use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 4use embassy_hal_internal::{Peri, PeripheralType};
5 5
6pub use self::filter::DateTimeFilter; 6pub use self::filter::DateTimeFilter;
7 7
@@ -14,7 +14,7 @@ use crate::clocks::clk_rtc_freq;
14 14
15/// A reference to the real time clock of the system 15/// A reference to the real time clock of the system
16pub struct Rtc<'d, T: Instance> { 16pub struct Rtc<'d, T: Instance> {
17 inner: PeripheralRef<'d, T>, 17 inner: Peri<'d, T>,
18} 18}
19 19
20impl<'d, T: Instance> Rtc<'d, T> { 20impl<'d, T: Instance> Rtc<'d, T> {
@@ -23,9 +23,7 @@ impl<'d, T: Instance> Rtc<'d, T> {
23 /// # Errors 23 /// # Errors
24 /// 24 ///
25 /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. 25 /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
26 pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self { 26 pub fn new(inner: Peri<'d, T>) -> Self {
27 into_ref!(inner);
28
29 // Set the RTC divider 27 // Set the RTC divider
30 inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1)); 28 inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1));
31 29
@@ -194,7 +192,7 @@ trait SealedInstance {
194 192
195/// RTC peripheral instance. 193/// RTC peripheral instance.
196#[allow(private_bounds)] 194#[allow(private_bounds)]
197pub trait Instance: SealedInstance {} 195pub trait Instance: SealedInstance + PeripheralType {}
198 196
199impl SealedInstance for crate::peripherals::RTC { 197impl SealedInstance for crate::peripherals::RTC {
200 fn regs(&self) -> crate::pac::rtc::Rtc { 198 fn regs(&self) -> crate::pac::rtc::Rtc {
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index c48b5c54f..559b3b909 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -3,12 +3,12 @@ use core::marker::PhantomData;
3 3
4use embassy_embedded_hal::SetConfig; 4use embassy_embedded_hal::SetConfig;
5use embassy_futures::join::join; 5use embassy_futures::join::join;
6use embassy_hal_internal::{into_ref, PeripheralRef}; 6use embassy_hal_internal::{Peri, PeripheralType};
7pub use embedded_hal_02::spi::{Phase, Polarity}; 7pub use embedded_hal_02::spi::{Phase, Polarity};
8 8
9use crate::dma::{AnyChannel, Channel}; 9use crate::dma::{AnyChannel, Channel};
10use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; 10use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _};
11use crate::{pac, peripherals, Peripheral}; 11use crate::{pac, peripherals};
12 12
13/// SPI errors. 13/// SPI errors.
14#[derive(Debug, Clone, Copy, PartialEq, Eq)] 14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -42,9 +42,9 @@ impl Default for Config {
42 42
43/// SPI driver. 43/// SPI driver.
44pub struct Spi<'d, T: Instance, M: Mode> { 44pub struct Spi<'d, T: Instance, M: Mode> {
45 inner: PeripheralRef<'d, T>, 45 inner: Peri<'d, T>,
46 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 46 tx_dma: Option<Peri<'d, AnyChannel>>,
47 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 47 rx_dma: Option<Peri<'d, AnyChannel>>,
48 phantom: PhantomData<(&'d mut T, M)>, 48 phantom: PhantomData<(&'d mut T, M)>,
49} 49}
50 50
@@ -73,17 +73,15 @@ fn calc_prescs(freq: u32) -> (u8, u8) {
73 73
74impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { 74impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
75 fn new_inner( 75 fn new_inner(
76 inner: impl Peripheral<P = T> + 'd, 76 inner: Peri<'d, T>,
77 clk: Option<PeripheralRef<'d, AnyPin>>, 77 clk: Option<Peri<'d, AnyPin>>,
78 mosi: Option<PeripheralRef<'d, AnyPin>>, 78 mosi: Option<Peri<'d, AnyPin>>,
79 miso: Option<PeripheralRef<'d, AnyPin>>, 79 miso: Option<Peri<'d, AnyPin>>,
80 cs: Option<PeripheralRef<'d, AnyPin>>, 80 cs: Option<Peri<'d, AnyPin>>,
81 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 81 tx_dma: Option<Peri<'d, AnyChannel>>,
82 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 82 rx_dma: Option<Peri<'d, AnyChannel>>,
83 config: Config, 83 config: Config,
84 ) -> Self { 84 ) -> Self {
85 into_ref!(inner);
86
87 Self::apply_config(&inner, &config); 85 Self::apply_config(&inner, &config);
88 86
89 let p = inner.regs(); 87 let p = inner.regs();
@@ -161,7 +159,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
161 /// 159 ///
162 /// Driver should be disabled before making changes and reenabled after the modifications 160 /// Driver should be disabled before making changes and reenabled after the modifications
163 /// are applied. 161 /// are applied.
164 fn apply_config(inner: &PeripheralRef<'d, T>, config: &Config) { 162 fn apply_config(inner: &Peri<'d, T>, config: &Config) {
165 let p = inner.regs(); 163 let p = inner.regs();
166 let (presc, postdiv) = calc_prescs(config.frequency); 164 let (presc, postdiv) = calc_prescs(config.frequency);
167 165
@@ -273,18 +271,17 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
273impl<'d, T: Instance> Spi<'d, T, Blocking> { 271impl<'d, T: Instance> Spi<'d, T, Blocking> {
274 /// Create an SPI driver in blocking mode. 272 /// Create an SPI driver in blocking mode.
275 pub fn new_blocking( 273 pub fn new_blocking(
276 inner: impl Peripheral<P = T> + 'd, 274 inner: Peri<'d, T>,
277 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 275 clk: Peri<'d, impl ClkPin<T> + 'd>,
278 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, 276 mosi: Peri<'d, impl MosiPin<T> + 'd>,
279 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, 277 miso: Peri<'d, impl MisoPin<T> + 'd>,
280 config: Config, 278 config: Config,
281 ) -> Self { 279 ) -> Self {
282 into_ref!(clk, mosi, miso);
283 Self::new_inner( 280 Self::new_inner(
284 inner, 281 inner,
285 Some(clk.map_into()), 282 Some(clk.into()),
286 Some(mosi.map_into()), 283 Some(mosi.into()),
287 Some(miso.map_into()), 284 Some(miso.into()),
288 None, 285 None,
289 None, 286 None,
290 None, 287 None,
@@ -294,16 +291,15 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
294 291
295 /// Create an SPI driver in blocking mode supporting writes only. 292 /// Create an SPI driver in blocking mode supporting writes only.
296 pub fn new_blocking_txonly( 293 pub fn new_blocking_txonly(
297 inner: impl Peripheral<P = T> + 'd, 294 inner: Peri<'d, T>,
298 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 295 clk: Peri<'d, impl ClkPin<T> + 'd>,
299 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, 296 mosi: Peri<'d, impl MosiPin<T> + 'd>,
300 config: Config, 297 config: Config,
301 ) -> Self { 298 ) -> Self {
302 into_ref!(clk, mosi);
303 Self::new_inner( 299 Self::new_inner(
304 inner, 300 inner,
305 Some(clk.map_into()), 301 Some(clk.into()),
306 Some(mosi.map_into()), 302 Some(mosi.into()),
307 None, 303 None,
308 None, 304 None,
309 None, 305 None,
@@ -314,17 +310,16 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
314 310
315 /// Create an SPI driver in blocking mode supporting reads only. 311 /// Create an SPI driver in blocking mode supporting reads only.
316 pub fn new_blocking_rxonly( 312 pub fn new_blocking_rxonly(
317 inner: impl Peripheral<P = T> + 'd, 313 inner: Peri<'d, T>,
318 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 314 clk: Peri<'d, impl ClkPin<T> + 'd>,
319 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, 315 miso: Peri<'d, impl MisoPin<T> + 'd>,
320 config: Config, 316 config: Config,
321 ) -> Self { 317 ) -> Self {
322 into_ref!(clk, miso);
323 Self::new_inner( 318 Self::new_inner(
324 inner, 319 inner,
325 Some(clk.map_into()), 320 Some(clk.into()),
326 None, 321 None,
327 Some(miso.map_into()), 322 Some(miso.into()),
328 None, 323 None,
329 None, 324 None,
330 None, 325 None,
@@ -336,43 +331,41 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
336impl<'d, T: Instance> Spi<'d, T, Async> { 331impl<'d, T: Instance> Spi<'d, T, Async> {
337 /// Create an SPI driver in async mode supporting DMA operations. 332 /// Create an SPI driver in async mode supporting DMA operations.
338 pub fn new( 333 pub fn new(
339 inner: impl Peripheral<P = T> + 'd, 334 inner: Peri<'d, T>,
340 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 335 clk: Peri<'d, impl ClkPin<T> + 'd>,
341 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, 336 mosi: Peri<'d, impl MosiPin<T> + 'd>,
342 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, 337 miso: Peri<'d, impl MisoPin<T> + 'd>,
343 tx_dma: impl Peripheral<P = impl Channel> + 'd, 338 tx_dma: Peri<'d, impl Channel>,
344 rx_dma: impl Peripheral<P = impl Channel> + 'd, 339 rx_dma: Peri<'d, impl Channel>,
345 config: Config, 340 config: Config,
346 ) -> Self { 341 ) -> Self {
347 into_ref!(tx_dma, rx_dma, clk, mosi, miso);
348 Self::new_inner( 342 Self::new_inner(
349 inner, 343 inner,
350 Some(clk.map_into()), 344 Some(clk.into()),
351 Some(mosi.map_into()), 345 Some(mosi.into()),
352 Some(miso.map_into()), 346 Some(miso.into()),
353 None, 347 None,
354 Some(tx_dma.map_into()), 348 Some(tx_dma.into()),
355 Some(rx_dma.map_into()), 349 Some(rx_dma.into()),
356 config, 350 config,
357 ) 351 )
358 } 352 }
359 353
360 /// Create an SPI driver in async mode supporting DMA write operations only. 354 /// Create an SPI driver in async mode supporting DMA write operations only.
361 pub fn new_txonly( 355 pub fn new_txonly(
362 inner: impl Peripheral<P = T> + 'd, 356 inner: Peri<'d, T>,
363 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 357 clk: Peri<'d, impl ClkPin<T> + 'd>,
364 mosi: impl Peripheral<P = impl MosiPin<T> + 'd> + 'd, 358 mosi: Peri<'d, impl MosiPin<T> + 'd>,
365 tx_dma: impl Peripheral<P = impl Channel> + 'd, 359 tx_dma: Peri<'d, impl Channel>,
366 config: Config, 360 config: Config,
367 ) -> Self { 361 ) -> Self {
368 into_ref!(tx_dma, clk, mosi);
369 Self::new_inner( 362 Self::new_inner(
370 inner, 363 inner,
371 Some(clk.map_into()), 364 Some(clk.into()),
372 Some(mosi.map_into()), 365 Some(mosi.into()),
373 None, 366 None,
374 None, 367 None,
375 Some(tx_dma.map_into()), 368 Some(tx_dma.into()),
376 None, 369 None,
377 config, 370 config,
378 ) 371 )
@@ -380,29 +373,28 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
380 373
381 /// Create an SPI driver in async mode supporting DMA read operations only. 374 /// Create an SPI driver in async mode supporting DMA read operations only.
382 pub fn new_rxonly( 375 pub fn new_rxonly(
383 inner: impl Peripheral<P = T> + 'd, 376 inner: Peri<'d, T>,
384 clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, 377 clk: Peri<'d, impl ClkPin<T> + 'd>,
385 miso: impl Peripheral<P = impl MisoPin<T> + 'd> + 'd, 378 miso: Peri<'d, impl MisoPin<T> + 'd>,
386 tx_dma: impl Peripheral<P = impl Channel> + 'd, 379 tx_dma: Peri<'d, impl Channel>,
387 rx_dma: impl Peripheral<P = impl Channel> + 'd, 380 rx_dma: Peri<'d, impl Channel>,
388 config: Config, 381 config: Config,
389 ) -> Self { 382 ) -> Self {
390 into_ref!(tx_dma, rx_dma, clk, miso);
391 Self::new_inner( 383 Self::new_inner(
392 inner, 384 inner,
393 Some(clk.map_into()), 385 Some(clk.into()),
394 None, 386 None,
395 Some(miso.map_into()), 387 Some(miso.into()),
396 None, 388 None,
397 Some(tx_dma.map_into()), 389 Some(tx_dma.into()),
398 Some(rx_dma.map_into()), 390 Some(rx_dma.into()),
399 config, 391 config,
400 ) 392 )
401 } 393 }
402 394
403 /// Write data to SPI using DMA. 395 /// Write data to SPI using DMA.
404 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 396 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
405 let tx_ch = self.tx_dma.as_mut().unwrap(); 397 let tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
406 let tx_transfer = unsafe { 398 let tx_transfer = unsafe {
407 // If we don't assign future to a variable, the data register pointer 399 // If we don't assign future to a variable, the data register pointer
408 // is held across an await and makes the future non-Send. 400 // is held across an await and makes the future non-Send.
@@ -427,14 +419,14 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
427 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 419 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
428 // Start RX first. Transfer starts when TX starts, if RX 420 // Start RX first. Transfer starts when TX starts, if RX
429 // is not started yet we might lose bytes. 421 // is not started yet we might lose bytes.
430 let rx_ch = self.rx_dma.as_mut().unwrap(); 422 let rx_ch = self.rx_dma.as_mut().unwrap().reborrow();
431 let rx_transfer = unsafe { 423 let rx_transfer = unsafe {
432 // If we don't assign future to a variable, the data register pointer 424 // If we don't assign future to a variable, the data register pointer
433 // is held across an await and makes the future non-Send. 425 // is held across an await and makes the future non-Send.
434 crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, buffer, T::RX_DREQ) 426 crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, buffer, T::RX_DREQ)
435 }; 427 };
436 428
437 let tx_ch = self.tx_dma.as_mut().unwrap(); 429 let tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
438 let tx_transfer = unsafe { 430 let tx_transfer = unsafe {
439 // If we don't assign future to a variable, the data register pointer 431 // If we don't assign future to a variable, the data register pointer
440 // is held across an await and makes the future non-Send. 432 // is held across an await and makes the future non-Send.
@@ -462,20 +454,20 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
462 async fn transfer_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { 454 async fn transfer_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
463 // Start RX first. Transfer starts when TX starts, if RX 455 // Start RX first. Transfer starts when TX starts, if RX
464 // is not started yet we might lose bytes. 456 // is not started yet we might lose bytes.
465 let rx_ch = self.rx_dma.as_mut().unwrap(); 457 let rx_ch = self.rx_dma.as_mut().unwrap().reborrow();
466 let rx_transfer = unsafe { 458 let rx_transfer = unsafe {
467 // If we don't assign future to a variable, the data register pointer 459 // If we don't assign future to a variable, the data register pointer
468 // is held across an await and makes the future non-Send. 460 // is held across an await and makes the future non-Send.
469 crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx, T::RX_DREQ) 461 crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx, T::RX_DREQ)
470 }; 462 };
471 463
472 let mut tx_ch = self.tx_dma.as_mut().unwrap(); 464 let mut tx_ch = self.tx_dma.as_mut().unwrap().reborrow();
473 // If we don't assign future to a variable, the data register pointer 465 // If we don't assign future to a variable, the data register pointer
474 // is held across an await and makes the future non-Send. 466 // is held across an await and makes the future non-Send.
475 let tx_transfer = async { 467 let tx_transfer = async {
476 let p = self.inner.regs(); 468 let p = self.inner.regs();
477 unsafe { 469 unsafe {
478 crate::dma::write(&mut tx_ch, tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await; 470 crate::dma::write(tx_ch.reborrow(), tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await;
479 471
480 if rx.len() > tx.len() { 472 if rx.len() > tx.len() {
481 let write_bytes_len = rx.len() - tx.len(); 473 let write_bytes_len = rx.len() - tx.len();
@@ -519,7 +511,7 @@ pub trait Mode: SealedMode {}
519 511
520/// SPI instance trait. 512/// SPI instance trait.
521#[allow(private_bounds)] 513#[allow(private_bounds)]
522pub trait Instance: SealedInstance {} 514pub trait Instance: SealedInstance + PeripheralType {}
523 515
524macro_rules! impl_instance { 516macro_rules! impl_instance {
525 ($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => { 517 ($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => {
diff --git a/embassy-rp/src/trng.rs b/embassy-rp/src/trng.rs
index 9f2f33c4b..44b1bb996 100644
--- a/embassy-rp/src/trng.rs
+++ b/embassy-rp/src/trng.rs
@@ -5,7 +5,7 @@ use core::marker::PhantomData;
5use core::ops::Not; 5use core::ops::Not;
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::Peripheral; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use rand_core::Error; 10use rand_core::Error;
11 11
@@ -20,7 +20,7 @@ trait SealedInstance {
20 20
21/// TRNG peripheral instance. 21/// TRNG peripheral instance.
22#[allow(private_bounds)] 22#[allow(private_bounds)]
23pub trait Instance: SealedInstance { 23pub trait Instance: SealedInstance + PeripheralType {
24 /// Interrupt for this peripheral. 24 /// Interrupt for this peripheral.
25 type Interrupt: Interrupt; 25 type Interrupt: Interrupt;
26} 26}
@@ -158,11 +158,7 @@ const TRNG_BLOCK_SIZE_BYTES: usize = TRNG_BLOCK_SIZE_BITS / 8;
158 158
159impl<'d, T: Instance> Trng<'d, T> { 159impl<'d, T: Instance> Trng<'d, T> {
160 /// Create a new TRNG driver. 160 /// Create a new TRNG driver.
161 pub fn new( 161 pub fn new(_trng: Peri<'d, T>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd, config: Config) -> Self {
162 _trng: impl Peripheral<P = T> + 'd,
163 _irq: impl Binding<T::Interrupt, InterruptHandler<T>> + 'd,
164 config: Config,
165 ) -> Self {
166 let regs = T::regs(); 162 let regs = T::regs();
167 163
168 regs.rng_imr().write(|w| w.set_ehr_valid_int_mask(false)); 164 regs.rng_imr().write(|w| w.set_ehr_valid_int_mask(false));
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs
index 152a432c9..5b5159d22 100644
--- a/embassy-rp/src/uart/buffered.rs
+++ b/embassy-rp/src/uart/buffered.rs
@@ -90,17 +90,15 @@ pub(crate) fn init_buffers<'d, T: Instance + 'd>(
90impl<'d, T: Instance> BufferedUart<'d, T> { 90impl<'d, T: Instance> BufferedUart<'d, T> {
91 /// Create a buffered UART instance. 91 /// Create a buffered UART instance.
92 pub fn new( 92 pub fn new(
93 _uart: impl Peripheral<P = T> + 'd, 93 _uart: Peri<'d, T>,
94 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 94 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
95 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 95 tx: Peri<'d, impl TxPin<T>>,
96 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 96 rx: Peri<'d, impl RxPin<T>>,
97 tx_buffer: &'d mut [u8], 97 tx_buffer: &'d mut [u8],
98 rx_buffer: &'d mut [u8], 98 rx_buffer: &'d mut [u8],
99 config: Config, 99 config: Config,
100 ) -> Self { 100 ) -> Self {
101 into_ref!(tx, rx); 101 super::Uart::<'d, T, Async>::init(Some(tx.into()), Some(rx.into()), None, None, config);
102
103 super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config);
104 init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); 102 init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer));
105 103
106 Self { 104 Self {
@@ -111,23 +109,21 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
111 109
112 /// Create a buffered UART instance with flow control. 110 /// Create a buffered UART instance with flow control.
113 pub fn new_with_rtscts( 111 pub fn new_with_rtscts(
114 _uart: impl Peripheral<P = T> + 'd, 112 _uart: Peri<'d, T>,
115 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 113 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
116 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 114 tx: Peri<'d, impl TxPin<T>>,
117 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 115 rx: Peri<'d, impl RxPin<T>>,
118 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 116 rts: Peri<'d, impl RtsPin<T>>,
119 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 117 cts: Peri<'d, impl CtsPin<T>>,
120 tx_buffer: &'d mut [u8], 118 tx_buffer: &'d mut [u8],
121 rx_buffer: &'d mut [u8], 119 rx_buffer: &'d mut [u8],
122 config: Config, 120 config: Config,
123 ) -> Self { 121 ) -> Self {
124 into_ref!(tx, rx, cts, rts);
125
126 super::Uart::<'d, T, Async>::init( 122 super::Uart::<'d, T, Async>::init(
127 Some(tx.map_into()), 123 Some(tx.into()),
128 Some(rx.map_into()), 124 Some(rx.into()),
129 Some(rts.map_into()), 125 Some(rts.into()),
130 Some(cts.map_into()), 126 Some(cts.into()),
131 config, 127 config,
132 ); 128 );
133 init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); 129 init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer));
@@ -184,15 +180,13 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
184impl<'d, T: Instance> BufferedUartRx<'d, T> { 180impl<'d, T: Instance> BufferedUartRx<'d, T> {
185 /// Create a new buffered UART RX. 181 /// Create a new buffered UART RX.
186 pub fn new( 182 pub fn new(
187 _uart: impl Peripheral<P = T> + 'd, 183 _uart: Peri<'d, T>,
188 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 184 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
189 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 185 rx: Peri<'d, impl RxPin<T>>,
190 rx_buffer: &'d mut [u8], 186 rx_buffer: &'d mut [u8],
191 config: Config, 187 config: Config,
192 ) -> Self { 188 ) -> Self {
193 into_ref!(rx); 189 super::Uart::<'d, T, Async>::init(None, Some(rx.into()), None, None, config);
194
195 super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config);
196 init_buffers::<T>(irq, None, Some(rx_buffer)); 190 init_buffers::<T>(irq, None, Some(rx_buffer));
197 191
198 Self { phantom: PhantomData } 192 Self { phantom: PhantomData }
@@ -200,16 +194,14 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
200 194
201 /// Create a new buffered UART RX with flow control. 195 /// Create a new buffered UART RX with flow control.
202 pub fn new_with_rts( 196 pub fn new_with_rts(
203 _uart: impl Peripheral<P = T> + 'd, 197 _uart: Peri<'d, T>,
204 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 198 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
205 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 199 rx: Peri<'d, impl RxPin<T>>,
206 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 200 rts: Peri<'d, impl RtsPin<T>>,
207 rx_buffer: &'d mut [u8], 201 rx_buffer: &'d mut [u8],
208 config: Config, 202 config: Config,
209 ) -> Self { 203 ) -> Self {
210 into_ref!(rx, rts); 204 super::Uart::<'d, T, Async>::init(None, Some(rx.into()), Some(rts.into()), None, config);
211
212 super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config);
213 init_buffers::<T>(irq, None, Some(rx_buffer)); 205 init_buffers::<T>(irq, None, Some(rx_buffer));
214 206
215 Self { phantom: PhantomData } 207 Self { phantom: PhantomData }
@@ -338,15 +330,13 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
338impl<'d, T: Instance> BufferedUartTx<'d, T> { 330impl<'d, T: Instance> BufferedUartTx<'d, T> {
339 /// Create a new buffered UART TX. 331 /// Create a new buffered UART TX.
340 pub fn new( 332 pub fn new(
341 _uart: impl Peripheral<P = T> + 'd, 333 _uart: Peri<'d, T>,
342 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 334 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
343 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 335 tx: Peri<'d, impl TxPin<T>>,
344 tx_buffer: &'d mut [u8], 336 tx_buffer: &'d mut [u8],
345 config: Config, 337 config: Config,
346 ) -> Self { 338 ) -> Self {
347 into_ref!(tx); 339 super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, None, config);
348
349 super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config);
350 init_buffers::<T>(irq, Some(tx_buffer), None); 340 init_buffers::<T>(irq, Some(tx_buffer), None);
351 341
352 Self { phantom: PhantomData } 342 Self { phantom: PhantomData }
@@ -354,16 +344,14 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
354 344
355 /// Create a new buffered UART TX with flow control. 345 /// Create a new buffered UART TX with flow control.
356 pub fn new_with_cts( 346 pub fn new_with_cts(
357 _uart: impl Peripheral<P = T> + 'd, 347 _uart: Peri<'d, T>,
358 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, 348 irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
359 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 349 tx: Peri<'d, impl TxPin<T>>,
360 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 350 cts: Peri<'d, impl CtsPin<T>>,
361 tx_buffer: &'d mut [u8], 351 tx_buffer: &'d mut [u8],
362 config: Config, 352 config: Config,
363 ) -> Self { 353 ) -> Self {
364 into_ref!(tx, cts); 354 super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, Some(cts.into()), config);
365
366 super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config);
367 init_buffers::<T>(irq, Some(tx_buffer), None); 355 init_buffers::<T>(irq, Some(tx_buffer), None);
368 356
369 Self { phantom: PhantomData } 357 Self { phantom: PhantomData }
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs
index 8d12aeef6..90c7655be 100644
--- a/embassy-rp/src/uart/mod.rs
+++ b/embassy-rp/src/uart/mod.rs
@@ -5,7 +5,7 @@ use core::task::Poll;
5 5
6use atomic_polyfill::{AtomicU16, Ordering}; 6use atomic_polyfill::{AtomicU16, Ordering};
7use embassy_futures::select::{select, Either}; 7use embassy_futures::select::{select, Either};
8use embassy_hal_internal::{into_ref, PeripheralRef}; 8use embassy_hal_internal::{Peri, PeripheralType};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use embassy_time::{Delay, Timer}; 10use embassy_time::{Delay, Timer};
11use pac::uart::regs::Uartris; 11use pac::uart::regs::Uartris;
@@ -15,7 +15,7 @@ use crate::dma::{AnyChannel, Channel};
15use crate::gpio::{AnyPin, SealedPin}; 15use crate::gpio::{AnyPin, SealedPin};
16use crate::interrupt::typelevel::{Binding, Interrupt}; 16use crate::interrupt::typelevel::{Binding, Interrupt};
17use crate::pac::io::vals::{Inover, Outover}; 17use crate::pac::io::vals::{Inover, Outover};
18use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; 18use crate::{interrupt, pac, peripherals, RegExt};
19 19
20mod buffered; 20mod buffered;
21pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; 21pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
@@ -142,30 +142,29 @@ pub struct Uart<'d, T: Instance, M: Mode> {
142 142
143/// UART TX driver. 143/// UART TX driver.
144pub struct UartTx<'d, T: Instance, M: Mode> { 144pub struct UartTx<'d, T: Instance, M: Mode> {
145 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 145 tx_dma: Option<Peri<'d, AnyChannel>>,
146 phantom: PhantomData<(&'d mut T, M)>, 146 phantom: PhantomData<(&'d mut T, M)>,
147} 147}
148 148
149/// UART RX driver. 149/// UART RX driver.
150pub struct UartRx<'d, T: Instance, M: Mode> { 150pub struct UartRx<'d, T: Instance, M: Mode> {
151 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 151 rx_dma: Option<Peri<'d, AnyChannel>>,
152 phantom: PhantomData<(&'d mut T, M)>, 152 phantom: PhantomData<(&'d mut T, M)>,
153} 153}
154 154
155impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { 155impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
156 /// Create a new DMA-enabled UART which can only send data 156 /// Create a new DMA-enabled UART which can only send data
157 pub fn new( 157 pub fn new(
158 _uart: impl Peripheral<P = T> + 'd, 158 _uart: Peri<'d, T>,
159 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 159 tx: Peri<'d, impl TxPin<T>>,
160 tx_dma: impl Peripheral<P = impl Channel> + 'd, 160 tx_dma: Peri<'d, impl Channel>,
161 config: Config, 161 config: Config,
162 ) -> Self { 162 ) -> Self {
163 into_ref!(tx, tx_dma); 163 Uart::<T, M>::init(Some(tx.into()), None, None, None, config);
164 Uart::<T, M>::init(Some(tx.map_into()), None, None, None, config); 164 Self::new_inner(Some(tx_dma.into()))
165 Self::new_inner(Some(tx_dma.map_into()))
166 } 165 }
167 166
168 fn new_inner(tx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self { 167 fn new_inner(tx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
169 Self { 168 Self {
170 tx_dma, 169 tx_dma,
171 phantom: PhantomData, 170 phantom: PhantomData,
@@ -225,13 +224,8 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
225 224
226impl<'d, T: Instance> UartTx<'d, T, Blocking> { 225impl<'d, T: Instance> UartTx<'d, T, Blocking> {
227 /// Create a new UART TX instance for blocking mode operations. 226 /// Create a new UART TX instance for blocking mode operations.
228 pub fn new_blocking( 227 pub fn new_blocking(_uart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self {
229 _uart: impl Peripheral<P = T> + 'd, 228 Uart::<T, Blocking>::init(Some(tx.into()), None, None, None, config);
230 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
231 config: Config,
232 ) -> Self {
233 into_ref!(tx);
234 Uart::<T, Blocking>::init(Some(tx.map_into()), None, None, None, config);
235 Self::new_inner(None) 229 Self::new_inner(None)
236 } 230 }
237 231
@@ -251,7 +245,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> {
251impl<'d, T: Instance> UartTx<'d, T, Async> { 245impl<'d, T: Instance> UartTx<'d, T, Async> {
252 /// Write to UART TX from the provided buffer using DMA. 246 /// Write to UART TX from the provided buffer using DMA.
253 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 247 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
254 let ch = self.tx_dma.as_mut().unwrap(); 248 let ch = self.tx_dma.as_mut().unwrap().reborrow();
255 let transfer = unsafe { 249 let transfer = unsafe {
256 T::regs().uartdmacr().write_set(|reg| { 250 T::regs().uartdmacr().write_set(|reg| {
257 reg.set_txdmae(true); 251 reg.set_txdmae(true);
@@ -268,18 +262,17 @@ impl<'d, T: Instance> UartTx<'d, T, Async> {
268impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { 262impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
269 /// Create a new DMA-enabled UART which can only receive data 263 /// Create a new DMA-enabled UART which can only receive data
270 pub fn new( 264 pub fn new(
271 _uart: impl Peripheral<P = T> + 'd, 265 _uart: Peri<'d, T>,
272 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 266 rx: Peri<'d, impl RxPin<T>>,
273 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 267 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
274 rx_dma: impl Peripheral<P = impl Channel> + 'd, 268 rx_dma: Peri<'d, impl Channel>,
275 config: Config, 269 config: Config,
276 ) -> Self { 270 ) -> Self {
277 into_ref!(rx, rx_dma); 271 Uart::<T, M>::init(None, Some(rx.into()), None, None, config);
278 Uart::<T, M>::init(None, Some(rx.map_into()), None, None, config); 272 Self::new_inner(true, Some(rx_dma.into()))
279 Self::new_inner(true, Some(rx_dma.map_into()))
280 } 273 }
281 274
282 fn new_inner(has_irq: bool, rx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self { 275 fn new_inner(has_irq: bool, rx_dma: Option<Peri<'d, AnyChannel>>) -> Self {
283 debug_assert_eq!(has_irq, rx_dma.is_some()); 276 debug_assert_eq!(has_irq, rx_dma.is_some());
284 if has_irq { 277 if has_irq {
285 // disable all error interrupts initially 278 // disable all error interrupts initially
@@ -346,13 +339,8 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
346 339
347impl<'d, T: Instance> UartRx<'d, T, Blocking> { 340impl<'d, T: Instance> UartRx<'d, T, Blocking> {
348 /// Create a new UART RX instance for blocking mode operations. 341 /// Create a new UART RX instance for blocking mode operations.
349 pub fn new_blocking( 342 pub fn new_blocking(_uart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self {
350 _uart: impl Peripheral<P = T> + 'd, 343 Uart::<T, Blocking>::init(None, Some(rx.into()), None, None, config);
351 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
352 config: Config,
353 ) -> Self {
354 into_ref!(rx);
355 Uart::<T, Blocking>::init(None, Some(rx.map_into()), None, None, config);
356 Self::new_inner(false, None) 344 Self::new_inner(false, None)
357 } 345 }
358 346
@@ -419,7 +407,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
419 // start a dma transfer. if errors have happened in the interim some error 407 // start a dma transfer. if errors have happened in the interim some error
420 // interrupt flags will have been raised, and those will be picked up immediately 408 // interrupt flags will have been raised, and those will be picked up immediately
421 // by the interrupt handler. 409 // by the interrupt handler.
422 let ch = self.rx_dma.as_mut().unwrap(); 410 let ch = self.rx_dma.as_mut().unwrap().reborrow();
423 T::regs().uartimsc().write_set(|w| { 411 T::regs().uartimsc().write_set(|w| {
424 w.set_oeim(true); 412 w.set_oeim(true);
425 w.set_beim(true); 413 w.set_beim(true);
@@ -566,7 +554,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
566 // start a dma transfer. if errors have happened in the interim some error 554 // start a dma transfer. if errors have happened in the interim some error
567 // interrupt flags will have been raised, and those will be picked up immediately 555 // interrupt flags will have been raised, and those will be picked up immediately
568 // by the interrupt handler. 556 // by the interrupt handler.
569 let mut ch = self.rx_dma.as_mut().unwrap(); 557 let ch = self.rx_dma.as_mut().unwrap();
570 T::regs().uartimsc().write_set(|w| { 558 T::regs().uartimsc().write_set(|w| {
571 w.set_oeim(true); 559 w.set_oeim(true);
572 w.set_beim(true); 560 w.set_beim(true);
@@ -583,7 +571,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
583 // If we don't assign future to a variable, the data register pointer 571 // If we don't assign future to a variable, the data register pointer
584 // is held across an await and makes the future non-Send. 572 // is held across an await and makes the future non-Send.
585 crate::dma::read( 573 crate::dma::read(
586 &mut ch, 574 ch.reborrow(),
587 T::regs().uartdr().as_ptr() as *const _, 575 T::regs().uartdr().as_ptr() as *const _,
588 sbuffer, 576 sbuffer,
589 T::RX_DREQ.into(), 577 T::RX_DREQ.into(),
@@ -700,41 +688,29 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
700impl<'d, T: Instance> Uart<'d, T, Blocking> { 688impl<'d, T: Instance> Uart<'d, T, Blocking> {
701 /// Create a new UART without hardware flow control 689 /// Create a new UART without hardware flow control
702 pub fn new_blocking( 690 pub fn new_blocking(
703 uart: impl Peripheral<P = T> + 'd, 691 uart: Peri<'d, T>,
704 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 692 tx: Peri<'d, impl TxPin<T>>,
705 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 693 rx: Peri<'d, impl RxPin<T>>,
706 config: Config, 694 config: Config,
707 ) -> Self { 695 ) -> Self {
708 into_ref!(tx, rx); 696 Self::new_inner(uart, tx.into(), rx.into(), None, None, false, None, None, config)
709 Self::new_inner(
710 uart,
711 tx.map_into(),
712 rx.map_into(),
713 None,
714 None,
715 false,
716 None,
717 None,
718 config,
719 )
720 } 697 }
721 698
722 /// Create a new UART with hardware flow control (RTS/CTS) 699 /// Create a new UART with hardware flow control (RTS/CTS)
723 pub fn new_with_rtscts_blocking( 700 pub fn new_with_rtscts_blocking(
724 uart: impl Peripheral<P = T> + 'd, 701 uart: Peri<'d, T>,
725 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 702 tx: Peri<'d, impl TxPin<T>>,
726 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 703 rx: Peri<'d, impl RxPin<T>>,
727 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 704 rts: Peri<'d, impl RtsPin<T>>,
728 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 705 cts: Peri<'d, impl CtsPin<T>>,
729 config: Config, 706 config: Config,
730 ) -> Self { 707 ) -> Self {
731 into_ref!(tx, rx, cts, rts);
732 Self::new_inner( 708 Self::new_inner(
733 uart, 709 uart,
734 tx.map_into(), 710 tx.into(),
735 rx.map_into(), 711 rx.into(),
736 Some(rts.map_into()), 712 Some(rts.into()),
737 Some(cts.map_into()), 713 Some(cts.into()),
738 false, 714 false,
739 None, 715 None,
740 None, 716 None,
@@ -762,50 +738,48 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
762impl<'d, T: Instance> Uart<'d, T, Async> { 738impl<'d, T: Instance> Uart<'d, T, Async> {
763 /// Create a new DMA enabled UART without hardware flow control 739 /// Create a new DMA enabled UART without hardware flow control
764 pub fn new( 740 pub fn new(
765 uart: impl Peripheral<P = T> + 'd, 741 uart: Peri<'d, T>,
766 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 742 tx: Peri<'d, impl TxPin<T>>,
767 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 743 rx: Peri<'d, impl RxPin<T>>,
768 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 744 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
769 tx_dma: impl Peripheral<P = impl Channel> + 'd, 745 tx_dma: Peri<'d, impl Channel>,
770 rx_dma: impl Peripheral<P = impl Channel> + 'd, 746 rx_dma: Peri<'d, impl Channel>,
771 config: Config, 747 config: Config,
772 ) -> Self { 748 ) -> Self {
773 into_ref!(tx, rx, tx_dma, rx_dma);
774 Self::new_inner( 749 Self::new_inner(
775 uart, 750 uart,
776 tx.map_into(), 751 tx.into(),
777 rx.map_into(), 752 rx.into(),
778 None, 753 None,
779 None, 754 None,
780 true, 755 true,
781 Some(tx_dma.map_into()), 756 Some(tx_dma.into()),
782 Some(rx_dma.map_into()), 757 Some(rx_dma.into()),
783 config, 758 config,
784 ) 759 )
785 } 760 }
786 761
787 /// Create a new DMA enabled UART with hardware flow control (RTS/CTS) 762 /// Create a new DMA enabled UART with hardware flow control (RTS/CTS)
788 pub fn new_with_rtscts( 763 pub fn new_with_rtscts(
789 uart: impl Peripheral<P = T> + 'd, 764 uart: Peri<'d, T>,
790 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 765 tx: Peri<'d, impl TxPin<T>>,
791 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 766 rx: Peri<'d, impl RxPin<T>>,
792 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 767 rts: Peri<'d, impl RtsPin<T>>,
793 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 768 cts: Peri<'d, impl CtsPin<T>>,
794 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, 769 _irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
795 tx_dma: impl Peripheral<P = impl Channel> + 'd, 770 tx_dma: Peri<'d, impl Channel>,
796 rx_dma: impl Peripheral<P = impl Channel> + 'd, 771 rx_dma: Peri<'d, impl Channel>,
797 config: Config, 772 config: Config,
798 ) -> Self { 773 ) -> Self {
799 into_ref!(tx, rx, cts, rts, tx_dma, rx_dma);
800 Self::new_inner( 774 Self::new_inner(
801 uart, 775 uart,
802 tx.map_into(), 776 tx.into(),
803 rx.map_into(), 777 rx.into(),
804 Some(rts.map_into()), 778 Some(rts.into()),
805 Some(cts.map_into()), 779 Some(cts.into()),
806 true, 780 true,
807 Some(tx_dma.map_into()), 781 Some(tx_dma.into()),
808 Some(rx_dma.map_into()), 782 Some(rx_dma.into()),
809 config, 783 config,
810 ) 784 )
811 } 785 }
@@ -813,14 +787,14 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
813 787
814impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { 788impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
815 fn new_inner( 789 fn new_inner(
816 _uart: impl Peripheral<P = T> + 'd, 790 _uart: Peri<'d, T>,
817 mut tx: PeripheralRef<'d, AnyPin>, 791 mut tx: Peri<'d, AnyPin>,
818 mut rx: PeripheralRef<'d, AnyPin>, 792 mut rx: Peri<'d, AnyPin>,
819 mut rts: Option<PeripheralRef<'d, AnyPin>>, 793 mut rts: Option<Peri<'d, AnyPin>>,
820 mut cts: Option<PeripheralRef<'d, AnyPin>>, 794 mut cts: Option<Peri<'d, AnyPin>>,
821 has_irq: bool, 795 has_irq: bool,
822 tx_dma: Option<PeripheralRef<'d, AnyChannel>>, 796 tx_dma: Option<Peri<'d, AnyChannel>>,
823 rx_dma: Option<PeripheralRef<'d, AnyChannel>>, 797 rx_dma: Option<Peri<'d, AnyChannel>>,
824 config: Config, 798 config: Config,
825 ) -> Self { 799 ) -> Self {
826 Self::init( 800 Self::init(
@@ -838,10 +812,10 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
838 } 812 }
839 813
840 fn init( 814 fn init(
841 tx: Option<PeripheralRef<'_, AnyPin>>, 815 tx: Option<Peri<'_, AnyPin>>,
842 rx: Option<PeripheralRef<'_, AnyPin>>, 816 rx: Option<Peri<'_, AnyPin>>,
843 rts: Option<PeripheralRef<'_, AnyPin>>, 817 rts: Option<Peri<'_, AnyPin>>,
844 cts: Option<PeripheralRef<'_, AnyPin>>, 818 cts: Option<Peri<'_, AnyPin>>,
845 config: Config, 819 config: Config,
846 ) { 820 ) {
847 let r = T::regs(); 821 let r = T::regs();
@@ -1326,7 +1300,7 @@ impl_mode!(Async);
1326 1300
1327/// UART instance. 1301/// UART instance.
1328#[allow(private_bounds)] 1302#[allow(private_bounds)]
1329pub trait Instance: SealedInstance { 1303pub trait Instance: SealedInstance + PeripheralType {
1330 /// Interrupt for this instance. 1304 /// Interrupt for this instance.
1331 type Interrupt: interrupt::typelevel::Interrupt; 1305 type Interrupt: interrupt::typelevel::Interrupt;
1332} 1306}
diff --git a/embassy-rp/src/usb.rs b/embassy-rp/src/usb.rs
index 26cb90d89..96541ade6 100644
--- a/embassy-rp/src/usb.rs
+++ b/embassy-rp/src/usb.rs
@@ -5,6 +5,7 @@ use core::slice;
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::PeripheralType;
8use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
9use embassy_usb_driver as driver; 10use embassy_usb_driver as driver;
10use embassy_usb_driver::{ 11use embassy_usb_driver::{
@@ -12,7 +13,7 @@ use embassy_usb_driver::{
12}; 13};
13 14
14use crate::interrupt::typelevel::{Binding, Interrupt}; 15use crate::interrupt::typelevel::{Binding, Interrupt};
15use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; 16use crate::{interrupt, pac, peripherals, Peri, RegExt};
16 17
17trait SealedInstance { 18trait SealedInstance {
18 fn regs() -> crate::pac::usb::Usb; 19 fn regs() -> crate::pac::usb::Usb;
@@ -21,7 +22,7 @@ trait SealedInstance {
21 22
22/// USB peripheral instance. 23/// USB peripheral instance.
23#[allow(private_bounds)] 24#[allow(private_bounds)]
24pub trait Instance: SealedInstance + 'static { 25pub trait Instance: SealedInstance + PeripheralType + 'static {
25 /// Interrupt for this peripheral. 26 /// Interrupt for this peripheral.
26 type Interrupt: interrupt::typelevel::Interrupt; 27 type Interrupt: interrupt::typelevel::Interrupt;
27} 28}
@@ -107,7 +108,7 @@ pub struct Driver<'d, T: Instance> {
107 108
108impl<'d, T: Instance> Driver<'d, T> { 109impl<'d, T: Instance> Driver<'d, T> {
109 /// Create a new USB driver. 110 /// Create a new USB driver.
110 pub fn new(_usb: impl Peripheral<P = T> + 'd, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>) -> Self { 111 pub fn new(_usb: Peri<'d, T>, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>) -> Self {
111 T::Interrupt::unpend(); 112 T::Interrupt::unpend();
112 unsafe { T::Interrupt::enable() }; 113 unsafe { T::Interrupt::enable() };
113 114
diff --git a/embassy-rp/src/watchdog.rs b/embassy-rp/src/watchdog.rs
index 553936602..760d6aac2 100644
--- a/embassy-rp/src/watchdog.rs
+++ b/embassy-rp/src/watchdog.rs
@@ -10,8 +10,8 @@ use core::marker::PhantomData;
10 10
11use embassy_time::Duration; 11use embassy_time::Duration;
12 12
13use crate::pac;
14use crate::peripherals::WATCHDOG; 13use crate::peripherals::WATCHDOG;
14use crate::{pac, Peri};
15 15
16/// The reason for a system reset from the watchdog. 16/// The reason for a system reset from the watchdog.
17#[derive(Debug, Copy, Clone, PartialEq, Eq)] 17#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -30,7 +30,7 @@ pub struct Watchdog {
30 30
31impl Watchdog { 31impl Watchdog {
32 /// Create a new `Watchdog` 32 /// Create a new `Watchdog`
33 pub fn new(_watchdog: WATCHDOG) -> Self { 33 pub fn new(_watchdog: Peri<'static, WATCHDOG>) -> Self {
34 Self { 34 Self {
35 phantom: PhantomData, 35 phantom: PhantomData,
36 load_value: 0, 36 load_value: 0,