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