Add drivers for gpio and piface
This commit is contained in:
parent
61a3c6093b
commit
4ed1cd3182
14 changed files with 259 additions and 17 deletions
emgauwa-lib
|
@ -26,3 +26,7 @@ libsqlite3-sys = { version = "*", features = ["bundled"] }
|
|||
uuid = "1.6"
|
||||
futures = "0.3"
|
||||
libc = "0.2"
|
||||
|
||||
rppal = "0.17"
|
||||
rppal-pfd = "0.0.5"
|
||||
rppal-mcp23s17 = "0.0.3"
|
||||
|
|
35
emgauwa-lib/src/drivers/gpio.rs
Normal file
35
emgauwa-lib/src/drivers/gpio.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use rppal::gpio::{Gpio, OutputPin};
|
||||
|
||||
use crate::drivers::RelayDriver;
|
||||
use crate::errors::EmgauwaError;
|
||||
|
||||
pub struct GpioDriver {
|
||||
pub gpio: OutputPin,
|
||||
pub inverted: bool,
|
||||
}
|
||||
|
||||
impl GpioDriver {
|
||||
pub fn new(pin: u8, inverted: bool) -> Result<Self, EmgauwaError> {
|
||||
let gpio = Gpio::new()?.get(pin)?.into_output();
|
||||
Ok(Self { gpio, inverted })
|
||||
}
|
||||
}
|
||||
|
||||
impl RelayDriver for GpioDriver {
|
||||
fn set(&mut self, value: bool) -> Result<(), EmgauwaError> {
|
||||
if self.get_high(value) {
|
||||
self.gpio.set_high();
|
||||
} else {
|
||||
self.gpio.set_low();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_pin(&self) -> u8 {
|
||||
self.gpio.pin()
|
||||
}
|
||||
|
||||
fn get_inverted(&self) -> bool {
|
||||
self.inverted
|
||||
}
|
||||
}
|
17
emgauwa-lib/src/drivers/mod.rs
Normal file
17
emgauwa-lib/src/drivers/mod.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
mod gpio;
|
||||
mod piface;
|
||||
|
||||
pub use gpio::GpioDriver;
|
||||
pub use piface::PifaceDriver;
|
||||
|
||||
use crate::errors::EmgauwaError;
|
||||
|
||||
pub trait RelayDriver {
|
||||
fn get_high(&self, value: bool) -> bool {
|
||||
value ^ self.get_inverted()
|
||||
}
|
||||
|
||||
fn set(&mut self, value: bool) -> Result<(), EmgauwaError>;
|
||||
fn get_pin(&self) -> u8;
|
||||
fn get_inverted(&self) -> bool;
|
||||
}
|
52
emgauwa-lib/src/drivers/piface.rs
Normal file
52
emgauwa-lib/src/drivers/piface.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use rppal_pfd::{
|
||||
ChipSelect, HardwareAddress, OutputPin, PiFaceDigital, PiFaceDigitalError, SpiBus, SpiMode,
|
||||
};
|
||||
|
||||
use crate::drivers::RelayDriver;
|
||||
use crate::errors::EmgauwaError;
|
||||
|
||||
pub struct PifaceDriver {
|
||||
pub pfd_pin: OutputPin,
|
||||
}
|
||||
|
||||
impl PifaceDriver {
|
||||
pub fn new(pin: u8, pfd: &Option<PiFaceDigital>) -> Result<Self, EmgauwaError> {
|
||||
let pfd = pfd.as_ref().ok_or(EmgauwaError::Hardware(String::from(
|
||||
"PiFaceDigital not initialized",
|
||||
)))?;
|
||||
let pfd_pin = pfd.get_output_pin(pin)?;
|
||||
Ok(Self { pfd_pin })
|
||||
}
|
||||
|
||||
pub fn init_piface() -> Result<PiFaceDigital, EmgauwaError> {
|
||||
let mut pfd = PiFaceDigital::new(
|
||||
HardwareAddress::new(0)?,
|
||||
SpiBus::Spi0,
|
||||
ChipSelect::Cs0,
|
||||
100_000,
|
||||
SpiMode::Mode0,
|
||||
)?;
|
||||
pfd.init()?;
|
||||
|
||||
Ok(pfd)
|
||||
}
|
||||
}
|
||||
|
||||
impl RelayDriver for PifaceDriver {
|
||||
fn set(&mut self, value: bool) -> Result<(), EmgauwaError> {
|
||||
if self.get_high(value) {
|
||||
self.pfd_pin.set_high().map_err(PiFaceDigitalError::from)?;
|
||||
} else {
|
||||
self.pfd_pin.set_low().map_err(PiFaceDigitalError::from)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_pin(&self) -> u8 {
|
||||
self.pfd_pin.get_pin_number()
|
||||
}
|
||||
|
||||
fn get_inverted(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
|
@ -6,6 +6,9 @@ use actix::MailboxError;
|
|||
use actix_web::http::StatusCode;
|
||||
use actix_web::HttpResponse;
|
||||
use config::ConfigError;
|
||||
use rppal::gpio;
|
||||
use rppal_mcp23s17::Mcp23s17Error;
|
||||
use rppal_pfd::PiFaceDigitalError;
|
||||
use serde::ser::SerializeStruct;
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
|
@ -21,6 +24,7 @@ pub enum EmgauwaError {
|
|||
Other(String),
|
||||
Internal(String),
|
||||
Connection(ControllerUid),
|
||||
Hardware(String),
|
||||
}
|
||||
|
||||
impl EmgauwaError {
|
||||
|
@ -33,6 +37,7 @@ impl EmgauwaError {
|
|||
EmgauwaError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
EmgauwaError::Connection(_) => StatusCode::GATEWAY_TIMEOUT,
|
||||
EmgauwaError::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
EmgauwaError::Hardware(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +52,7 @@ impl From<&EmgauwaError> for String {
|
|||
EmgauwaError::Internal(_) => String::from("internal error"),
|
||||
EmgauwaError::Connection(_) => String::from("the target controller is not connected"),
|
||||
EmgauwaError::Other(err) => format!("other error: {}", err),
|
||||
EmgauwaError::Hardware(err) => format!("hardware error: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +99,25 @@ impl From<ConfigError> for EmgauwaError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<gpio::Error> for EmgauwaError {
|
||||
fn from(value: gpio::Error) -> Self {
|
||||
Self::Hardware(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PiFaceDigitalError> for EmgauwaError {
|
||||
fn from(value: PiFaceDigitalError) -> Self {
|
||||
match value {
|
||||
PiFaceDigitalError::Mcp23s17Error { source } => match source {
|
||||
Mcp23s17Error::SpiError { source } => Self::Hardware(source.to_string()),
|
||||
_ => Self::Hardware(source.to_string()),
|
||||
},
|
||||
PiFaceDigitalError::GpioError { source } => Self::Hardware(source.to_string()),
|
||||
_ => Self::Hardware(value.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&EmgauwaError> for HttpResponse {
|
||||
fn from(err: &EmgauwaError) -> Self {
|
||||
HttpResponse::build(err.get_code()).json(err)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
pub mod constants;
|
||||
pub mod db;
|
||||
pub mod drivers;
|
||||
pub mod errors;
|
||||
pub mod models;
|
||||
pub mod settings;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue