diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs index 71390306..930de206 100644 --- a/embassy-rp/src/gpio.rs +++ b/embassy-rp/src/gpio.rs @@ -411,6 +411,16 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> { pub fn toggle(&mut self) { self.pin.toggle_set_as_output() } + + #[inline] + pub fn is_high(&self) -> bool { + self.pin.is_high() + } + + #[inline] + pub fn is_low(&self) -> bool { + self.pin.is_low() + } } /// GPIO flexible pin. @@ -791,6 +801,18 @@ mod eh02 { } } + impl<'d, T: Pin> embedded_hal_02::digital::v2::InputPin for OutputOpenDrain<'d, T> { + type Error = Infallible; + + fn is_high(&self) -> Result { + Ok(self.is_high()) + } + + fn is_low(&self) -> Result { + Ok(self.is_low()) + } + } + impl<'d, T: Pin> embedded_hal_02::digital::v2::OutputPin for OutputOpenDrain<'d, T> { type Error = Infallible; @@ -946,6 +968,16 @@ mod eh1 { } } + impl<'d, T: Pin> embedded_hal_1::digital::InputPin for OutputOpenDrain<'d, T> { + fn is_high(&self) -> Result { + Ok(self.is_high()) + } + + fn is_low(&self) -> Result { + Ok(self.is_low()) + } + } + impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Flex<'d, T> { type Error = Infallible; } diff --git a/tests/rp/src/bin/gpio.rs b/tests/rp/src/bin/gpio.rs index af22fe27..80e92d0f 100644 --- a/tests/rp/src/bin/gpio.rs +++ b/tests/rp/src/bin/gpio.rs @@ -78,6 +78,7 @@ async fn main(_spawner: Spawner) { a.set_as_input(); // When an OutputOpenDrain is high, it doesn't drive the pin. + b.set_high(); a.set_pull(Pull::Up); delay(); assert!(a.is_high()); @@ -85,9 +86,8 @@ async fn main(_spawner: Spawner) { delay(); assert!(a.is_low()); - b.set_low(); - // When an OutputOpenDrain is low, it drives the pin low. + b.set_low(); a.set_pull(Pull::Up); delay(); assert!(a.is_low()); @@ -95,14 +95,36 @@ async fn main(_spawner: Spawner) { delay(); assert!(a.is_low()); + // Check high again b.set_high(); - a.set_pull(Pull::Up); delay(); assert!(a.is_high()); a.set_pull(Pull::Down); delay(); assert!(a.is_low()); + + // When an OutputOpenDrain is high, it reads the input value in the pin. + b.set_high(); + a.set_as_input(); + a.set_pull(Pull::Up); + delay(); + assert!(b.is_high()); + a.set_as_output(); + a.set_low(); + delay(); + assert!(b.is_low()); + + // When an OutputOpenDrain is low, it always reads low. + b.set_low(); + a.set_as_input(); + a.set_pull(Pull::Up); + delay(); + assert!(b.is_low()); + a.set_as_output(); + a.set_low(); + delay(); + assert!(b.is_low()); } // FLEX