Add impl of SectionInterface for Linux GPIO
This commit is contained in:
parent
cffd420f86
commit
11eba1a9e5
14
sprinklers_linux/Cargo.toml
Normal file
14
sprinklers_linux/Cargo.toml
Normal file
@ -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
Normal file
75
sprinklers_linux/src/lib.rs
Normal file
@ -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…
x
Reference in New Issue
Block a user