nix-config/overlay/pi-sensors/src/open_pin.rs

67 lines
1.5 KiB
Rust

use embedded_hal::digital::v2::{InputPin, OutputPin};
use rppal::gpio::{IoPin, Mode};
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::Input);
OpenPin {
iopin: pin,
mode: Mode::Input,
}
}
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<bool, Self::Error> {
Ok(self.iopin.is_high())
}
/// Is the input pin low?
fn is_low(&self) -> Result<bool, Self::Error> {
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(())
}
}