From 2bc5e9523d4373002487614ecfef1e3f0858fd66 Mon Sep 17 00:00:00 2001
From: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Date: Mon, 22 Jan 2024 21:19:18 +0100
Subject: [PATCH] nrf/gpio: remove generics.

---
 docs/modules/ROOT/examples/basic/src/main.rs  |  3 +-
 embassy-nrf/src/gpio.rs                       | 62 +++++++++----------
 embassy-nrf/src/gpiote.rs                     | 53 +++++++++-------
 .../nrf52840/src/bin/ethernet_enc28j60.rs     | 12 +---
 examples/nrf52840/src/bin/gpiote_port.rs      | 12 ++--
 examples/nrf52840/src/bin/usb_hid_keyboard.rs |  4 +-
 examples/nrf52840/src/bin/wifi_esp_hosted.rs  | 12 ++--
 tests/nrf/src/bin/ethernet_enc28j60_perf.rs   |  5 +-
 tests/nrf/src/bin/wifi_esp_hosted_perf.rs     | 12 ++--
 9 files changed, 86 insertions(+), 89 deletions(-)

diff --git a/docs/modules/ROOT/examples/basic/src/main.rs b/docs/modules/ROOT/examples/basic/src/main.rs
index 2a4ee5968..4412712c8 100644
--- a/docs/modules/ROOT/examples/basic/src/main.rs
+++ b/docs/modules/ROOT/examples/basic/src/main.rs
@@ -4,12 +4,11 @@
 use defmt::*;
 use embassy_executor::Spawner;
 use embassy_nrf::gpio::{Level, Output, OutputDrive};
-use embassy_nrf::peripherals::P0_13;
 use embassy_time::{Duration, Timer};
 use {defmt_rtt as _, panic_probe as _}; // global logger
 
 #[embassy_executor::task]
-async fn blinker(mut led: Output<'static, P0_13>, interval: Duration) {
+async fn blinker(mut led: Output<'static>, interval: Duration) {
     loop {
         led.set_high();
         Timer::after(interval).await;
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index eabf409dd..287811e61 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -36,14 +36,14 @@ pub enum Pull {
 }
 
 /// GPIO input driver.
-pub struct Input<'d, T: Pin> {
-    pub(crate) pin: Flex<'d, T>,
+pub struct Input<'d> {
+    pub(crate) pin: Flex<'d>,
 }
 
-impl<'d, T: Pin> Input<'d, T> {
+impl<'d> Input<'d> {
     /// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
     #[inline]
-    pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
+    pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, pull: Pull) -> Self {
         let mut pin = Flex::new(pin);
         pin.set_as_input(pull);
 
@@ -122,14 +122,14 @@ pub enum OutputDrive {
 }
 
 /// GPIO output driver.
-pub struct Output<'d, T: Pin> {
-    pub(crate) pin: Flex<'d, T>,
+pub struct Output<'d> {
+    pub(crate) pin: Flex<'d>,
 }
 
-impl<'d, T: Pin> Output<'d, T> {
+impl<'d> Output<'d> {
     /// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration.
     #[inline]
-    pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self {
+    pub fn new(pin: impl Peripheral<P = impl Pin> + 'd, initial_output: Level, drive: OutputDrive) -> Self {
         let mut pin = Flex::new(pin);
         match initial_output {
             Level::High => pin.set_high(),
@@ -209,20 +209,20 @@ fn convert_pull(pull: Pull) -> PULL_A {
 /// This pin can either be a disconnected, input, or output pin, or both. The level register bit will remain
 /// set while not in output mode, so the pin's level will be 'remembered' when it is not in output
 /// mode.
-pub struct Flex<'d, T: Pin> {
-    pub(crate) pin: PeripheralRef<'d, T>,
+pub struct Flex<'d> {
+    pub(crate) pin: PeripheralRef<'d, AnyPin>,
 }
 
-impl<'d, T: Pin> Flex<'d, T> {
+impl<'d> Flex<'d> {
     /// Wrap the pin in a `Flex`.
     ///
     /// The pin remains disconnected. The initial output level is unspecified, but can be changed
     /// before the pin is put into output mode.
     #[inline]
-    pub fn new(pin: impl Peripheral<P = T> + 'd) -> Self {
+    pub fn new(pin: impl Peripheral<P = impl Pin> + 'd) -> Self {
         into_ref!(pin);
         // Pin will be in disconnected state.
-        Self { pin }
+        Self { pin: pin.map_into() }
     }
 
     /// Put the pin into input mode.
@@ -349,7 +349,7 @@ impl<'d, T: Pin> Flex<'d, T> {
     }
 }
 
-impl<'d, T: Pin> Drop for Flex<'d, T> {
+impl<'d> Drop for Flex<'d> {
     fn drop(&mut self) {
         self.pin.conf().reset();
     }
@@ -510,7 +510,7 @@ macro_rules! impl_pin {
 mod eh02 {
     use super::*;
 
-    impl<'d, T: Pin> embedded_hal_02::digital::v2::InputPin for Input<'d, T> {
+    impl<'d> embedded_hal_02::digital::v2::InputPin for Input<'d> {
         type Error = Infallible;
 
         fn is_high(&self) -> Result<bool, Self::Error> {
@@ -522,7 +522,7 @@ mod eh02 {
         }
     }
 
-    impl<'d, T: Pin> embedded_hal_02::digital::v2::OutputPin for Output<'d, T> {
+    impl<'d> embedded_hal_02::digital::v2::OutputPin for Output<'d> {
         type Error = Infallible;
 
         fn set_high(&mut self) -> Result<(), Self::Error> {
@@ -534,7 +534,7 @@ mod eh02 {
         }
     }
 
-    impl<'d, T: Pin> embedded_hal_02::digital::v2::StatefulOutputPin for Output<'d, T> {
+    impl<'d> embedded_hal_02::digital::v2::StatefulOutputPin for Output<'d> {
         fn is_set_high(&self) -> Result<bool, Self::Error> {
             Ok(self.is_set_high())
         }
@@ -544,7 +544,7 @@ mod eh02 {
         }
     }
 
-    impl<'d, T: Pin> embedded_hal_02::digital::v2::ToggleableOutputPin for Output<'d, T> {
+    impl<'d> embedded_hal_02::digital::v2::ToggleableOutputPin for Output<'d> {
         type Error = Infallible;
         #[inline]
         fn toggle(&mut self) -> Result<(), Self::Error> {
@@ -556,7 +556,7 @@ mod eh02 {
     /// Implement [`embedded_hal_02::digital::v2::InputPin`] for [`Flex`];
     ///
     /// If the pin is not in input mode the result is unspecified.
-    impl<'d, T: Pin> embedded_hal_02::digital::v2::InputPin for Flex<'d, T> {
+    impl<'d> embedded_hal_02::digital::v2::InputPin for Flex<'d> {
         type Error = Infallible;
 
         fn is_high(&self) -> Result<bool, Self::Error> {
@@ -568,7 +568,7 @@ mod eh02 {
         }
     }
 
-    impl<'d, T: Pin> embedded_hal_02::digital::v2::OutputPin for Flex<'d, T> {
+    impl<'d> embedded_hal_02::digital::v2::OutputPin for Flex<'d> {
         type Error = Infallible;
 
         fn set_high(&mut self) -> Result<(), Self::Error> {
@@ -580,7 +580,7 @@ mod eh02 {
         }
     }
 
-    impl<'d, T: Pin> embedded_hal_02::digital::v2::StatefulOutputPin for Flex<'d, T> {
+    impl<'d> embedded_hal_02::digital::v2::StatefulOutputPin for Flex<'d> {
         fn is_set_high(&self) -> Result<bool, Self::Error> {
             Ok(self.is_set_high())
         }
@@ -590,7 +590,7 @@ mod eh02 {
         }
     }
 
-    impl<'d, T: Pin> embedded_hal_02::digital::v2::ToggleableOutputPin for Flex<'d, T> {
+    impl<'d> embedded_hal_02::digital::v2::ToggleableOutputPin for Flex<'d> {
         type Error = Infallible;
         #[inline]
         fn toggle(&mut self) -> Result<(), Self::Error> {
@@ -600,11 +600,11 @@ mod eh02 {
     }
 }
 
-impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Input<'d, T> {
+impl<'d> embedded_hal_1::digital::ErrorType for Input<'d> {
     type Error = Infallible;
 }
 
-impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Input<'d, T> {
+impl<'d> embedded_hal_1::digital::InputPin for Input<'d> {
     fn is_high(&mut self) -> Result<bool, Self::Error> {
         Ok((*self).is_high())
     }
@@ -614,11 +614,11 @@ impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Input<'d, T> {
     }
 }
 
-impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Output<'d, T> {
+impl<'d> embedded_hal_1::digital::ErrorType for Output<'d> {
     type Error = Infallible;
 }
 
-impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Output<'d, T> {
+impl<'d> embedded_hal_1::digital::OutputPin for Output<'d> {
     fn set_high(&mut self) -> Result<(), Self::Error> {
         Ok(self.set_high())
     }
@@ -628,7 +628,7 @@ impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Output<'d, T> {
     }
 }
 
-impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Output<'d, T> {
+impl<'d> embedded_hal_1::digital::StatefulOutputPin for Output<'d> {
     fn is_set_high(&mut self) -> Result<bool, Self::Error> {
         Ok((*self).is_set_high())
     }
@@ -638,14 +638,14 @@ impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Output<'d, T> {
     }
 }
 
-impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Flex<'d, T> {
+impl<'d> embedded_hal_1::digital::ErrorType for Flex<'d> {
     type Error = Infallible;
 }
 
 /// Implement [`InputPin`] for [`Flex`];
 ///
 /// If the pin is not in input mode the result is unspecified.
-impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Flex<'d, T> {
+impl<'d> embedded_hal_1::digital::InputPin for Flex<'d> {
     fn is_high(&mut self) -> Result<bool, Self::Error> {
         Ok((*self).is_high())
     }
@@ -655,7 +655,7 @@ impl<'d, T: Pin> embedded_hal_1::digital::InputPin for Flex<'d, T> {
     }
 }
 
-impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Flex<'d, T> {
+impl<'d> embedded_hal_1::digital::OutputPin for Flex<'d> {
     fn set_high(&mut self) -> Result<(), Self::Error> {
         Ok(self.set_high())
     }
@@ -665,7 +665,7 @@ impl<'d, T: Pin> embedded_hal_1::digital::OutputPin for Flex<'d, T> {
     }
 }
 
-impl<'d, T: Pin> embedded_hal_1::digital::StatefulOutputPin for Flex<'d, T> {
+impl<'d> embedded_hal_1::digital::StatefulOutputPin for Flex<'d> {
     fn is_set_high(&mut self) -> Result<bool, Self::Error> {
         Ok((*self).is_set_high())
     }
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 8020b8dc2..a459446a2 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -156,12 +156,12 @@ impl Iterator for BitIter {
 }
 
 /// GPIOTE channel driver in input mode
-pub struct InputChannel<'d, C: Channel, T: GpioPin> {
-    ch: PeripheralRef<'d, C>,
-    pin: Input<'d, T>,
+pub struct InputChannel<'d> {
+    ch: PeripheralRef<'d, AnyChannel>,
+    pin: Input<'d>,
 }
 
-impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> {
+impl<'d> Drop for InputChannel<'d> {
     fn drop(&mut self) {
         let g = regs();
         let num = self.ch.number();
@@ -170,9 +170,9 @@ impl<'d, C: Channel, T: GpioPin> Drop for InputChannel<'d, C, T> {
     }
 }
 
-impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> {
+impl<'d> InputChannel<'d> {
     /// Create a new GPIOTE input channel driver.
-    pub fn new(ch: impl Peripheral<P = C> + 'd, pin: Input<'d, T>, polarity: InputChannelPolarity) -> Self {
+    pub fn new(ch: impl Peripheral<P = impl Channel> + 'd, pin: Input<'d>, polarity: InputChannelPolarity) -> Self {
         into_ref!(ch);
 
         let g = regs();
@@ -195,7 +195,7 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> {
 
         g.events_in[num].reset();
 
-        InputChannel { ch, pin }
+        InputChannel { ch: ch.map_into(), pin }
     }
 
     /// Asynchronously wait for an event in this channel.
@@ -227,12 +227,12 @@ impl<'d, C: Channel, T: GpioPin> InputChannel<'d, C, T> {
 }
 
 /// GPIOTE channel driver in output mode
-pub struct OutputChannel<'d, C: Channel, T: GpioPin> {
-    ch: PeripheralRef<'d, C>,
-    _pin: Output<'d, T>,
+pub struct OutputChannel<'d> {
+    ch: PeripheralRef<'d, AnyChannel>,
+    _pin: Output<'d>,
 }
 
-impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> {
+impl<'d> Drop for OutputChannel<'d> {
     fn drop(&mut self) {
         let g = regs();
         let num = self.ch.number();
@@ -241,9 +241,9 @@ impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> {
     }
 }
 
-impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
+impl<'d> OutputChannel<'d> {
     /// Create a new GPIOTE output channel driver.
-    pub fn new(ch: impl Peripheral<P = C> + 'd, pin: Output<'d, T>, polarity: OutputChannelPolarity) -> Self {
+    pub fn new(ch: impl Peripheral<P = impl Channel> + 'd, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self {
         into_ref!(ch);
         let g = regs();
         let num = ch.number();
@@ -267,7 +267,10 @@ impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
             unsafe { w.psel().bits(pin.pin.pin.pin()) }
         });
 
-        OutputChannel { ch, _pin: pin }
+        OutputChannel {
+            ch: ch.map_into(),
+            _pin: pin,
+        }
     }
 
     /// Triggers the OUT task (does the action as configured with task_out_polarity, defaults to Toggle).
@@ -348,7 +351,7 @@ impl<'a> Future for PortInputFuture<'a> {
     }
 }
 
-impl<'d, T: GpioPin> Input<'d, T> {
+impl<'d> Input<'d> {
     /// Wait until the pin is high. If it is already high, return immediately.
     pub async fn wait_for_high(&mut self) {
         self.pin.wait_for_high().await
@@ -375,7 +378,7 @@ impl<'d, T: GpioPin> Input<'d, T> {
     }
 }
 
-impl<'d, T: GpioPin> Flex<'d, T> {
+impl<'d> Flex<'d> {
     /// Wait until the pin is high. If it is already high, return immediately.
     pub async fn wait_for_high(&mut self) {
         self.pin.conf().modify(|_, w| w.sense().high());
@@ -420,7 +423,7 @@ mod sealed {
 /// GPIOTE channel trait.
 ///
 /// Implemented by all GPIOTE channels.
-pub trait Channel: sealed::Channel + Sized {
+pub trait Channel: sealed::Channel + Into<AnyChannel> + Sized + 'static {
     /// Get the channel number.
     fn number(&self) -> usize;
 
@@ -460,6 +463,12 @@ macro_rules! impl_channel {
                 $number as usize
             }
         }
+
+        impl From<peripherals::$type> for AnyChannel {
+            fn from(val: peripherals::$type) -> Self {
+                Channel::degrade(val)
+            }
+        }
     };
 }
 
@@ -477,7 +486,7 @@ impl_channel!(GPIOTE_CH7, 7);
 mod eh02 {
     use super::*;
 
-    impl<'d, C: Channel, T: GpioPin> embedded_hal_02::digital::v2::InputPin for InputChannel<'d, C, T> {
+    impl<'d> embedded_hal_02::digital::v2::InputPin for InputChannel<'d> {
         type Error = Infallible;
 
         fn is_high(&self) -> Result<bool, Self::Error> {
@@ -490,11 +499,11 @@ mod eh02 {
     }
 }
 
-impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::ErrorType for InputChannel<'d, C, T> {
+impl<'d> embedded_hal_1::digital::ErrorType for InputChannel<'d> {
     type Error = Infallible;
 }
 
-impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::InputPin for InputChannel<'d, C, T> {
+impl<'d> embedded_hal_1::digital::InputPin for InputChannel<'d> {
     fn is_high(&mut self) -> Result<bool, Self::Error> {
         Ok(self.pin.is_high())
     }
@@ -504,7 +513,7 @@ impl<'d, C: Channel, T: GpioPin> embedded_hal_1::digital::InputPin for InputChan
     }
 }
 
-impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> {
+impl<'d> embedded_hal_async::digital::Wait for Input<'d> {
     async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
         Ok(self.wait_for_high().await)
     }
@@ -526,7 +535,7 @@ impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> {
     }
 }
 
-impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> {
+impl<'d> embedded_hal_async::digital::Wait for Flex<'d> {
     async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
         Ok(self.wait_for_high().await)
     }
diff --git a/examples/nrf52840/src/bin/ethernet_enc28j60.rs b/examples/nrf52840/src/bin/ethernet_enc28j60.rs
index a8e64b38a..279f32edc 100644
--- a/examples/nrf52840/src/bin/ethernet_enc28j60.rs
+++ b/examples/nrf52840/src/bin/ethernet_enc28j60.rs
@@ -24,10 +24,7 @@ bind_interrupts!(struct Irqs {
 #[embassy_executor::task]
 async fn net_task(
     stack: &'static Stack<
-        Enc28j60<
-            ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_15>, Delay>,
-            Output<'static, peripherals::P0_13>,
-        >,
+        Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>,
     >,
 ) -> ! {
     stack.run().await
@@ -71,12 +68,7 @@ async fn main(spawner: Spawner) {
     // Init network stack
     static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
     static STACK: StaticCell<
-        Stack<
-            Enc28j60<
-                ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_15>, Delay>,
-                Output<'static, peripherals::P0_13>,
-            >,
-        >,
+        Stack<Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>>,
     > = StaticCell::new();
     let stack = STACK.init(Stack::new(
         device,
diff --git a/examples/nrf52840/src/bin/gpiote_port.rs b/examples/nrf52840/src/bin/gpiote_port.rs
index c1afe2f20..0dddb1a97 100644
--- a/examples/nrf52840/src/bin/gpiote_port.rs
+++ b/examples/nrf52840/src/bin/gpiote_port.rs
@@ -3,11 +3,11 @@
 
 use defmt::{info, unwrap};
 use embassy_executor::Spawner;
-use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull};
+use embassy_nrf::gpio::{Input, Pull};
 use {defmt_rtt as _, panic_probe as _};
 
 #[embassy_executor::task(pool_size = 4)]
-async fn button_task(n: usize, mut pin: Input<'static, AnyPin>) {
+async fn button_task(n: usize, mut pin: Input<'static>) {
     loop {
         pin.wait_for_low().await;
         info!("Button {:?} pressed!", n);
@@ -21,10 +21,10 @@ async fn main(spawner: Spawner) {
     let p = embassy_nrf::init(Default::default());
     info!("Starting!");
 
-    let btn1 = Input::new(p.P0_11.degrade(), Pull::Up);
-    let btn2 = Input::new(p.P0_12.degrade(), Pull::Up);
-    let btn3 = Input::new(p.P0_24.degrade(), Pull::Up);
-    let btn4 = Input::new(p.P0_25.degrade(), Pull::Up);
+    let btn1 = Input::new(p.P0_11, Pull::Up);
+    let btn2 = Input::new(p.P0_12, Pull::Up);
+    let btn3 = Input::new(p.P0_24, Pull::Up);
+    let btn4 = Input::new(p.P0_25, Pull::Up);
 
     unwrap!(spawner.spawn(button_task(1, btn1)));
     unwrap!(spawner.spawn(button_task(2, btn2)));
diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs
index 45850b4a4..3e86590c4 100644
--- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs
+++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs
@@ -8,7 +8,7 @@ use defmt::*;
 use embassy_executor::Spawner;
 use embassy_futures::join::join;
 use embassy_futures::select::{select, Either};
-use embassy_nrf::gpio::{Input, Pin, Pull};
+use embassy_nrf::gpio::{Input, Pull};
 use embassy_nrf::usb::vbus_detect::HardwareVbusDetect;
 use embassy_nrf::usb::Driver;
 use embassy_nrf::{bind_interrupts, pac, peripherals, usb};
@@ -97,7 +97,7 @@ async fn main(_spawner: Spawner) {
         }
     };
 
-    let mut button = Input::new(p.P0_11.degrade(), Pull::Up);
+    let mut button = Input::new(p.P0_11, Pull::Up);
 
     let (reader, mut writer) = hid.split();
 
diff --git a/examples/nrf52840/src/bin/wifi_esp_hosted.rs b/examples/nrf52840/src/bin/wifi_esp_hosted.rs
index fc2086f75..00bd50081 100644
--- a/examples/nrf52840/src/bin/wifi_esp_hosted.rs
+++ b/examples/nrf52840/src/bin/wifi_esp_hosted.rs
@@ -5,7 +5,7 @@ use defmt::{info, unwrap, warn};
 use embassy_executor::Spawner;
 use embassy_net::tcp::TcpSocket;
 use embassy_net::{Stack, StackResources};
-use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull};
+use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
 use embassy_nrf::rng::Rng;
 use embassy_nrf::spim::{self, Spim};
 use embassy_nrf::{bind_interrupts, peripherals};
@@ -27,9 +27,9 @@ bind_interrupts!(struct Irqs {
 async fn wifi_task(
     runner: hosted::Runner<
         'static,
-        ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_31>, Delay>,
-        Input<'static, AnyPin>,
-        Output<'static, peripherals::P1_05>,
+        ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>,
+        Input<'static>,
+        Output<'static>,
     >,
 ) -> ! {
     runner.run().await
@@ -50,8 +50,8 @@ async fn main(spawner: Spawner) {
     let sck = p.P0_29;
     let mosi = p.P0_30;
     let cs = Output::new(p.P0_31, Level::High, OutputDrive::HighDrive);
-    let handshake = Input::new(p.P1_01.degrade(), Pull::Up);
-    let ready = Input::new(p.P1_04.degrade(), Pull::None);
+    let handshake = Input::new(p.P1_01, Pull::Up);
+    let ready = Input::new(p.P1_04, Pull::None);
     let reset = Output::new(p.P1_05, Level::Low, OutputDrive::Standard);
 
     let mut config = spim::Config::default();
diff --git a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
index 7dc1941d7..33c2f4235 100644
--- a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
+++ b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
@@ -21,10 +21,7 @@ bind_interrupts!(struct Irqs {
     RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>;
 });
 
-type MyDriver = Enc28j60<
-    ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_15>, Delay>,
-    Output<'static, peripherals::P0_13>,
->;
+type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>;
 
 #[embassy_executor::task]
 async fn net_task(stack: &'static Stack<MyDriver>) -> ! {
diff --git a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
index c96064f84..b83edddc4 100644
--- a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
+++ b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
@@ -6,7 +6,7 @@ teleprobe_meta::timeout!(120);
 use defmt::{info, unwrap};
 use embassy_executor::Spawner;
 use embassy_net::{Config, Stack, StackResources};
-use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull};
+use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
 use embassy_nrf::rng::Rng;
 use embassy_nrf::spim::{self, Spim};
 use embassy_nrf::{bind_interrupts, peripherals};
@@ -28,9 +28,9 @@ const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
 async fn wifi_task(
     runner: hosted::Runner<
         'static,
-        ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_31>, Delay>,
-        Input<'static, AnyPin>,
-        Output<'static, peripherals::P1_05>,
+        ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>,
+        Input<'static>,
+        Output<'static>,
     >,
 ) -> ! {
     runner.run().await
@@ -53,8 +53,8 @@ async fn main(spawner: Spawner) {
     let sck = p.P0_29;
     let mosi = p.P0_30;
     let cs = Output::new(p.P0_31, Level::High, OutputDrive::HighDrive);
-    let handshake = Input::new(p.P1_01.degrade(), Pull::Up);
-    let ready = Input::new(p.P1_04.degrade(), Pull::None);
+    let handshake = Input::new(p.P1_01, Pull::Up);
+    let ready = Input::new(p.P1_04, Pull::None);
     let reset = Output::new(p.P1_05, Level::Low, OutputDrive::Standard);
 
     let mut config = spim::Config::default();