diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 05ffc0a43..9bd2cd627 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The functions of the `RadioClockController` have been split up to the modem peripheral structs. The clock management is now provided by the `ModemClockController`. (#3687) - Added GPIO11-GPIO17 to ESP32-C2. (#3726) - Added the feature `requires-unstable` (#3772) +- `AnyPin::downcast` to allow retrieving the original GPIO type (#3783) ### Changed diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 074773b34..5a24b4460 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -2167,6 +2167,56 @@ impl InputPin for AnyPin<'_> { } impl OutputPin for AnyPin<'_> {} +for_each_gpio! { + ($n:literal, $gpio:ident $($_rest:tt)*) => { + impl<'lt> TryFrom> for crate::peripherals::$gpio<'lt> { + type Error = AnyPin<'lt>; + + fn try_from(any_pin: AnyPin<'lt>) -> Result { + if any_pin.number() == $n { + Ok(unsafe { Self::steal() }) + } else { + Err(any_pin) + } + } + } + }; +} + +impl AnyPin<'_> { + #[procmacros::doc_replace] + /// Attempts to downcast the pin into the underlying GPIO instance. + /// + /// ## Example + /// + /// ```rust,no_run + /// # {before_snippet} + /// # + /// use esp_hal::{ + /// gpio::AnyPin, + /// peripherals::{GPIO2, GPIO4}, + /// }; + /// + /// let any_pin2 = AnyPin::from(peripherals.GPIO2); + /// let any_pin3 = AnyPin::from(peripherals.GPIO3); + /// + /// let gpio2 = any_pin2 + /// .downcast::() + /// .expect("This downcast succeeds because AnyPin was created from GPIO2"); + /// let gpio4 = any_pin3 + /// .downcast::() + /// .expect_err("This AnyPin was created from GPIO3, it cannot be downcast to GPIO4"); + /// # + /// # {after_snippet} + /// ``` + pub fn downcast(self) -> Result + where + Self: TryInto, + { + self.try_into() + } +} + #[cfg(not(esp32h2))] impl RtcPin for AnyPin<'_> { #[cfg(xtensa)]