Browse Source

Add impl of SectionInterface for Linux GPIO

master
Alex Mikhalev 4 years ago
parent
commit
11eba1a9e5
  1. 14
      sprinklers_linux/Cargo.toml
  2. 75
      sprinklers_linux/src/lib.rs

14
sprinklers_linux/Cargo.toml

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
[package]
name = "sprinklers_linux"
version = "0.1.0"
authors = ["Alex Mikhalev <alexmikhalevalex@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
sprinklers_core = { path = "../sprinklers_core" }
gpio-cdev = "0.4.0"
tracing = "0.1.21"
serde = { version = "1.0.116", features = ["derive"] }
eyre = "0.6.0"

75
sprinklers_linux/src/lib.rs

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
use sprinklers_core::section_interface::{SecId, SectionInterface};
use eyre::WrapErr;
use gpio_cdev::{LineHandle, LineRequestFlags};
use serde::{Deserialize, Serialize};
use tracing::{error, trace, warn};
pub struct LinuxGpio {
lines: Vec<LineHandle>,
}
impl SectionInterface for LinuxGpio {
fn num_sections(&self) -> SecId {
self.lines.len() as SecId
}
fn set_section_state(&self, id: SecId, running: bool) {
if let Some(line) = &self.lines.get(id as usize) {
trace!(
line = line.line().offset(),
id,
running,
"setting state of line"
);
if let Err(err) = line.set_value(running as u8) {
error!("error setting GPIO line value: {}", err);
}
} else {
warn!("set_section_state: invalid section id: {}", id);
}
}
fn get_section_state(&self, id: SecId) -> bool {
if let Some(line) = &self.lines.get(id as usize) {
match line.get_value() {
Ok(active) => active != 0,
Err(err) => {
error!("error getting GPIO line value: {}", err);
false
}
}
} else {
warn!("get_section_state: invalid section id: {}", id);
false
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct LinuxGpioConfig {
chip_path: String,
line_offsets: Vec<u32>,
}
impl LinuxGpioConfig {
pub fn build(self) -> eyre::Result<LinuxGpio> {
let mut chip =
gpio_cdev::Chip::new(self.chip_path).wrap_err("could not create gpio_cdev Chip")?;
let lines: Result<Vec<_>, eyre::Report> = self
.line_offsets
.into_iter()
.map(|line_offset| {
let line = chip
.get_line(line_offset)
.wrap_err("could not get line for chip")?;
let line_handle = line
.request(LineRequestFlags::OUTPUT, 0, "sprinklers_rs")
.wrap_err("could not request line access")?;
Ok(line_handle)
})
.collect();
let lines = lines?;
Ok(LinuxGpio { lines })
}
}
Loading…
Cancel
Save