Add drivers for gpio and piface
This commit is contained in:
		
							parent
							
								
									61a3c6093b
								
							
						
					
					
						commit
						4ed1cd3182
					
				
					 14 changed files with 259 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -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