diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 69fc2e708..f6d7c2180 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Implement `embedded-hal` output pin traits for `DummyPin` (#2019) - Added `esp_hal::init` to simplify HAL initialisation (#1970, #1999) +- Added GpioPin::degrade to create ErasePins easily. Same for AnyPin by accident. (#2075) +- Added missing functions to `Flex`: `unlisten`, `is_interrupt_set`, `wakeup_enable`, `wait_for_high`, `wait_for_low`, `wait_for_rising_edge`, `wait_for_falling_edge`, `wait_for_any_edge`. (#2075) +- `Flex` now implements `Wait`. (#2075) - Added sleep and wakeup support for esp32c2 (#1922) ### Changed @@ -18,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Delay::new()` is now a `const` function (#1999) - You can now create an `AnyPin` out of an `ErasedPin`. (#2072) +- `Input`, `Output`, `OutputOpenDrain` and `Flex` are now type-erased by default. Use the new `new_typed` constructor to keep using the ZST pin types. (#2075) ### Fixed - SHA driver can now be safely used in multiple contexts concurrently (#2049) diff --git a/esp-hal/MIGRATING-0.20.md b/esp-hal/MIGRATING-0.20.md index 4902d0046..9b185d6d9 100644 --- a/esp-hal/MIGRATING-0.20.md +++ b/esp-hal/MIGRATING-0.20.md @@ -41,3 +41,13 @@ Instead of manually grabbing peripherals and setting up clocks, you should now c - The `GpioN` type aliasses are no longer available. You can use `GpioPin` instead. - The `AnyInputOnlyPin` has been removed. Replace any use with `AnyPin`. - The `NoPinType` has been removed. You can use `DummyPin` in its place. + +### Type-erased GPIO drivers + +You no longer have to spell out the GPIO pin type for `Input`, `Output`, `OutputOpenDrain` or `Flex`. +However, if you want to, you can keep using their typed form! + +```rust +let pin = Input::new(io.gpio0); // pin will have the type `Input<'some>` (or `Input<'some, ErasedPin>` if you want to be explicit about it) +let pin = Input::new_typed(io.gpio0); // pin will have the type `Input<'some, GpioPin<0>>` +``` diff --git a/esp-hal/src/gpio/any_pin.rs b/esp-hal/src/gpio/any_pin.rs index e82e48aca..f22203914 100644 --- a/esp-hal/src/gpio/any_pin.rs +++ b/esp-hal/src/gpio/any_pin.rs @@ -13,9 +13,12 @@ pub struct AnyPin<'d> { impl<'d> AnyPin<'d> { /// Create wrapper for the given pin. #[inline] - pub fn new(pin: impl crate::peripheral::Peripheral

+ 'd) -> Self { + pub fn new

(pin: impl crate::peripheral::Peripheral

+ 'd) -> Self + where + P: Pin, + { crate::into_ref!(pin); - let pin = pin.erased_pin(private::Internal); + let pin = pin.degrade_internal(private::Internal); Self { pin, @@ -27,11 +30,12 @@ impl<'d> AnyPin<'d> { /// Create wrapper for the given pin. The peripheral signal will be /// inverted. #[inline] - pub fn new_inverted( - pin: impl crate::peripheral::Peripheral

+ 'd, - ) -> Self { + pub fn new_inverted

(pin: impl crate::peripheral::Peripheral

+ 'd) -> Self + where + P: Pin, + { crate::into_ref!(pin); - let pin = pin.erased_pin(private::Internal); + let pin = pin.degrade_internal(private::Internal); Self { pin, @@ -59,6 +63,7 @@ impl<'d> Pin for AnyPin<'d> { delegate::delegate! { to self.pin { fn number(&self, _internal: private::Internal) -> u8; + fn degrade_internal(&self, _internal: private::Internal) -> ErasedPin; fn sleep_mode(&mut self, on: bool, _internal: private::Internal); fn set_alternate_function(&mut self, alternate: AlternateFunction, _internal: private::Internal); fn is_listening(&self, _internal: private::Internal) -> bool; diff --git a/esp-hal/src/gpio/dummy_pin.rs b/esp-hal/src/gpio/dummy_pin.rs index 614132075..5d319808a 100644 --- a/esp-hal/src/gpio/dummy_pin.rs +++ b/esp-hal/src/gpio/dummy_pin.rs @@ -32,6 +32,10 @@ impl Pin for DummyPin { panic!("DummyPin not supported here!"); } + fn degrade_internal(&self, _: private::Internal) -> ErasedPin { + panic!("Can not type erase the DummyPin!"); + } + fn sleep_mode(&mut self, _on: bool, _: private::Internal) {} fn set_alternate_function(&mut self, _alternate: AlternateFunction, _: private::Internal) {} diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index d2a882882..210b827fd 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -136,6 +136,17 @@ pub enum Level { High, } +impl core::ops::Not for Level { + type Output = Self; + + fn not(self) -> Self { + match self { + Self::Low => Self::High, + Self::High => Self::Low, + } + } +} + impl From for Level { fn from(val: bool) -> Self { match val { @@ -259,6 +270,21 @@ pub trait Pin: private::Sealed { /// GPIO number fn number(&self, _: private::Internal) -> u8; + /// Type-erase (degrade) this pin into an ErasedPin. + /// + /// This converts pin singletons (`GpioPin<0>`, …), which are all different + /// types, into the same type. It is useful for creating arrays of pins, + /// or avoiding generics. + fn degrade(self) -> ErasedPin + where + Self: Sized, + { + self.degrade_internal(private::Internal) + } + + #[doc(hidden)] + fn degrade_internal(&self, _: private::Internal) -> ErasedPin; + /// Enable/disable sleep-mode fn sleep_mode(&mut self, on: bool, _: private::Internal); @@ -431,11 +457,6 @@ pub trait TouchPin: Pin { fn set_threshold(&self, threshold: u16, _: private::Internal); } -#[doc(hidden)] -pub trait CreateErasedPin: Pin { - fn erased_pin(&self, _: private::Internal) -> ErasedPin; -} - #[doc(hidden)] pub trait InterruptStatusRegisterAccess { fn pro_cpu_interrupt_status_read() -> u32; @@ -844,6 +865,10 @@ where GPIONUM } + fn degrade_internal(&self, _: private::Internal) -> ErasedPin { + self.degrade_pin(private::Internal) + } + fn sleep_mode(&mut self, on: bool, _: private::Internal) { get_io_mux_reg(GPIONUM).modify(|_, w| w.slp_sel().bit(on)); } @@ -1261,6 +1286,8 @@ pub trait GpioProperties { type IsOutput: BooleanType; type IsAnalog: BooleanType; type IsTouch: BooleanType; + + fn degrade_pin(&self, _: private::Internal) -> ErasedPin; } #[doc(hidden)] @@ -1335,6 +1362,10 @@ macro_rules! gpio { type InterruptStatus = $crate::gpio::[< InterruptStatusRegisterAccessBank $bank >]; type Signals = [< Gpio $gpionum Signals >]; $crate::pin_types!($type); + + fn degrade_pin(&self, _: $crate::private::Internal) -> ErasedPin { + $crate::gpio::ErasedPin::[< Gpio $gpionum >](unsafe { Self::steal() }) + } } #[doc(hidden)] @@ -1366,12 +1397,6 @@ macro_rules! gpio { input_signals } } - - impl $crate::gpio::CreateErasedPin for GpioPin<$gpionum> { - fn erased_pin(&self, _: $crate::private::Internal) -> ErasedPin { - $crate::gpio::ErasedPin::[< Gpio $gpionum >](unsafe { Self::steal() }) - } - } )+ /// Pins available on this chip @@ -1390,7 +1415,7 @@ macro_rules! gpio { } impl ErasedPin { - pub(crate) unsafe fn clone_unchecked(&mut self) -> Self { + pub(crate) unsafe fn clone_unchecked(&self) -> Self { match self { $( ErasedPin::[](_) => { @@ -1401,15 +1426,10 @@ macro_rules! gpio { } } - impl $crate::gpio::CreateErasedPin for ErasedPin { - fn erased_pin(&self, _: $crate::private::Internal) -> ErasedPin { - match self { - $( - ErasedPin::[](_) => { - ErasedPin::[< Gpio $gpionum >](unsafe { GpioPin::steal() }) - } - )+ - } + impl $crate::peripheral::Peripheral for ErasedPin { + type P = ErasedPin; + unsafe fn clone_unchecked(&mut self) -> Self { + ErasedPin::clone_unchecked(self) } } @@ -1868,8 +1888,21 @@ macro_rules! touch_common { } /// GPIO output driver. -pub struct Output<'d, P> { - pin: PeripheralRef<'d, P>, +pub struct Output<'d, P = ErasedPin> { + pin: Flex<'d, P>, +} + +impl<'d> Output<'d> { + /// Create GPIO output driver for a [GpioPin] with the provided level + #[inline] + pub fn new( + pin: impl crate::peripheral::Peripheral

+ 'd, + initial_output: Level, + ) -> Self { + let pin = Flex::new(pin); + + Self::new_inner(pin, initial_output) + } } impl<'d, P> Output<'d, P> @@ -1878,11 +1911,20 @@ where { /// Create GPIO output driver for a [GpioPin] with the provided level #[inline] - pub fn new(pin: impl crate::peripheral::Peripheral

+ 'd, initial_output: Level) -> Self { - crate::into_ref!(pin); + pub fn new_typed( + pin: impl crate::peripheral::Peripheral

+ 'd, + initial_output: Level, + ) -> Self { + let pin = Flex::new_typed(pin); - pin.set_output_high(initial_output.into(), private::Internal); - pin.set_to_push_pull_output(private::Internal); + Self::new_inner(pin, initial_output) + } + + fn new_inner(mut pin: Flex<'d, P>, initial_output: Level) -> Self { + pin.pin + .set_output_high(initial_output.into(), private::Internal); + + pin.set_as_output(); Self { pin } } @@ -1890,55 +1932,68 @@ where /// Set the output as high. #[inline] pub fn set_high(&mut self) { - self.pin.set_output_high(true, private::Internal); + self.set_level(Level::High) } /// Set the output as low. #[inline] pub fn set_low(&mut self) { - self.pin.set_output_high(false, private::Internal); + self.set_level(Level::Low) } /// Set the output level. #[inline] pub fn set_level(&mut self, level: Level) { - self.pin.set_output_high(level.into(), private::Internal); + self.pin.set_level(level) } /// Is the output pin set as high? #[inline] pub fn is_set_high(&self) -> bool { - self.pin.is_set_high(private::Internal) + self.get_output_level() == Level::High } /// Is the output pin set as low? #[inline] pub fn is_set_low(&self) -> bool { - !self.pin.is_set_high(private::Internal) + self.get_output_level() == Level::Low } /// What level output is set to #[inline] pub fn get_output_level(&self) -> Level { - self.pin.is_set_high(private::Internal).into() + self.pin.get_output_level() } /// Toggle pin output #[inline] pub fn toggle(&mut self) { - let level = !self.pin.is_set_high(private::Internal); - self.pin.set_output_high(level, private::Internal); + self.pin.toggle(); } /// Configure the [DriveStrength] of the pin pub fn set_drive_strength(&mut self, strength: DriveStrength) { - self.pin.set_drive_strength(strength, private::Internal); + self.pin.set_drive_strength(strength); } } /// GPIO input driver. -pub struct Input<'d, P> { - pin: PeripheralRef<'d, P>, +pub struct Input<'d, P = ErasedPin> { + pin: Flex<'d, P>, +} + +impl<'d> Input<'d> { + /// Create GPIO input driver for a [Pin] with the provided [Pull] + /// configuration. + #[inline] + pub fn new( + pin: impl crate::peripheral::Peripheral

+ 'd, + pull: Pull, + ) -> Self { + let pin = Flex::new(pin); + + Self::new_inner(pin, pull) + } } impl<'d, P> Input<'d, P> @@ -1948,28 +2003,247 @@ where /// Create GPIO input driver for a [Pin] with the provided [Pull] /// configuration. #[inline] - pub fn new(pin: impl crate::peripheral::Peripheral

+ 'd, pull: Pull) -> Self { - crate::into_ref!(pin); - pin.init_input(pull == Pull::Down, pull == Pull::Up, private::Internal); + pub fn new_typed(pin: impl crate::peripheral::Peripheral

+ 'd, pull: Pull) -> Self { + let pin = Flex::new_typed(pin); + + Self::new_inner(pin, pull) + } + + fn new_inner(mut pin: Flex<'d, P>, pull: Pull) -> Self { + pin.set_as_input(pull); + Self { pin } } /// Get whether the pin input level is high. #[inline] pub fn is_high(&self) -> bool { - self.pin.is_input_high(private::Internal) + self.get_level() == Level::High } /// Get whether the pin input level is low. #[inline] pub fn is_low(&self) -> bool { - !self.is_high() + self.get_level() == Level::Low } /// Get the current pin input level. #[inline] pub fn get_level(&self) -> Level { - self.is_high().into() + self.pin.get_level() + } + + /// Listen for interrupts + #[inline] + pub fn listen(&mut self, event: Event) { + self.pin.listen(event); + } + + /// Stop listening for interrupts + pub fn unlisten(&mut self) { + self.pin.unlisten(); + } + + /// Clear the interrupt status bit for this Pin + #[inline] + pub fn clear_interrupt(&mut self) { + self.pin.clear_interrupt(); + } + + /// Checks if the interrupt status bit for this Pin is set + #[inline] + pub fn is_interrupt_set(&self) -> bool { + self.pin.is_interrupt_set() + } + + /// Enable as a wake-up source. + /// + /// This will unlisten for interrupts + #[inline] + pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) { + self.pin.wakeup_enable(enable, event); + } +} + +/// GPIO open-drain output driver. +pub struct OutputOpenDrain<'d, P = ErasedPin> { + pin: Flex<'d, P>, +} + +impl<'d> OutputOpenDrain<'d> { + /// Create GPIO open-drain output driver for a [Pin] with the provided + /// initial output-level and [Pull] configuration. + #[inline] + pub fn new( + pin: impl crate::peripheral::Peripheral

+ 'd, + initial_output: Level, + pull: Pull, + ) -> Self { + let pin = Flex::new(pin); + + Self::new_inner(pin, initial_output, pull) + } +} + +impl<'d, P> OutputOpenDrain<'d, P> +where + P: InputPin + OutputPin, +{ + /// Create GPIO open-drain output driver for a [Pin] with the provided + /// initial output-level and [Pull] configuration. + #[inline] + pub fn new_typed( + pin: impl crate::peripheral::Peripheral

+ 'd, + initial_output: Level, + pull: Pull, + ) -> Self { + let pin = Flex::new_typed(pin); + + Self::new_inner(pin, initial_output, pull) + } + + fn new_inner(mut pin: Flex<'d, P>, initial_output: Level, pull: Pull) -> Self { + pin.pin + .set_output_high(initial_output.into(), private::Internal); + + pin.set_as_open_drain(pull); + + Self { pin } + } + + /// Get whether the pin input level is high. + #[inline] + pub fn is_high(&self) -> bool { + self.get_level() == Level::High + } + + /// Get whether the pin input level is low. + #[inline] + pub fn is_low(&self) -> bool { + self.get_level() == Level::Low + } + + /// Get the current pin input level. + #[inline] + pub fn get_level(&self) -> Level { + self.pin.get_level() + } + + /// Listen for interrupts + #[inline] + pub fn listen(&mut self, event: Event) { + self.pin.listen(event); + } + + /// Clear the interrupt status bit for this Pin + #[inline] + pub fn clear_interrupt(&mut self) { + self.pin.clear_interrupt(); + } + + /// Set the output as high. + #[inline] + pub fn set_high(&mut self) { + self.set_level(Level::High); + } + + /// Set the output as low. + #[inline] + pub fn set_low(&mut self) { + self.set_level(Level::Low); + } + + /// Set the output level. + #[inline] + pub fn set_level(&mut self, level: Level) { + self.pin.set_level(level); + } + + /// Is the output pin set as high? + #[inline] + pub fn is_set_high(&self) -> bool { + self.get_output_level() == Level::High + } + + /// Is the output pin set as low? + #[inline] + pub fn is_set_low(&self) -> bool { + self.get_output_level() == Level::Low + } + + /// What level output is set to + #[inline] + pub fn get_output_level(&self) -> Level { + self.pin.get_output_level() + } + + /// Toggle pin output + #[inline] + pub fn toggle(&mut self) { + self.pin.toggle() + } + + /// Configure the [DriveStrength] of the pin + pub fn set_drive_strength(&mut self, strength: DriveStrength) { + self.pin.set_drive_strength(strength); + } +} + +/// Flexible pin driver. +pub struct Flex<'d, P = ErasedPin> { + pin: PeripheralRef<'d, P>, +} + +impl<'d> Flex<'d> { + /// Create flexible pin driver for a [Pin]. + /// No mode change happens. + #[inline] + pub fn new(pin: impl crate::peripheral::Peripheral

+ 'd) -> Self { + crate::into_ref!(pin); + let pin = pin.degrade_internal(private::Internal); + Self::new_typed(pin) + } +} + +impl<'d, P> Flex<'d, P> +where + P: Pin, +{ + /// Create flexible pin driver for a [Pin]. + /// No mode change happens. + #[inline] + pub fn new_typed(pin: impl crate::peripheral::Peripheral

+ 'd) -> Self { + crate::into_ref!(pin); + Self { pin } + } +} + +impl<'d, P> Flex<'d, P> +where + P: InputPin, +{ + /// Set the GPIO to input mode. + pub fn set_as_input(&mut self, pull: Pull) { + self.pin + .init_input(pull == Pull::Down, pull == Pull::Up, private::Internal); + } + + /// Get whether the pin input level is high. + #[inline] + pub fn is_high(&self) -> bool { + self.get_level() == Level::High + } + + /// Get whether the pin input level is low. + #[inline] + pub fn is_low(&self) -> bool { + self.get_level() == Level::Low + } + + /// Get the current pin input level. + #[inline] + pub fn get_level(&self) -> Level { + self.pin.is_input_high(private::Internal).into() } /// Listen for interrupts @@ -2004,72 +2278,25 @@ where } } -/// GPIO open-drain output driver. -pub struct OutputOpenDrain<'d, P> { - pin: PeripheralRef<'d, P>, -} - -impl<'d, P> OutputOpenDrain<'d, P> +impl<'d, P> Flex<'d, P> where - P: InputPin + OutputPin, + P: OutputPin, { - /// Create GPIO open-drain output driver for a [Pin] with the provided - /// initial output-level and [Pull] configuration. - #[inline] - pub fn new( - pin: impl crate::peripheral::Peripheral

+ 'd, - initial_output: Level, - pull: Pull, - ) -> Self { - crate::into_ref!(pin); - pin.set_output_high(initial_output.into(), private::Internal); - pin.set_to_open_drain_output(private::Internal); - pin.internal_pull_down(pull == Pull::Down, private::Internal); - pin.internal_pull_up(pull == Pull::Up, private::Internal); - - Self { pin } - } - - /// Get whether the pin input level is high. - #[inline] - pub fn is_high(&self) -> bool { - self.pin.is_input_high(private::Internal) - } - - /// Get whether the pin input level is low. - #[inline] - pub fn is_low(&self) -> bool { - !self.is_high() - } - - /// Get the current pin input level. - #[inline] - pub fn get_level(&self) -> Level { - self.is_high().into() - } - - /// Listen for interrupts - #[inline] - pub fn listen(&mut self, event: Event) { - self.pin.listen(event, private::Internal); - } - - /// Clear the interrupt status bit for this Pin - #[inline] - pub fn clear_interrupt(&mut self) { - self.pin.clear_interrupt(private::Internal); + /// Set the GPIO to output mode. + pub fn set_as_output(&mut self) { + self.pin.set_to_push_pull_output(private::Internal); } /// Set the output as high. #[inline] pub fn set_high(&mut self) { - self.pin.set_output_high(true, private::Internal); + self.set_level(Level::High) } /// Set the output as low. #[inline] pub fn set_low(&mut self) { - self.pin.set_output_high(false, private::Internal); + self.set_level(Level::Low) } /// Set the output level. @@ -2081,13 +2308,13 @@ where /// Is the output pin set as high? #[inline] pub fn is_set_high(&self) -> bool { - self.pin.is_set_high(private::Internal) + self.get_output_level() == Level::High } /// Is the output pin set as low? #[inline] pub fn is_set_low(&self) -> bool { - !self.pin.is_set_high(private::Internal) + self.get_output_level() == Level::Low } /// What level output is set to @@ -2099,8 +2326,8 @@ where /// Toggle pin output #[inline] pub fn toggle(&mut self) { - let level = !self.pin.is_set_high(private::Internal); - self.pin.set_output_high(level, private::Internal); + let level = !self.get_output_level(); + self.set_level(level); } /// Configure the [DriveStrength] of the pin @@ -2109,23 +2336,10 @@ where } } -/// GPIO flexible pin driver. -pub struct Flex<'d, P> { - pin: PeripheralRef<'d, P>, -} - impl<'d, P> Flex<'d, P> where P: InputPin + OutputPin, { - /// Create GPIO flexible pin driver for a [Pin]. - /// No mode change happens. - #[inline] - pub fn new(pin: impl crate::peripheral::Peripheral

+ 'd) -> Self { - crate::into_ref!(pin); - Self { pin } - } - /// Set the GPIO to open-drain mode. pub fn set_as_open_drain(&mut self, pull: Pull) { self.pin.set_to_open_drain_output(private::Internal); @@ -2134,439 +2348,6 @@ where self.pin .internal_pull_up(pull == Pull::Up, private::Internal); } - - /// Set the GPIO to input mode. - pub fn set_as_input(&mut self, pull: Pull) { - self.pin - .init_input(pull == Pull::Down, pull == Pull::Up, private::Internal); - } - - /// Set the GPIO to output mode. - pub fn set_as_output(&mut self) { - self.pin.set_to_push_pull_output(private::Internal); - } - - /// Get whether the pin input level is high. - #[inline] - pub fn is_high(&self) -> bool { - self.pin.is_input_high(private::Internal) - } - - /// Get whether the pin input level is low. - #[inline] - pub fn is_low(&self) -> bool { - !self.is_high() - } - - /// Get the current pin input level. - #[inline] - pub fn get_level(&self) -> Level { - self.is_high().into() - } - - /// Listen for interrupts - #[inline] - pub fn listen(&mut self, event: Event) { - self.pin.listen(event, private::Internal); - } - - /// Clear the interrupt status bit for this Pin - #[inline] - pub fn clear_interrupt(&mut self) { - self.pin.clear_interrupt(private::Internal); - } - - /// Set the output as high. - #[inline] - pub fn set_high(&mut self) { - self.pin.set_output_high(true, private::Internal); - } - - /// Set the output as low. - #[inline] - pub fn set_low(&mut self) { - self.pin.set_output_high(false, private::Internal); - } - - /// Set the output level. - #[inline] - pub fn set_level(&mut self, level: Level) { - self.pin.set_output_high(level.into(), private::Internal); - } - - /// Is the output pin set as high? - #[inline] - pub fn is_set_high(&self) -> bool { - self.pin.is_set_high(private::Internal) - } - - /// Is the output pin set as low? - #[inline] - pub fn is_set_low(&self) -> bool { - !self.pin.is_set_high(private::Internal) - } - - /// What level output is set to - #[inline] - pub fn get_output_level(&self) -> Level { - self.pin.is_set_high(private::Internal).into() - } - - /// Toggle pin output - #[inline] - pub fn toggle(&mut self) { - let level = !self.pin.is_set_high(private::Internal); - self.pin.set_output_high(level, private::Internal); - } - - /// Configure the [DriveStrength] of the pin - pub fn set_drive_strength(&mut self, strength: DriveStrength) { - self.pin.set_drive_strength(strength, private::Internal); - } -} - -/// Generic GPIO output driver. -pub struct AnyOutput<'d> { - pin: ErasedPin, - _phantom: PhantomData<&'d ()>, -} - -impl<'d> AnyOutput<'d> { - /// Create GPIO output driver for a [GpioPin] with the provided level - #[inline] - pub fn new( - pin: impl crate::peripheral::Peripheral

+ 'd, - initial_output: Level, - ) -> Self { - crate::into_ref!(pin); - - pin.set_output_high(initial_output.into(), private::Internal); - pin.set_to_push_pull_output(private::Internal); - - let pin = pin.erased_pin(private::Internal); - - Self { - pin, - _phantom: PhantomData, - } - } - - /// Set the output as high. - #[inline] - pub fn set_high(&mut self) { - self.pin.set_output_high(true, private::Internal); - } - - /// Set the output as low. - #[inline] - pub fn set_low(&mut self) { - self.pin.set_output_high(false, private::Internal); - } - - /// Set the output level. - #[inline] - pub fn set_level(&mut self, level: Level) { - self.pin.set_output_high(level.into(), private::Internal); - } - - /// Is the output pin set as high? - #[inline] - pub fn is_set_high(&self) -> bool { - self.pin.is_set_high(private::Internal) - } - - /// Is the output pin set as low? - #[inline] - pub fn is_set_low(&self) -> bool { - !self.pin.is_set_high(private::Internal) - } - - /// What level output is set to - #[inline] - pub fn get_output_level(&self) -> Level { - self.pin.is_set_high(private::Internal).into() - } - - /// Toggle pin output - #[inline] - pub fn toggle(&mut self) { - let pin = &mut self.pin; - pin.set_output_high(!pin.is_set_high(private::Internal), private::Internal); - } -} - -/// Generic GPIO input driver. -pub struct AnyInput<'d> { - pin: ErasedPin, - _phantom: PhantomData<&'d ()>, -} - -impl<'d> AnyInput<'d> { - /// Create GPIO input driver for a [Pin] with the provided [Pull] - /// configuration. - #[inline] - pub fn new( - pin: impl crate::peripheral::Peripheral

+ 'd, - pull: Pull, - ) -> Self { - crate::into_ref!(pin); - pin.init_input(pull == Pull::Down, pull == Pull::Up, private::Internal); - - let pin = pin.erased_pin(private::Internal); - - Self { - pin, - _phantom: PhantomData, - } - } - - /// Get whether the pin input level is high. - #[inline] - pub fn is_high(&self) -> bool { - self.pin.is_input_high(private::Internal) - } - - /// Get whether the pin input level is low. - #[inline] - pub fn is_low(&self) -> bool { - !self.is_high() - } - - /// Get the current pin input level. - #[inline] - pub fn get_level(&self) -> Level { - self.is_high().into() - } - - /// Listen for interrupts - #[inline] - pub fn listen(&mut self, event: Event) { - self.pin.listen(event, private::Internal); - } - - /// Clear the interrupt status bit for this Pin - #[inline] - pub fn clear_interrupt(&mut self) { - self.pin.clear_interrupt(private::Internal); - } -} - -/// Generic GPIO open-drain output driver. -pub struct AnyOutputOpenDrain<'d> { - pin: ErasedPin, - _phantom: PhantomData<&'d ()>, -} - -impl<'d> AnyOutputOpenDrain<'d> { - /// Create GPIO open-drain output driver for a [Pin] with the provided - /// initial output-level and [Pull] configuration. - #[inline] - pub fn new( - pin: impl crate::peripheral::Peripheral

+ 'd, - initial_output: Level, - pull: Pull, - ) -> Self { - crate::into_ref!(pin); - pin.set_output_high(initial_output.into(), private::Internal); - pin.internal_pull_down(pull == Pull::Down, private::Internal); - pin.internal_pull_up(pull == Pull::Up, private::Internal); - pin.set_to_open_drain_output(private::Internal); - - let pin = pin.erased_pin(private::Internal); - - Self { - pin, - _phantom: PhantomData, - } - } - - /// Get whether the pin input level is high. - #[inline] - pub fn is_high(&self) -> bool { - self.pin.is_input_high(private::Internal) - } - - /// Get whether the pin input level is low. - #[inline] - pub fn is_low(&self) -> bool { - !self.is_high() - } - - /// Get the current pin input level. - #[inline] - pub fn get_level(&self) -> Level { - self.is_high().into() - } - - /// Listen for interrupts - #[inline] - pub fn listen(&mut self, event: Event) { - self.pin.listen(event, private::Internal); - } - - /// Clear the interrupt status bit for this Pin - #[inline] - pub fn clear_interrupt(&mut self) { - self.pin.clear_interrupt(private::Internal); - } - - /// Set the output as high. - #[inline] - pub fn set_high(&mut self) { - self.pin.set_output_high(true, private::Internal); - } - - /// Set the output as low. - #[inline] - pub fn set_low(&mut self) { - self.pin.set_output_high(false, private::Internal); - } - - /// Set the output level. - #[inline] - pub fn set_level(&mut self, level: Level) { - self.pin.set_output_high(level.into(), private::Internal); - } - - /// Is the output pin set as high? - #[inline] - pub fn is_set_high(&self) -> bool { - self.pin.is_set_high(private::Internal) - } - - /// Is the output pin set as low? - #[inline] - pub fn is_set_low(&self) -> bool { - !self.pin.is_set_high(private::Internal) - } - - /// What level output is set to - #[inline] - pub fn get_output_level(&self) -> Level { - self.pin.is_set_high(private::Internal).into() - } - - /// Toggle pin output - #[inline] - pub fn toggle(&mut self) { - let pin = &mut self.pin; - pin.set_output_high(!pin.is_set_high(private::Internal), private::Internal); - } -} - -/// Generic GPIO flexible pin driver. -pub struct AnyFlex<'d> { - pin: ErasedPin, - _phantom: PhantomData<&'d ()>, -} - -impl<'d> AnyFlex<'d> { - /// Create GPIO flexible pin driver for a [Pin]. - /// No mode change happens. - #[inline] - pub fn new( - pin: impl crate::peripheral::Peripheral

+ 'd, - ) -> Self { - crate::into_ref!(pin); - let pin = pin.erased_pin(private::Internal); - Self { - pin, - _phantom: PhantomData, - } - } - - /// Set the GPIO to open-drain mode. - pub fn set_as_open_drain(&mut self, pull: Pull) { - self.pin.set_to_open_drain_output(private::Internal); - self.pin - .internal_pull_down(pull == Pull::Down, private::Internal); - self.pin - .internal_pull_up(pull == Pull::Up, private::Internal); - } - - /// Set the GPIO to input mode. - pub fn set_as_input(&mut self, pull: Pull) { - self.pin - .init_input(pull == Pull::Down, pull == Pull::Up, private::Internal); - } - - /// Set the GPIO to output mode. - pub fn set_as_output(&mut self) { - self.pin.set_to_push_pull_output(private::Internal); - } - - /// Get whether the pin input level is high. - #[inline] - pub fn is_high(&self) -> bool { - self.pin.is_input_high(private::Internal) - } - - /// Get whether the pin input level is low. - #[inline] - pub fn is_low(&self) -> bool { - !self.is_high() - } - - /// Get the current pin input level. - #[inline] - pub fn get_level(&self) -> Level { - self.is_high().into() - } - - /// Listen for interrupts - #[inline] - pub fn listen(&mut self, event: Event) { - self.pin.listen(event, private::Internal); - } - - /// Clear the interrupt status bit for this Pin - #[inline] - pub fn clear_interrupt(&mut self) { - self.pin.clear_interrupt(private::Internal); - } - - /// Set the output as high. - #[inline] - pub fn set_high(&mut self) { - self.pin.set_output_high(true, private::Internal); - } - - /// Set the output as low. - #[inline] - pub fn set_low(&mut self) { - self.pin.set_output_high(false, private::Internal); - } - - /// Set the output level. - #[inline] - pub fn set_level(&mut self, level: Level) { - self.pin.set_output_high(level.into(), private::Internal); - } - - /// Is the output pin set as high? - #[inline] - pub fn is_set_high(&self) -> bool { - self.pin.is_set_high(private::Internal) - } - - /// Is the output pin set as low? - #[inline] - pub fn is_set_low(&self) -> bool { - !self.pin.is_set_high(private::Internal) - } - - /// What level output is set to - #[inline] - pub fn get_output_level(&self) -> Level { - self.pin.is_set_high(private::Internal).into() - } - - /// Toggle pin output - #[inline] - pub fn toggle(&mut self) { - let pin = &mut self.pin; - pin.set_output_high(!pin.is_set_high(private::Internal), private::Internal); - } } pub(crate) mod internal { @@ -2579,6 +2360,10 @@ pub(crate) mod internal { handle_gpio_input!(self, target, { Pin::number(target, private::Internal) }) } + fn degrade_internal(&self, _: private::Internal) -> ErasedPin { + unsafe { self.clone_unchecked() } + } + fn sleep_mode(&mut self, on: bool, _: private::Internal) { handle_gpio_input!(self, target, { Pin::sleep_mode(target, on, private::Internal) @@ -2822,7 +2607,7 @@ mod asynch { const NEW_AW: AtomicWaker = AtomicWaker::new(); static PIN_WAKERS: [AtomicWaker; NUM_PINS] = [NEW_AW; NUM_PINS]; - impl<'d, P> Input<'d, P> + impl<'d, P> Flex<'d, P> where P: InputPin, { @@ -2859,37 +2644,35 @@ mod asynch { } } - impl<'d> AnyInput<'d> { + impl<'d, P> Input<'d, P> + where + P: InputPin, + { /// Wait until the pin is high. If it is already high, return /// immediately. pub async fn wait_for_high(&mut self) { - self.listen(Event::HighLevel); - PinFuture::new(self.pin.number(private::Internal)).await + self.pin.wait_for_high().await } /// Wait until the pin is low. If it is already low, return immediately. pub async fn wait_for_low(&mut self) { - self.listen(Event::LowLevel); - PinFuture::new(self.pin.number(private::Internal)).await + self.pin.wait_for_low().await } /// Wait for the pin to undergo a transition from low to high. pub async fn wait_for_rising_edge(&mut self) { - self.listen(Event::RisingEdge); - PinFuture::new(self.pin.number(private::Internal)).await + self.pin.wait_for_rising_edge().await } /// Wait for the pin to undergo a transition from high to low. pub async fn wait_for_falling_edge(&mut self) { - self.listen(Event::FallingEdge); - PinFuture::new(self.pin.number(private::Internal)).await + self.pin.wait_for_falling_edge().await } /// Wait for the pin to undergo any transition, i.e low to high OR high /// to low. pub async fn wait_for_any_edge(&mut self) { - self.listen(Event::AnyEdge); - PinFuture::new(self.pin.number(private::Internal)).await + self.pin.wait_for_any_edge().await } } @@ -2990,10 +2773,10 @@ mod embedded_hal_02_impls { type Error = core::convert::Infallible; fn is_high(&self) -> Result { - Ok(self.pin.is_input_high(private::Internal)) + Ok(self.pin.is_high()) } fn is_low(&self) -> Result { - Ok(!self.pin.is_input_high(private::Internal)) + Ok(self.pin.is_low()) } } @@ -3004,11 +2787,11 @@ mod embedded_hal_02_impls { type Error = core::convert::Infallible; fn set_high(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(true, private::Internal); + self.pin.is_set_high(); Ok(()) } fn set_low(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(false, private::Internal); + self.pin.is_set_low(); Ok(()) } } @@ -3044,10 +2827,10 @@ mod embedded_hal_02_impls { type Error = core::convert::Infallible; fn is_high(&self) -> Result { - Ok(self.pin.is_input_high(private::Internal)) + Ok(self.pin.is_high()) } fn is_low(&self) -> Result { - Ok(!self.pin.is_input_high(private::Internal)) + Ok(self.pin.is_low()) } } @@ -3058,11 +2841,12 @@ mod embedded_hal_02_impls { type Error = core::convert::Infallible; fn set_high(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(true, private::Internal); + self.set_high(); Ok(()) } + fn set_low(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(false, private::Internal); + self.set_low(); Ok(()) } } @@ -3098,10 +2882,10 @@ mod embedded_hal_02_impls { type Error = core::convert::Infallible; fn is_high(&self) -> Result { - Ok(self.pin.is_input_high(private::Internal)) + Ok(self.is_high()) } fn is_low(&self) -> Result { - Ok(!self.pin.is_input_high(private::Internal)) + Ok(self.is_low()) } } @@ -3144,132 +2928,6 @@ mod embedded_hal_02_impls { Ok(()) } } - - impl<'d> digital::InputPin for AnyInput<'d> { - type Error = core::convert::Infallible; - - fn is_high(&self) -> Result { - Ok(self.pin.is_input_high(private::Internal)) - } - fn is_low(&self) -> Result { - Ok(!self.pin.is_input_high(private::Internal)) - } - } - - impl<'d> digital::OutputPin for AnyOutput<'d> { - type Error = core::convert::Infallible; - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(true, private::Internal); - Ok(()) - } - fn set_low(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(false, private::Internal); - Ok(()) - } - } - - impl<'d> digital::StatefulOutputPin for AnyOutput<'d> { - fn is_set_high(&self) -> Result { - Ok(self.is_set_high()) - } - fn is_set_low(&self) -> Result { - Ok(self.is_set_low()) - } - } - - impl<'d> digital::ToggleableOutputPin for AnyOutput<'d> { - type Error = core::convert::Infallible; - - fn toggle(&mut self) -> Result<(), Self::Error> { - self.toggle(); - Ok(()) - } - } - - impl<'d> digital::InputPin for AnyOutputOpenDrain<'d> { - type Error = core::convert::Infallible; - - fn is_high(&self) -> Result { - Ok(self.pin.is_input_high(private::Internal)) - } - fn is_low(&self) -> Result { - Ok(!self.pin.is_input_high(private::Internal)) - } - } - - impl<'d> digital::OutputPin for AnyOutputOpenDrain<'d> { - type Error = core::convert::Infallible; - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(true, private::Internal); - Ok(()) - } - fn set_low(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(false, private::Internal); - Ok(()) - } - } - - impl<'d> digital::StatefulOutputPin for AnyOutputOpenDrain<'d> { - fn is_set_high(&self) -> Result { - Ok(self.is_set_high()) - } - fn is_set_low(&self) -> Result { - Ok(self.is_set_low()) - } - } - - impl<'d> digital::ToggleableOutputPin for AnyOutputOpenDrain<'d> { - type Error = core::convert::Infallible; - - fn toggle(&mut self) -> Result<(), Self::Error> { - self.toggle(); - Ok(()) - } - } - - impl<'d> digital::InputPin for AnyFlex<'d> { - type Error = core::convert::Infallible; - - fn is_high(&self) -> Result { - Ok(self.pin.is_input_high(private::Internal)) - } - fn is_low(&self) -> Result { - Ok(!self.pin.is_input_high(private::Internal)) - } - } - - impl<'d> digital::OutputPin for AnyFlex<'d> { - type Error = core::convert::Infallible; - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(true, private::Internal); - Ok(()) - } - fn set_low(&mut self) -> Result<(), Self::Error> { - self.pin.set_output_high(false, private::Internal); - Ok(()) - } - } - - impl<'d> digital::StatefulOutputPin for AnyFlex<'d> { - fn is_set_high(&self) -> Result { - Ok(self.is_set_high()) - } - fn is_set_low(&self) -> Result { - Ok(self.is_set_low()) - } - } - - impl<'d> digital::ToggleableOutputPin for AnyFlex<'d> { - type Error = core::convert::Infallible; - - fn toggle(&mut self) -> Result<(), Self::Error> { - self.toggle(); - Ok(()) - } - } } mod embedded_hal_impls { @@ -3289,11 +2947,11 @@ mod embedded_hal_impls { P: InputPin, { fn is_high(&mut self) -> Result { - Ok(Input::is_high(self)) + Ok(Self::is_high(self)) } fn is_low(&mut self) -> Result { - Ok(Input::is_low(self)) + Ok(Self::is_low(self)) } } @@ -3309,12 +2967,12 @@ mod embedded_hal_impls { P: OutputPin, { fn set_low(&mut self) -> Result<(), Self::Error> { - self.set_low(); + Self::set_low(self); Ok(()) } fn set_high(&mut self) -> Result<(), Self::Error> { - self.set_high(); + Self::set_high(self); Ok(()) } } @@ -3337,11 +2995,11 @@ mod embedded_hal_impls { P: InputPin + OutputPin, { fn is_high(&mut self) -> Result { - Ok(OutputOpenDrain::is_high(self)) + Ok(Self::is_high(self)) } fn is_low(&mut self) -> Result { - Ok(OutputOpenDrain::is_low(self)) + Ok(Self::is_low(self)) } } @@ -3357,12 +3015,12 @@ mod embedded_hal_impls { P: InputPin + OutputPin, { fn set_low(&mut self) -> Result<(), Self::Error> { - self.set_low(); + Self::set_low(self); Ok(()) } fn set_high(&mut self) -> Result<(), Self::Error> { - self.set_high(); + Self::set_high(self); Ok(()) } } @@ -3382,42 +3040,39 @@ mod embedded_hal_impls { impl<'d, P> digital::InputPin for Flex<'d, P> where - P: InputPin + OutputPin, + P: InputPin, { fn is_high(&mut self) -> Result { - Ok(Flex::is_high(self)) + Ok(Self::is_high(self)) } fn is_low(&mut self) -> Result { - Ok(Flex::is_low(self)) + Ok(Self::is_low(self)) } } - impl<'d, P> digital::ErrorType for Flex<'d, P> - where - P: InputPin + OutputPin, - { + impl<'d, P> digital::ErrorType for Flex<'d, P> { type Error = core::convert::Infallible; } impl<'d, P> digital::OutputPin for Flex<'d, P> where - P: InputPin + OutputPin, + P: OutputPin, { fn set_low(&mut self) -> Result<(), Self::Error> { - self.set_low(); + Self::set_low(self); Ok(()) } fn set_high(&mut self) -> Result<(), Self::Error> { - self.set_high(); + Self::set_high(self); Ok(()) } } impl<'d, P> digital::StatefulOutputPin for Flex<'d, P> where - P: InputPin + OutputPin, + P: OutputPin, { fn is_set_high(&mut self) -> Result { Ok(Self::is_set_high(self)) @@ -3427,98 +3082,6 @@ mod embedded_hal_impls { Ok(Self::is_set_low(self)) } } - - impl<'d> digital::ErrorType for AnyInput<'d> { - type Error = core::convert::Infallible; - } - - impl<'d> digital::InputPin for AnyInput<'d> { - fn is_high(&mut self) -> Result { - Ok(AnyInput::is_high(self)) - } - - fn is_low(&mut self) -> Result { - Ok(AnyInput::is_low(self)) - } - } - - impl<'d> digital::ErrorType for AnyOutput<'d> { - type Error = core::convert::Infallible; - } - - impl<'d> digital::OutputPin for AnyOutput<'d> { - fn set_low(&mut self) -> Result<(), Self::Error> { - self.set_low(); - Ok(()) - } - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.set_high(); - Ok(()) - } - } - - impl<'d> digital::StatefulOutputPin for AnyOutput<'d> { - fn is_set_high(&mut self) -> Result { - Ok(Self::is_set_high(self)) - } - - fn is_set_low(&mut self) -> Result { - Ok(Self::is_set_low(self)) - } - } - - impl<'d> digital::ErrorType for AnyOutputOpenDrain<'d> { - type Error = core::convert::Infallible; - } - - impl<'d> digital::OutputPin for AnyOutputOpenDrain<'d> { - fn set_low(&mut self) -> Result<(), Self::Error> { - self.set_low(); - Ok(()) - } - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.set_high(); - Ok(()) - } - } - - impl<'d> digital::StatefulOutputPin for AnyOutputOpenDrain<'d> { - fn is_set_high(&mut self) -> Result { - Ok(Self::is_set_high(self)) - } - - fn is_set_low(&mut self) -> Result { - Ok(Self::is_set_low(self)) - } - } - - impl<'d> digital::ErrorType for AnyFlex<'d> { - type Error = core::convert::Infallible; - } - - impl<'d> digital::OutputPin for AnyFlex<'d> { - fn set_low(&mut self) -> Result<(), Self::Error> { - self.set_low(); - Ok(()) - } - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.set_high(); - Ok(()) - } - } - - impl<'d> digital::StatefulOutputPin for AnyFlex<'d> { - fn is_set_high(&mut self) -> Result { - Ok(Self::is_set_high(self)) - } - - fn is_set_low(&mut self) -> Result { - Ok(Self::is_set_low(self)) - } - } } mod embedded_hal_async_impls { @@ -3526,59 +3089,62 @@ mod embedded_hal_async_impls { use super::*; + impl<'d, P> Wait for Flex<'d, P> + where + P: InputPin, + { + async fn wait_for_high(&mut self) -> Result<(), Self::Error> { + Self::wait_for_high(self).await; + Ok(()) + } + + async fn wait_for_low(&mut self) -> Result<(), Self::Error> { + Self::wait_for_low(self).await; + Ok(()) + } + + async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> { + Self::wait_for_rising_edge(self).await; + Ok(()) + } + + async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> { + Self::wait_for_falling_edge(self).await; + Ok(()) + } + + async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> { + Self::wait_for_any_edge(self).await; + Ok(()) + } + } + impl<'d, P> Wait for Input<'d, P> where P: InputPin, { async fn wait_for_high(&mut self) -> Result<(), Self::Error> { - self.wait_for_high().await; + Self::wait_for_high(self).await; Ok(()) } async fn wait_for_low(&mut self) -> Result<(), Self::Error> { - self.wait_for_low().await; + Self::wait_for_low(self).await; Ok(()) } async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> { - self.wait_for_rising_edge().await; + Self::wait_for_rising_edge(self).await; Ok(()) } async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> { - self.wait_for_falling_edge().await; + Self::wait_for_falling_edge(self).await; Ok(()) } async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> { - self.wait_for_any_edge().await; - Ok(()) - } - } - - impl<'d> Wait for AnyInput<'d> { - async fn wait_for_high(&mut self) -> Result<(), Self::Error> { - self.wait_for_high().await; - Ok(()) - } - - async fn wait_for_low(&mut self) -> Result<(), Self::Error> { - self.wait_for_low().await; - Ok(()) - } - - async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> { - self.wait_for_rising_edge().await; - Ok(()) - } - - async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> { - self.wait_for_falling_edge().await; - Ok(()) - } - - async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> { - self.wait_for_any_edge().await; + Self::wait_for_any_edge(self).await; Ok(()) } } diff --git a/examples/src/bin/blinky_erased_pins.rs b/examples/src/bin/blinky_erased_pins.rs index c34d3d121..93d23e56f 100644 --- a/examples/src/bin/blinky_erased_pins.rs +++ b/examples/src/bin/blinky_erased_pins.rs @@ -14,7 +14,7 @@ use esp_backtrace as _; use esp_hal::{ delay::Delay, - gpio::{AnyInput, AnyOutput, Io, Level, Pull}, + gpio::{ErasedPin, Input, Io, Level, Output, Pin, Pull}, prelude::*, }; @@ -25,17 +25,17 @@ fn main() -> ! { let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); // Set LED GPIOs as an output: - let led1 = AnyOutput::new(io.pins.gpio2, Level::Low); - let led2 = AnyOutput::new(io.pins.gpio4, Level::Low); - let led3 = AnyOutput::new(io.pins.gpio5, Level::Low); + let led1 = Output::new(io.pins.gpio2.degrade(), Level::Low); + let led2 = Output::new(io.pins.gpio4.degrade(), Level::Low); + let led3 = Output::new(io.pins.gpio5.degrade(), Level::Low); // Use boot button as an input: #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] - let button = io.pins.gpio0; + let button = io.pins.gpio0.degrade(); #[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))] - let button = io.pins.gpio9; + let button = io.pins.gpio9.degrade(); - let button = AnyInput::new(button, Pull::Up); + let button = Input::new(button, Pull::Up); let mut pins = [led1, led2, led3]; @@ -47,7 +47,7 @@ fn main() -> ! { } } -fn toggle_pins(leds: &mut [AnyOutput], button: &AnyInput) { +fn toggle_pins(leds: &mut [Output], button: &Input) { for pin in leds.iter_mut() { pin.toggle(); } diff --git a/examples/src/bin/embassy_multicore.rs b/examples/src/bin/embassy_multicore.rs index ddebf657f..7d871f2b0 100644 --- a/examples/src/bin/embassy_multicore.rs +++ b/examples/src/bin/embassy_multicore.rs @@ -21,7 +21,7 @@ use esp_backtrace as _; use esp_hal::{ cpu_control::{CpuControl, Stack}, get_core, - gpio::{AnyOutput, Io, Level}, + gpio::{ErasedPin, Io, Level, Output, Pin}, timer::{timg::TimerGroup, ErasedTimer}, }; use esp_hal_embassy::Executor; @@ -34,7 +34,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new(); /// duration of time. #[embassy_executor::task] async fn control_led( - mut led: AnyOutput<'static>, + mut led: Output<'static, ErasedPin>, control: &'static Signal, ) { println!("Starting control_led() on core {}", get_core() as usize); @@ -65,7 +65,7 @@ async fn main(_spawner: Spawner) { static LED_CTRL: StaticCell> = StaticCell::new(); let led_ctrl_signal = &*LED_CTRL.init(Signal::new()); - let led = AnyOutput::new(io.pins.gpio0, Level::Low); + let led = Output::new(io.pins.gpio0.degrade(), Level::Low); let _guard = cpu_control .start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) }, move || { diff --git a/examples/src/bin/embassy_multicore_interrupt.rs b/examples/src/bin/embassy_multicore_interrupt.rs index 23fa2ee0d..0c69a468f 100644 --- a/examples/src/bin/embassy_multicore_interrupt.rs +++ b/examples/src/bin/embassy_multicore_interrupt.rs @@ -20,7 +20,7 @@ use esp_backtrace as _; use esp_hal::{ cpu_control::{CpuControl, Stack}, get_core, - gpio::{AnyOutput, Io, Level}, + gpio::{ErasedPin, Io, Level, Output, Pin}, interrupt::{software::SoftwareInterruptControl, Priority}, prelude::*, timer::{timg::TimerGroup, ErasedTimer}, @@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new(); /// duration of time. #[embassy_executor::task] async fn control_led( - mut led: AnyOutput<'static>, + mut led: Output<'static, ErasedPin>, control: &'static Signal, ) { println!("Starting control_led() on core {}", get_core() as usize); @@ -87,7 +87,7 @@ fn main() -> ! { static LED_CTRL: StaticCell> = StaticCell::new(); let led_ctrl_signal = &*LED_CTRL.init(Signal::new()); - let led = AnyOutput::new(io.pins.gpio0, Level::Low); + let led = Output::new(io.pins.gpio0.degrade(), Level::Low); static EXECUTOR_CORE_1: StaticCell> = StaticCell::new(); let executor_core1 = InterruptExecutor::new(sw_ints.software_interrupt1); diff --git a/examples/src/bin/embassy_rmt_rx.rs b/examples/src/bin/embassy_rmt_rx.rs index cd2a4040e..0befacef8 100644 --- a/examples/src/bin/embassy_rmt_rx.rs +++ b/examples/src/bin/embassy_rmt_rx.rs @@ -13,7 +13,7 @@ use embassy_executor::Spawner; use embassy_time::{Duration, Timer}; use esp_backtrace as _; use esp_hal::{ - gpio::{GpioPin, Io, Level, Output}, + gpio::{Io, Level, Output}, prelude::*, rmt::{asynch::RxChannelAsync, PulseCode, Rmt, RxChannelConfig, RxChannelCreatorAsync}, timer::timg::TimerGroup, @@ -26,7 +26,7 @@ const WIDTH: usize = 80; compile_error!("Run this example in release mode"); #[embassy_executor::task] -async fn signal_task(mut pin: Output<'static, GpioPin<5>>) { +async fn signal_task(mut pin: Output<'static>) { loop { for _ in 0..10 { pin.toggle(); diff --git a/examples/src/bin/gpio_interrupt.rs b/examples/src/bin/gpio_interrupt.rs index 0c1021833..c59955549 100644 --- a/examples/src/bin/gpio_interrupt.rs +++ b/examples/src/bin/gpio_interrupt.rs @@ -17,20 +17,12 @@ use critical_section::Mutex; use esp_backtrace as _; use esp_hal::{ delay::Delay, - gpio::{Event, GpioPin, Input, Io, Level, Output, Pull}, + gpio::{Event, Input, Io, Level, Output, Pull}, macros::ram, prelude::*, }; -cfg_if::cfg_if! { - if #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] { - const BUTTON_PIN: u8 = 0; - } else { - const BUTTON_PIN: u8 = 9; - } -} - -static BUTTON: Mutex>>>> = Mutex::new(RefCell::new(None)); +static BUTTON: Mutex>> = Mutex::new(RefCell::new(None)); #[entry] fn main() -> ! { diff --git a/examples/src/bin/spi_slave_dma.rs b/examples/src/bin/spi_slave_dma.rs index 8996ce6f3..6631a5ed3 100644 --- a/examples/src/bin/spi_slave_dma.rs +++ b/examples/src/bin/spi_slave_dma.rs @@ -34,7 +34,7 @@ use esp_hal::{ delay::Delay, dma::{Dma, DmaPriority}, dma_buffers, - gpio::{GpioPin, Input, Io, Level, Output, Pull}, + gpio::{Input, Io, Level, Output, Pull}, prelude::*, spi::{ slave::{prelude::*, Spi}, @@ -48,17 +48,16 @@ fn main() -> ! { let peripherals = esp_hal::init(esp_hal::Config::default()); let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); - let slave_sclk = io.pins.gpio0; + let mut master_sclk = Output::new(io.pins.gpio4, Level::Low); - let slave_miso = io.pins.gpio1; let master_miso = Input::new(io.pins.gpio5, Pull::None); - let slave_mosi = io.pins.gpio2; let mut master_mosi = Output::new(io.pins.gpio8, Level::Low); + let mut master_cs = Output::new(io.pins.gpio9, Level::High); + + let slave_sclk = io.pins.gpio0; + let slave_miso = io.pins.gpio1; + let slave_mosi = io.pins.gpio2; let slave_cs = io.pins.gpio3; - let mut master_cs = Output::new(io.pins.gpio9, Level::Low); - master_cs.set_high(); - master_sclk.set_low(); - master_mosi.set_low(); let dma = Dma::new(peripherals.DMA); cfg_if::cfg_if! { @@ -189,10 +188,10 @@ fn main() -> ! { fn bitbang_master( master_send: &[u8], master_receive: &mut [u8], - master_cs: &mut Output>, - master_mosi: &mut Output>, - master_sclk: &mut Output>, - master_miso: &Input>, + master_cs: &mut Output, + master_mosi: &mut Output, + master_sclk: &mut Output, + master_miso: &Input, ) { // Bit-bang out the contents of master_send and read into master_receive // as quickly as manageable. MSB first. Mode 0, so sampled on the rising diff --git a/hil-test/src/lib.rs b/hil-test/src/lib.rs index b00876759..d1c9835c6 100644 --- a/hil-test/src/lib.rs +++ b/hil-test/src/lib.rs @@ -49,8 +49,7 @@ macro_rules! common_test_pins { cfg_if::cfg_if! { if #[cfg(any(esp32s2, esp32s3))] { ($io.pins.gpio9, $io.pins.gpio10) - } - else { + } else { ($io.pins.gpio2, $io.pins.gpio3) } } diff --git a/hil-test/tests/aes_dma.rs b/hil-test/tests/aes_dma.rs index f86e95bc4..1f8861c48 100644 --- a/hil-test/tests/aes_dma.rs +++ b/hil-test/tests/aes_dma.rs @@ -14,7 +14,6 @@ use esp_hal::{ dma::{Dma, DmaPriority}, dma_buffers, peripherals::Peripherals, - prelude::*, }; use hil_test as _; diff --git a/hil-test/tests/delay.rs b/hil-test/tests/delay.rs index 82296ed94..e5a9dae3e 100644 --- a/hil-test/tests/delay.rs +++ b/hil-test/tests/delay.rs @@ -20,7 +20,7 @@ mod tests { #[init] fn init() -> Context { - let peripherals = esp_hal::init(esp_hal::Config::default()); + let _peripherals = esp_hal::init(esp_hal::Config::default()); let delay = Delay::new(); Context { delay } diff --git a/hil-test/tests/get_time.rs b/hil-test/tests/get_time.rs index 6c7eadecd..7a126459f 100644 --- a/hil-test/tests/get_time.rs +++ b/hil-test/tests/get_time.rs @@ -61,7 +61,7 @@ mod tests { #[test] #[timeout(3)] fn test_current_time_construct_timg0(ctx: Context) { - time_moves_forward_during(ctx, |ctx| { + time_moves_forward_during(ctx, |_| { // construct the timer in between calls to current_time let _ = esp_hal::timer::timg::TimerGroup::new(unsafe { esp_hal::peripherals::TIMG0::steal() diff --git a/hil-test/tests/gpio.rs b/hil-test/tests/gpio.rs index 2b395de0c..4caba762a 100644 --- a/hil-test/tests/gpio.rs +++ b/hil-test/tests/gpio.rs @@ -15,7 +15,7 @@ use core::cell::RefCell; use critical_section::Mutex; use esp_hal::{ delay::Delay, - gpio::{AnyPin, GpioPin, Input, Io, Level, Output, Pull}, + gpio::{AnyPin, ErasedPin, Input, Io, Level, Output, Pin, Pull}, macros::handler, timer::timg::TimerGroup, InterruptConfigurable, @@ -23,22 +23,11 @@ use esp_hal::{ use hil_test as _; static COUNTER: Mutex> = Mutex::new(RefCell::new(0)); -static INPUT_PIN: Mutex>>> = - Mutex::new(RefCell::new(None)); +static INPUT_PIN: Mutex>> = Mutex::new(RefCell::new(None)); -cfg_if::cfg_if! { - if #[cfg(not(any(esp32s2, esp32s3)))] { - pub type TestGpio1 = GpioPin<2>; - pub type TestGpio2 = GpioPin<3>; - } else if #[cfg(any(esp32s2, esp32s3))] { - pub type TestGpio1 = GpioPin<9>; - pub type TestGpio2 = GpioPin<10>; - } -} - -struct Context<'d> { - test_gpio1: Input<'d, TestGpio1>, - test_gpio2: Output<'d, TestGpio2>, +struct Context { + test_gpio1: ErasedPin, + test_gpio2: ErasedPin, delay: Delay, } @@ -64,7 +53,7 @@ mod tests { use super::*; #[init] - fn init() -> Context<'static> { + fn init() -> Context { let peripherals = esp_hal::init(esp_hal::Config::default()); let mut io = Io::new(peripherals.GPIO, peripherals.IO_MUX); @@ -78,20 +67,22 @@ mod tests { esp_hal_embassy::init(timg0.timer0); Context { - test_gpio1: Input::new(gpio1, Pull::Down), - test_gpio2: Output::new(gpio2, Level::Low), + test_gpio1: gpio1.degrade(), + test_gpio2: gpio2.degrade(), delay, } } #[test] - async fn test_async_edge(ctx: Context<'static>) { + async fn test_async_edge(ctx: Context) { let counter = AtomicUsize::new(0); let Context { - mut test_gpio1, - mut test_gpio2, + test_gpio1, + test_gpio2, .. } = ctx; + let mut test_gpio1 = Input::new(test_gpio1, Pull::Down); + let mut test_gpio2 = Output::new(test_gpio2, Level::Low); embassy_futures::select::select( async { loop { @@ -113,8 +104,8 @@ mod tests { } #[test] - async fn test_a_pin_can_wait(_ctx: Context<'static>) { - let mut first = Input::new(unsafe { GpioPin::<0>::steal() }, Pull::Down); + async fn test_a_pin_can_wait(ctx: Context) { + let mut first = Input::new(ctx.test_gpio1, Pull::Down); embassy_futures::select::select( first.wait_for_rising_edge(), @@ -126,69 +117,74 @@ mod tests { } #[test] - fn test_gpio_input(ctx: Context<'static>) { + fn test_gpio_input(ctx: Context) { + let test_gpio1 = Input::new(ctx.test_gpio1, Pull::Down); // `InputPin`: - assert_eq!(ctx.test_gpio1.is_low(), true); - assert_eq!(ctx.test_gpio1.is_high(), false); + assert_eq!(test_gpio1.is_low(), true); + assert_eq!(test_gpio1.is_high(), false); } #[test] - fn test_gpio_output(mut ctx: Context<'static>) { + fn test_gpio_output(ctx: Context) { + let mut test_gpio2 = Output::new(ctx.test_gpio2, Level::Low); + // `StatefulOutputPin`: - assert_eq!(ctx.test_gpio2.is_set_low(), true); - assert_eq!(ctx.test_gpio2.is_set_high(), false); - ctx.test_gpio2.set_high(); - assert_eq!(ctx.test_gpio2.is_set_low(), false); - assert_eq!(ctx.test_gpio2.is_set_high(), true); + assert_eq!(test_gpio2.is_set_low(), true); + assert_eq!(test_gpio2.is_set_high(), false); + test_gpio2.set_high(); + assert_eq!(test_gpio2.is_set_low(), false); + assert_eq!(test_gpio2.is_set_high(), true); // `ToggleableOutputPin`: - ctx.test_gpio2.toggle(); - assert_eq!(ctx.test_gpio2.is_set_low(), true); - assert_eq!(ctx.test_gpio2.is_set_high(), false); - ctx.test_gpio2.toggle(); - assert_eq!(ctx.test_gpio2.is_set_low(), false); - assert_eq!(ctx.test_gpio2.is_set_high(), true); + test_gpio2.toggle(); + assert_eq!(test_gpio2.is_set_low(), true); + assert_eq!(test_gpio2.is_set_high(), false); + test_gpio2.toggle(); + assert_eq!(test_gpio2.is_set_low(), false); + assert_eq!(test_gpio2.is_set_high(), true); } #[test] - fn test_gpio_interrupt(mut ctx: Context<'static>) { + fn test_gpio_interrupt(ctx: Context) { + let mut test_gpio1 = Input::new(ctx.test_gpio1, Pull::Down); + let mut test_gpio2 = Output::new(ctx.test_gpio2, Level::Low); + critical_section::with(|cs| { *COUNTER.borrow_ref_mut(cs) = 0; - ctx.test_gpio1.listen(Event::AnyEdge); - INPUT_PIN.borrow_ref_mut(cs).replace(ctx.test_gpio1); + test_gpio1.listen(Event::AnyEdge); + INPUT_PIN.borrow_ref_mut(cs).replace(test_gpio1); }); - ctx.test_gpio2.set_high(); + test_gpio2.set_high(); ctx.delay.delay_millis(1); - ctx.test_gpio2.set_low(); + test_gpio2.set_low(); ctx.delay.delay_millis(1); - ctx.test_gpio2.set_high(); + test_gpio2.set_high(); ctx.delay.delay_millis(1); - ctx.test_gpio2.set_low(); + test_gpio2.set_low(); ctx.delay.delay_millis(1); - ctx.test_gpio2.set_high(); + test_gpio2.set_high(); ctx.delay.delay_millis(1); - ctx.test_gpio2.set_low(); + test_gpio2.set_low(); ctx.delay.delay_millis(1); - ctx.test_gpio2.set_high(); + test_gpio2.set_high(); ctx.delay.delay_millis(1); - ctx.test_gpio2.set_low(); + test_gpio2.set_low(); ctx.delay.delay_millis(1); - ctx.test_gpio2.set_high(); + test_gpio2.set_high(); ctx.delay.delay_millis(1); let count = critical_section::with(|cs| *COUNTER.borrow_ref(cs)); assert_eq!(count, 9); - ctx.test_gpio1 = critical_section::with(|cs| INPUT_PIN.borrow_ref_mut(cs).take().unwrap()); - ctx.test_gpio1.unlisten(); - } - - #[test] - fn test_gpio_od(ctx: Context<'static>) { let mut test_gpio1 = - OutputOpenDrain::new(unsafe { TestGpio1::steal() }, Level::High, Pull::Up); - let mut test_gpio2 = - OutputOpenDrain::new(unsafe { TestGpio2::steal() }, Level::High, Pull::Up); + critical_section::with(|cs| INPUT_PIN.borrow_ref_mut(cs).take().unwrap()); + test_gpio1.unlisten(); + } + + #[test] + fn test_gpio_od(ctx: Context) { + let mut test_gpio1 = OutputOpenDrain::new(ctx.test_gpio1, Level::High, Pull::Up); + let mut test_gpio2 = OutputOpenDrain::new(ctx.test_gpio2, Level::High, Pull::Up); ctx.delay.delay_millis(1); @@ -232,9 +228,9 @@ mod tests { } #[test] - fn test_gpio_flex(ctx: Context<'static>) { - let mut test_gpio1 = Flex::new(unsafe { TestGpio1::steal() }); - let mut test_gpio2 = Flex::new(unsafe { TestGpio2::steal() }); + fn test_gpio_flex(ctx: Context) { + let mut test_gpio1 = Flex::new(ctx.test_gpio1); + let mut test_gpio2 = Flex::new(ctx.test_gpio2); test_gpio1.set_high(); test_gpio1.set_as_output(); @@ -274,9 +270,9 @@ mod tests { // Tests touch pin (GPIO2) as AnyPin and Output // https://github.com/esp-rs/esp-hal/issues/1943 #[test] - fn test_gpio_touch_anypin_output() { - let any_pin2 = AnyPin::new(unsafe { TestGpio1::steal() }); - let any_pin3 = AnyPin::new(unsafe { TestGpio2::steal() }); + fn test_gpio_touch_anypin_output(ctx: Context) { + let any_pin2 = AnyPin::new(ctx.test_gpio1); + let any_pin3 = AnyPin::new(ctx.test_gpio2); let out_pin = Output::new(any_pin2, Level::High); let in_pin = Input::new(any_pin3, Pull::Down); @@ -288,9 +284,9 @@ mod tests { // Tests touch pin (GPIO2) as AnyPin and Input // https://github.com/esp-rs/esp-hal/issues/1943 #[test] - fn test_gpio_touch_anypin_input() { - let any_pin2 = AnyPin::new(unsafe { TestGpio1::steal() }); - let any_pin3 = AnyPin::new(unsafe { TestGpio2::steal() }); + fn test_gpio_touch_anypin_input(ctx: Context) { + let any_pin2 = AnyPin::new(ctx.test_gpio1); + let any_pin3 = AnyPin::new(ctx.test_gpio2); let out_pin = Output::new(any_pin3, Level::Low); let in_pin = Input::new(any_pin2, Pull::Down); diff --git a/hil-test/tests/qspi_read.rs b/hil-test/tests/qspi_read.rs index 7aeb77064..c6de7c38d 100644 --- a/hil-test/tests/qspi_read.rs +++ b/hil-test/tests/qspi_read.rs @@ -15,7 +15,7 @@ use esp_hal::{ dma::{Channel, Dma, DmaPriority, DmaRxBuf}, dma_buffers, - gpio::{AnyOutput, AnyPin, Io, Level}, + gpio::{ErasedPin, Io, Level, Output}, prelude::*, spi::{ master::{Address, Command, Spi, SpiDma}, @@ -41,13 +41,13 @@ cfg_if::cfg_if! { struct Context { spi: esp_hal::peripherals::SPI2, dma_channel: Channel<'static, DmaChannel0, Blocking>, - miso: AnyPin<'static>, - miso_mirror: AnyOutput<'static>, + miso: ErasedPin, + miso_mirror: Output<'static>, } fn execute( mut spi: SpiDma<'static, esp_hal::peripherals::SPI2, DmaChannel0, HalfDuplexMode, Blocking>, - mut miso_mirror: AnyOutput<'static>, + mut miso_mirror: Output<'static>, wanted: u8, ) { const DMA_BUFFER_SIZE: usize = 4; @@ -103,8 +103,8 @@ mod tests { let (miso, miso_mirror) = hil_test::common_test_pins!(io); - let miso = AnyPin::new(miso); - let miso_mirror = AnyOutput::new(miso_mirror, Level::High); + let miso = miso.degrade(); + let miso_mirror = Output::new(miso_mirror, Level::High); let dma = Dma::new(peripherals.DMA); diff --git a/hil-test/tests/qspi_write_read.rs b/hil-test/tests/qspi_write_read.rs index 5c39b5c37..16f2a65e2 100644 --- a/hil-test/tests/qspi_write_read.rs +++ b/hil-test/tests/qspi_write_read.rs @@ -17,7 +17,7 @@ use esp_hal::{ dma::{Channel, Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{AnyOutput, AnyPin, Io, Level}, + gpio::{ErasedPin, Io, Level, Output}, prelude::*, spi::{ master::{Address, Command, Spi, SpiDma}, @@ -43,13 +43,13 @@ cfg_if::cfg_if! { struct Context { spi: esp_hal::peripherals::SPI2, dma_channel: Channel<'static, DmaChannel0, Blocking>, - mosi: AnyPin<'static>, - mosi_mirror: AnyOutput<'static>, + mosi: ErasedPin, + mosi_mirror: Output<'static>, } fn execute( mut spi: SpiDma<'static, esp_hal::peripherals::SPI2, DmaChannel0, HalfDuplexMode, Blocking>, - mut mosi_mirror: AnyOutput<'static>, + mut mosi_mirror: Output<'static>, wanted: u8, ) { const DMA_BUFFER_SIZE: usize = 4; @@ -105,8 +105,8 @@ mod tests { let (mosi, mosi_mirror) = hil_test::common_test_pins!(io); - let mosi = AnyPin::new(mosi); - let mosi_mirror = AnyOutput::new(mosi_mirror, Level::High); + let mosi = mosi.degrade(); + let mosi_mirror = Output::new(mosi_mirror, Level::High); let dma = Dma::new(peripherals.DMA); diff --git a/hil-test/tests/spi_full_duplex_dma_async.rs b/hil-test/tests/spi_full_duplex_dma_async.rs index d8052e5bf..e41e02fdb 100644 --- a/hil-test/tests/spi_full_duplex_dma_async.rs +++ b/hil-test/tests/spi_full_duplex_dma_async.rs @@ -24,7 +24,7 @@ use embedded_hal_async::spi::SpiBus; use esp_hal::{ dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{AnyPin, GpioPin, Io, Level, Output, Pull}, + gpio::{ErasedPin, Io, Level, Output, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, @@ -57,8 +57,8 @@ const DMA_BUFFER_SIZE: usize = 5; struct Context { spi: SpiDmaBus<'static, SPI2, DmaChannel0, FullDuplexMode, Async>, pcnt_unit: Unit<'static, 0>, - out_pin: Output<'static, GpioPin<5>>, - mosi_mirror: AnyPin<'static>, + out_pin: Output<'static>, + mosi_mirror: ErasedPin, } #[cfg(test)] @@ -79,7 +79,7 @@ mod tests { let (mosi_mirror, mosi) = hil_test::common_test_pins!(io); let miso = io.pins.gpio4; let cs = io.pins.gpio8; - let mosi_mirror = AnyPin::new(mosi_mirror); + let mosi_mirror = mosi_mirror.degrade(); let mut out_pin = Output::new(io.pins.gpio5, Level::Low); out_pin.set_low(); diff --git a/hil-test/tests/spi_full_duplex_dma_pcnt.rs b/hil-test/tests/spi_full_duplex_dma_pcnt.rs index 6a839e290..bbfdd59ec 100644 --- a/hil-test/tests/spi_full_duplex_dma_pcnt.rs +++ b/hil-test/tests/spi_full_duplex_dma_pcnt.rs @@ -20,7 +20,7 @@ use esp_hal::{ dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{AnyPin, GpioPin, Io, Level, Output, Pull}, + gpio::{ErasedPin, Io, Level, Output, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, @@ -51,8 +51,8 @@ cfg_if::cfg_if! { struct Context { spi: SpiDma<'static, SPI2, DmaChannel0, FullDuplexMode, Blocking>, pcnt_unit: Unit<'static, 0>, - out_pin: Output<'static, GpioPin<5>>, - mosi_mirror: AnyPin<'static>, + out_pin: Output<'static>, + mosi_mirror: ErasedPin, } #[cfg(test)] @@ -91,7 +91,7 @@ mod tests { let mut out_pin = Output::new(io.pins.gpio5, Level::Low); out_pin.set_low(); assert_eq!(out_pin.is_set_low(), true); - let mosi_mirror = AnyPin::new(mosi_mirror); + let mosi_mirror = mosi_mirror.degrade(); Context { spi, diff --git a/hil-test/tests/spi_half_duplex_read.rs b/hil-test/tests/spi_half_duplex_read.rs index 59a4be945..9dd69893b 100644 --- a/hil-test/tests/spi_half_duplex_read.rs +++ b/hil-test/tests/spi_half_duplex_read.rs @@ -16,7 +16,7 @@ use esp_hal::{ dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{AnyOutput, Io, Level}, + gpio::{Io, Level, Output}, peripherals::SPI2, prelude::*, spi::{ @@ -42,7 +42,7 @@ cfg_if::cfg_if! { struct Context { spi: SpiDma<'static, SPI2, DmaChannel0, HalfDuplexMode, Blocking>, - miso_mirror: AnyOutput<'static>, + miso_mirror: Output<'static>, } #[cfg(test)] @@ -60,7 +60,7 @@ mod tests { let sclk = io.pins.gpio0; let (miso, miso_mirror) = hil_test::common_test_pins!(io); - let miso_mirror = AnyOutput::new(miso_mirror, Level::High); + let miso_mirror = Output::new(miso_mirror, Level::High); let dma = Dma::new(peripherals.DMA);