1099: rp: implement input for OutputOpenDrain r=Dirbaio a=Dirbaio

Needed for onewire and similar protocols.

Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
bors[bot] 2022-12-06 20:12:29 +00:00 committed by GitHub
commit 40f0272dd0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 3 deletions

View file

@ -411,6 +411,16 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
pub fn toggle(&mut self) { pub fn toggle(&mut self) {
self.pin.toggle_set_as_output() 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. /// 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<bool, Self::Error> {
Ok(self.is_high())
}
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(self.is_low())
}
}
impl<'d, T: Pin> embedded_hal_02::digital::v2::OutputPin for OutputOpenDrain<'d, T> { impl<'d, T: Pin> embedded_hal_02::digital::v2::OutputPin for OutputOpenDrain<'d, T> {
type Error = Infallible; 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<bool, Self::Error> {
Ok(self.is_high())
}
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(self.is_low())
}
}
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Flex<'d, T> { impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Flex<'d, T> {
type Error = Infallible; type Error = Infallible;
} }

View file

@ -78,6 +78,7 @@ async fn main(_spawner: Spawner) {
a.set_as_input(); a.set_as_input();
// When an OutputOpenDrain is high, it doesn't drive the pin. // When an OutputOpenDrain is high, it doesn't drive the pin.
b.set_high();
a.set_pull(Pull::Up); a.set_pull(Pull::Up);
delay(); delay();
assert!(a.is_high()); assert!(a.is_high());
@ -85,9 +86,8 @@ async fn main(_spawner: Spawner) {
delay(); delay();
assert!(a.is_low()); assert!(a.is_low());
b.set_low();
// When an OutputOpenDrain is low, it drives the pin low. // When an OutputOpenDrain is low, it drives the pin low.
b.set_low();
a.set_pull(Pull::Up); a.set_pull(Pull::Up);
delay(); delay();
assert!(a.is_low()); assert!(a.is_low());
@ -95,14 +95,36 @@ async fn main(_spawner: Spawner) {
delay(); delay();
assert!(a.is_low()); assert!(a.is_low());
// Check high again
b.set_high(); b.set_high();
a.set_pull(Pull::Up); a.set_pull(Pull::Up);
delay(); delay();
assert!(a.is_high()); assert!(a.is_high());
a.set_pull(Pull::Down); a.set_pull(Pull::Down);
delay(); delay();
assert!(a.is_low()); 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 // FLEX