Alex Mikhalev
4 years ago
2 changed files with 89 additions and 0 deletions
@ -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 @@ |
|||||||
|
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