1 // Copyright (c) 2018 The rust-gpio-cdev Project Developers.
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8
9 use gpio_cdev::*;
10 use nix::poll::*;
11 use quicli::prelude::*;
12 use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd};
13 use structopt::StructOpt;
14
15 type PollEventFlags = nix::poll::PollFlags;
16
17 #[derive(Debug, StructOpt)]
18 struct Cli {
19 /// The gpiochip device (e.g. /dev/gpiochip0)
20 chip: String,
21 /// The offset of the GPIO lines for the provided chip
22 lines: Vec<u32>,
23 }
24
do_main(args: Cli) -> anyhow::Result<()>25 fn do_main(args: Cli) -> anyhow::Result<()> {
26 let mut chip = Chip::new(args.chip)?;
27
28 // Get event handles for each line to monitor.
29 let mut evt_handles: Vec<LineEventHandle> = args
30 .lines
31 .into_iter()
32 .map(|off| {
33 let line = chip.get_line(off).unwrap();
34 line.events(
35 LineRequestFlags::INPUT,
36 EventRequestFlags::BOTH_EDGES,
37 "monitor",
38 )
39 .unwrap()
40 })
41 .collect();
42
43 // Create a vector of file descriptors for polling
44 let ownedfd: Vec<OwnedFd> = evt_handles
45 .iter()
46 .map(|h| unsafe { OwnedFd::from_raw_fd(h.as_raw_fd()) })
47 .collect();
48 let mut pollfds: Vec<PollFd> = ownedfd
49 .iter()
50 .map(|fd| PollFd::new(fd, PollEventFlags::POLLIN | PollEventFlags::POLLPRI))
51 .collect();
52
53 loop {
54 // poll for an event on any of the lines
55 if poll(&mut pollfds, -1)? == 0 {
56 println!("Timeout?!?");
57 } else {
58 for i in 0..pollfds.len() {
59 if let Some(revts) = pollfds[i].revents() {
60 let h = &mut evt_handles[i];
61 if revts.contains(PollEventFlags::POLLIN) {
62 let event = h.get_event()?;
63 println!("[{}] {:?}", h.line().offset(), event);
64
65 // You can figure out the new level from the event,
66 // but this shows that you can use the event handle
67 // to read the value of the bit.
68 let val = h.get_value()?;
69 println!(" {}", val);
70 } else if revts.contains(PollEventFlags::POLLPRI) {
71 println!("[{}] Got a POLLPRI", h.line().offset());
72 }
73 }
74 }
75 }
76 }
77 }
78
main() -> CliResult79 fn main() -> CliResult {
80 let args = Cli::from_args();
81 do_main(args).or_else(|e| {
82 error!("{:?}", e);
83 Ok(())
84 })
85 }
86