blob: ce66a605b8f4f0df2361ce0be6e6f2864e145609 [file] [log] [blame]
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
// SPDX-FileCopyrightText: 2022 Linaro Ltd.
// SPDX-FileCopyrightText: 2022 Viresh Kumar <viresh.kumar@linaro.org>
mod common;
mod line_info {
use libc::EINVAL;
use std::time::Duration;
use crate::common::*;
use gpiosim_sys::{Direction as SimDirection, Sim};
use libgpiod::{
chip::Chip,
line::{Bias, Direction, Drive, Edge, EventClock},
Error as ChipError, OperationType,
};
const NGPIO: usize = 8;
mod properties {
use super::*;
#[test]
fn default() {
let sim = Sim::new(Some(NGPIO), None, false).unwrap();
sim.set_line_name(4, "four").unwrap();
sim.hog_line(4, "hog4", SimDirection::OutputLow).unwrap();
sim.enable().unwrap();
let chip = Chip::open(&sim.dev_path()).unwrap();
let info4 = chip.line_info(4).unwrap();
assert_eq!(info4.offset(), 4);
assert_eq!(info4.name().unwrap(), "four");
assert!(info4.is_used());
assert_eq!(info4.consumer().unwrap(), "hog4");
assert_eq!(info4.direction().unwrap(), Direction::Output);
assert!(!info4.is_active_low());
assert_eq!(info4.bias().unwrap(), None);
assert_eq!(info4.drive().unwrap(), Drive::PushPull);
assert_eq!(info4.edge_detection().unwrap(), None);
assert_eq!(info4.event_clock().unwrap(), EventClock::Monotonic);
assert!(!info4.is_debounced());
assert_eq!(info4.debounce_period(), Duration::from_millis(0));
assert_eq!(
chip.line_info(NGPIO as u32).unwrap_err(),
ChipError::OperationFailed(OperationType::ChipGetLineInfo, errno::Errno(EINVAL))
);
}
#[test]
fn name_and_offset() {
let sim = Sim::new(Some(NGPIO), None, false).unwrap();
// Line 0 has no name
for i in 1..NGPIO {
sim.set_line_name(i as u32, &i.to_string()).unwrap();
}
sim.enable().unwrap();
let chip = Chip::open(&sim.dev_path()).unwrap();
let info = chip.line_info(0).unwrap();
assert_eq!(info.offset(), 0);
assert_eq!(
info.name().unwrap_err(),
ChipError::NullString("GPIO line's name")
);
for i in 1..NGPIO {
let info = chip.line_info(i as u32).unwrap();
assert_eq!(info.offset(), i as u32);
assert_eq!(info.name().unwrap(), &i.to_string());
}
}
#[test]
fn is_used() {
let sim = Sim::new(Some(NGPIO), None, false).unwrap();
sim.hog_line(0, "hog", SimDirection::OutputHigh).unwrap();
sim.enable().unwrap();
let chip = Chip::open(&sim.dev_path()).unwrap();
let info = chip.line_info(0).unwrap();
assert!(info.is_used());
let info = chip.line_info(1).unwrap();
assert!(!info.is_used());
}
#[test]
fn consumer() {
let sim = Sim::new(Some(NGPIO), None, false).unwrap();
sim.hog_line(0, "hog", SimDirection::OutputHigh).unwrap();
sim.enable().unwrap();
let chip = Chip::open(&sim.dev_path()).unwrap();
let info = chip.line_info(0).unwrap();
assert_eq!(info.consumer().unwrap(), "hog");
let info = chip.line_info(1).unwrap();
assert_eq!(
info.consumer().unwrap_err(),
ChipError::NullString("GPIO line's consumer name")
);
}
#[test]
fn direction() {
let sim = Sim::new(Some(NGPIO), None, false).unwrap();
sim.hog_line(0, "hog", SimDirection::Input).unwrap();
sim.hog_line(1, "hog", SimDirection::OutputHigh).unwrap();
sim.hog_line(2, "hog", SimDirection::OutputLow).unwrap();
sim.enable().unwrap();
let chip = Chip::open(&sim.dev_path()).unwrap();
let info = chip.line_info(0).unwrap();
assert_eq!(info.direction().unwrap(), Direction::Input);
let info = chip.line_info(1).unwrap();
assert_eq!(info.direction().unwrap(), Direction::Output);
let info = chip.line_info(2).unwrap();
assert_eq!(info.direction().unwrap(), Direction::Output);
}
#[test]
fn bias() {
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.bias().unwrap(), None);
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_bias(Direction::Input, Some(Bias::PullUp));
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.bias().unwrap(), Some(Bias::PullUp));
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_bias(Direction::Input, Some(Bias::PullDown));
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.bias().unwrap(), Some(Bias::PullDown));
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_bias(Direction::Input, Some(Bias::Disabled));
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.bias().unwrap(), Some(Bias::Disabled));
}
#[test]
fn drive() {
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.drive().unwrap(), Drive::PushPull);
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_drive(Direction::Input, Drive::PushPull);
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.drive().unwrap(), Drive::PushPull);
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_drive(Direction::Output, Drive::OpenDrain);
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.drive().unwrap(), Drive::OpenDrain);
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_drive(Direction::Output, Drive::OpenSource);
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.drive().unwrap(), Drive::OpenSource);
}
#[test]
fn edge() {
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.edge_detection().unwrap(), None);
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_edge(Some(Direction::Input), Some(Edge::Both));
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.edge_detection().unwrap(), Some(Edge::Both));
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_edge(Some(Direction::Input), Some(Edge::Rising));
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.edge_detection().unwrap(), Some(Edge::Rising));
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_edge(Some(Direction::Input), Some(Edge::Falling));
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.edge_detection().unwrap(), Some(Edge::Falling));
}
#[test]
fn event_clock() {
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.event_clock().unwrap(), EventClock::Monotonic);
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_clock(EventClock::Monotonic);
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.event_clock().unwrap(), EventClock::Monotonic);
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_clock(EventClock::Realtime);
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.event_clock().unwrap(), EventClock::Realtime);
}
#[test]
#[ignore]
fn event_clock_hte() {
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_clock(EventClock::HTE);
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert_eq!(info.event_clock().unwrap(), EventClock::HTE);
}
#[test]
fn debounce() {
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert!(!info.is_debounced());
assert_eq!(info.debounce_period(), Duration::from_millis(0));
let mut config = TestConfig::new(NGPIO).unwrap();
config.lconfig_debounce(Duration::from_millis(100));
config.lconfig_add_settings(&[0]);
config.request_lines().unwrap();
let info = config.chip().line_info(0).unwrap();
assert!(info.is_debounced());
assert_eq!(info.debounce_period(), Duration::from_millis(100));
}
}
}