Commit e786513f authored by Simon Wörner's avatar Simon Wörner

added measure support in gpio poll

parent 63778789
extern crate std;
extern crate nix;
use std::fmt;
use std::time::Duration;
use std::io::prelude::*;
use std::io::{Error, ErrorKind, SeekFrom};
......@@ -9,6 +10,8 @@ use std::path::Path;
use std::os::unix::io::RawFd;
use measure::Measure;
fn duration_to_ms(duration: Duration) -> u64 {
duration.as_secs() * 1_000u64 + duration.subsec_nanos() as u64 / 1_000_000u64
}
......@@ -77,6 +80,18 @@ impl Value {
}
}
pub fn from_buffer(b: &[u8; 1]) -> Option<Self> {
Value::from_char(b[0])
}
pub fn from_char(c: u8) -> Option<Self> {
match c {
48 => Some(Value::Low), // '0'
49 => Some(Value::High), // '1'
_ => None
}
}
pub fn as_str(&self) -> &'static str {
match *self {
Value::High => "1",
......@@ -94,13 +109,22 @@ pub struct Port {
#[derive(Debug)]
pub struct SyncPort {
pub port: Port,
file: File
file: File,
buffer: [u8; 1]
}
#[derive(Debug)]
pub struct AsyncPort {
pub port: Port,
pub edge: Edge,
file: RawFd
file: RawFd,
fds: [nix::poll::PollFd; 1],
buffer: [u8; 1]
}
impl fmt::Debug for AsyncPort {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "AsyncPort {{ port: {:?}, edge: {:?}, file: {:?}, fds: [?], buffer: {:?} }}",
self.port, self.edge, self.file, self.buffer)
}
}
impl Port {
......@@ -146,7 +170,8 @@ impl SyncPort {
pub fn new(number: u8, direction: Direction) -> std::io::Result<SyncPort> {
Ok(SyncPort {
port: Port::new(number, direction)?,
file: SyncPort::open(number, direction)?
file: SyncPort::open(number, direction)?,
buffer: [0; 1]
})
}
......@@ -161,12 +186,10 @@ impl SyncPort {
}
pub fn read(&mut self) -> std::io::Result<Value> {
let mut contents = String::new();
self.file.seek(SeekFrom::Start(0))?;
self.file.read_to_string(&mut contents)?;
self.file.read_exact(&mut self.buffer)?;
Value::from_str(contents.as_str())
Value::from_buffer(&self.buffer)
.ok_or(Error::new(ErrorKind::InvalidData, "Unrecognized GPIO Value"))
}
......@@ -177,10 +200,13 @@ impl SyncPort {
impl AsyncPort {
pub fn new(number: u8, edge: Edge) -> std::io::Result<AsyncPort> {
let file = AsyncPort::open(number)?;
let port = AsyncPort {
port: Port::new(number, Direction::In)?,
edge: edge,
file: AsyncPort::open(number)?
file: file,
fds:[nix::poll::PollFd::new(file, nix::poll::POLLPRI, nix::poll::EventFlags::empty())],
buffer: [0; 1]
};
port.init()?;
......@@ -197,13 +223,16 @@ impl AsyncPort {
.or(Err(Error::new(ErrorKind::Other, "open failed")))
}
pub fn poll(&mut self, timeout: Option<Duration>) -> std::io::Result<Option<Value>> {
let mut fds = [nix::poll::PollFd::new(self.file, nix::poll::POLLPRI, nix::poll::EventFlags::empty())];
let mut buffer: [u8; 1] = [0; 1];
let poll = nix::poll::poll(&mut fds, match timeout { None => -1, Some(t) => duration_to_ms(t) as i32})
pub fn poll(&mut self, timeout: Option<Duration>, measure: Option<&mut Measure>) -> std::io::Result<Option<Value>> {
let poll = nix::poll::poll(&mut self.fds, match timeout { None => -1, Some(t) => duration_to_ms(t) as i32})
.or(Err(Error::new(ErrorKind::Other, "poll failed")))?;
// start measure
match measure {
Some(m) => m.start(),
None => { }
}
if poll == 0 {
return Ok(None);
}
......@@ -211,14 +240,11 @@ impl AsyncPort {
nix::unistd::lseek(self.file, 0, nix::unistd::Whence::SeekSet)
.or(Err(Error::new(ErrorKind::Other, "lseek failed")))?;
nix::unistd::read(self.file, &mut buffer)
nix::unistd::read(self.file, &mut self.buffer)
.or(Err(Error::new(ErrorKind::Other, "read failed")))?;
match buffer[0] {
48 => Ok(Some(Value::Low)), // '0'
49 => Ok(Some(Value::High)), // '1'
_ => Err(Error::new(ErrorKind::InvalidData, "Unrecognized GPIO Value"))
}
Value::from_buffer(&self.buffer)
.map_or(Err(Error::new(ErrorKind::InvalidData, "Unrecognized GPIO Value")), |v| Ok(Some(v)))
}
fn set_edge(&self) -> std::io::Result<()> {
......
......@@ -15,5 +15,5 @@ fn main() {
println!("trigger = {:?}", trigger.read());
trigger.write(Value::Low).expect("write failed");
println!("trigger = {:?}", trigger.read());
println!("echo = {:?}", echo.poll(Some(Duration::new(1, 0))));
println!("echo = {:?}", echo.poll(Some(Duration::new(1, 0)), None));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment