use embedded_hal::digital::{OutputPin as _, PinState, StatefulOutputPin};
use gpiocdev::{line::Direction, Request};
use gpiocdev_embedded_hal::OutputPin;
use gpiosim::{Level, Simpleton};
#[test]
fn set_high() {
let s = Simpleton::new(5);
let offset = 3;
let mut pin = OutputPin::new(s.dev_path(), offset, PinState::Low).unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::Low);
pin.set_high().unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::High);
}
#[test]
fn set_low() {
let s = Simpleton::new(5);
let offset = 2;
let mut pin = OutputPin::new(s.dev_path(), offset, PinState::High).unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::High);
pin.set_low().unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::Low);
}
#[test]
fn is_set_high() {
let s = Simpleton::new(5);
let offset = 3;
let mut pin = OutputPin::new(s.dev_path(), offset, PinState::Low).unwrap();
assert!(!pin.is_set_high().unwrap());
pin.set_high().unwrap();
assert!(pin.is_set_high().unwrap());
pin.set_low().unwrap();
assert!(!pin.is_set_high().unwrap());
}
#[test]
fn is_set_low() {
let s = Simpleton::new(5);
let offset = 3;
let mut pin = OutputPin::new(s.dev_path(), offset, PinState::Low).unwrap();
assert!(pin.is_set_low().unwrap());
pin.set_high().unwrap();
assert!(!pin.is_set_low().unwrap());
pin.set_low().unwrap();
assert!(pin.is_set_low().unwrap());
}
#[test]
fn toggle() {
let s = Simpleton::new(5);
let offset = 2;
let mut pin = OutputPin::new(s.dev_path(), offset, PinState::High).unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::High);
pin.toggle().unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::Low);
pin.toggle().unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::High);
}
#[test]
fn into_input_pin() {
use embedded_hal::digital::InputPin as _;
let s = Simpleton::new(5);
let offset = 2;
let pin = OutputPin::new(s.dev_path(), offset, PinState::High).unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::High);
let mut pin = pin.into_input_pin().unwrap();
assert!(pin.is_high().unwrap());
assert_eq!(s.get_level(offset).unwrap(), Level::High);
s.pulldown(offset).unwrap();
assert!(pin.is_low().unwrap());
let req = Request::from(pin);
let config = req.config();
let offsets = config.lines();
assert_eq!(offsets.len(), 1);
assert_eq!(offsets[0], offset);
let line_config = config.line_config(offset).unwrap();
assert_eq!(line_config.direction, Some(Direction::Input));
}
mod try_from_request {
use super::*;
use gpiocdev::line::Value;
#[test]
fn output_request() {
let s = Simpleton::new(5);
let offset = 2;
let mut config = gpiocdev::request::Config::default();
config
.on_chip(s.dev_path())
.with_line(offset)
.as_output(Value::Active);
let req = Request::from_config(config).request().unwrap();
let config = req.config();
let mut pin = OutputPin::try_from(req).unwrap();
pin.set_low().unwrap();
assert_eq!(s.get_level(offset).unwrap(), Level::Low);
let req = Request::from(pin);
assert_eq!(config, req.config());
}
#[test]
fn input_request() {
let s = Simpleton::new(5);
let offset = 2;
let req = Request::builder()
.on_chip(s.dev_path())
.with_line(offset)
.as_input()
.request()
.unwrap();
assert_eq!(
OutputPin::try_from(req).unwrap_err(),
gpiocdev_embedded_hal::Error::RequiresOutputMode
);
}
#[test]
fn as_is_request() {
let s = Simpleton::new(5);
let offset = 2;
let req = Request::builder()
.on_chip(s.dev_path())
.with_line(offset)
.request()
.unwrap();
assert_eq!(
OutputPin::try_from(req).unwrap_err(),
gpiocdev_embedded_hal::Error::RequiresOutputMode
);
}
#[test]
fn multiple_lines() {
let s = Simpleton::new(5);
let req = Request::builder()
.on_chip(s.dev_path())
.with_lines(&[1, 2])
.as_output(Value::Inactive)
.request()
.unwrap();
assert_eq!(
OutputPin::try_from(req).unwrap_err(),
gpiocdev_embedded_hal::Error::MultipleLinesRequested
);
}
}
#[test]
fn into_request() {
let s = Simpleton::new(5);
let offset = 2;
let pin = OutputPin::new(s.dev_path(), offset, PinState::High).unwrap();
let req = Request::from(pin);
let config = req.config();
let offsets = config.lines();
assert_eq!(offsets.len(), 1);
assert_eq!(offsets[0], offset);
let line_config = config.line_config(offset).unwrap();
assert_eq!(line_config.direction, Some(Direction::Output));
}
#[test]
fn from_found_line() {
let s = Simpleton::new(5);
let offset = 2;
let fl = gpiocdev::FoundLine {
chip: s.dev_path().clone(),
info: gpiocdev::line::Info {
offset,
..Default::default()
},
};
let pin = OutputPin::from_found_line(fl, PinState::High).unwrap();
let req = Request::from(pin);
let config = req.config();
let offsets = config.lines();
assert_eq!(offsets.len(), 1);
assert_eq!(offsets[0], offset);
let line_config = config.line_config(offset).unwrap();
assert_eq!(line_config.direction, Some(Direction::Output));
}
#[test]
fn from_name() {
use gpiosim::Bank;
let s = gpiosim::builder()
.with_bank(
Bank::new(8, "output from_name")
.name(3, "ofn banana")
.name(6, "ofn apple"),
)
.live()
.unwrap();
let offset = 6;
let pin = OutputPin::from_name("ofn apple", PinState::High).unwrap();
let req = Request::from(pin);
assert_eq!(&req.chip_path(), s.chips()[0].dev_path());
let config = req.config();
let offsets = config.lines();
assert_eq!(offsets.len(), 1);
assert_eq!(offsets[0], offset);
let line_config = config.line_config(offset).unwrap();
assert_eq!(line_config.direction, Some(Direction::Output));
assert_eq!(
OutputPin::from_name("ofn grape", PinState::High).unwrap_err(),
gpiocdev_embedded_hal::Error::UnfoundLine("ofn grape".into())
);
}