use embedded_hal::digital::v2::{InputPin, OutputPin}; use rppal::gpio::{IoPin, Mode, PullUpDown}; use void; /** * Raspberry pi does not have open drain pins so we have to emulate it. */ pub struct OpenPin { iopin: IoPin, mode: Mode, } impl OpenPin { pub fn new(mut pin: IoPin) -> OpenPin { pin.set_mode(Mode::Output); pin.set_high(); pin.set_pullupdown(PullUpDown::Off); OpenPin { iopin: pin, mode: Mode::Output, } } pub fn switch_input(&mut self) { if self.mode != Mode::Input { self.mode = Mode::Input; self.iopin.set_mode(Mode::Input); } } pub fn switch_output(&mut self) { if self.mode != Mode::Output { self.mode = Mode::Output; self.iopin.set_mode(Mode::Output); } } } // Current rppal implementation does not support embedded_hal::gpio::v2 pins API. impl InputPin for OpenPin { type Error = void::Void; fn is_high(&self) -> Result { Ok(self.iopin.is_high()) } /// Is the input pin low? fn is_low(&self) -> Result { Ok(self.iopin.is_low()) } } // Current rppal implementation does not support embedded_hal::gpio::v2 pins API. impl OutputPin for OpenPin { type Error = void::Void; fn set_low(&mut self) -> Result<(), Self::Error> { self.switch_output(); self.iopin.set_low(); Ok(()) } fn set_high(&mut self) -> Result<(), Self::Error> { self.iopin.set_high(); self.switch_input(); Ok(()) } }