Alex Mikhalev
4 years ago
2 changed files with 89 additions and 0 deletions
@ -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" |
@ -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…
Reference in new issue