Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![allow(unused_mut)]
- #![allow(dead_code)]
- use std::fs;
- use std::process;
- use std::io::prelude::*;
- use std::thread::sleep;
- use std::time::Duration;
- use std::error::Error;
- // Struct defining how GPIO pins will be represented.
- // A GPIO pin object will be the pin's number, it's value sysfs handle, and its direction sysfs handle.
- struct GPIOPin {
- number: u8,
- value: fs::File,
- direction: fs::File,
- }
- // Function to export a GPIO pin and produce a GPIOPin object for it.
- fn gpioload(which:u8) -> GPIOPin {
- // where the GPIO export interface files are.
- let exportpath = "/sys/class/gpio/export";
- let unexportpath = "/sys/class/gpio/unexport";
- // where the in/out handle will be, when it is created.
- let directionpath = format!("/sys/class/gpio/gpio{}/direction",which.to_string());
- // where the value handle will be, when it is created.
- let valuepath = format!("/sys/class/gpio/gpio{}/value",which.to_string());
- // open the export files.
- let mut export = match fs::File::create(&exportpath) {
- Err(why) => {
- // gripe if opening it didn't work.
- println!("Error opening export: {}",why.description());
- process::exit(1);
- },
- Ok(file) => file,
- };
- let mut unexport = match fs::File::create(&unexportpath) {
- Err(why) => {
- println!("Error opening unexport: {}",why.description());
- process::exit(1);
- },
- Ok(file) => file,
- };
- // write the GPIO pin number to the export file.
- match export.write_all(which.to_string().as_bytes()) {
- Err(_why) => {
- // If writing to export throws an error, first check if that's just because we tried to export a pin that's already exported.
- // If this is the case, unexporting will succeed, at which point we can just re-export it again and keep going.
- // Otherwise, error out for real.
- match unexport.write_all(which.to_string().as_bytes()) {
- Err(why) => {
- println!("Error writing to export: {}",why.description());
- process::exit(1);
- },
- Ok(_) => {
- // If we were right about it already being exported (and we're re-exporting it), whine a little to the user about that.
- println!("Channel {} already open, continuing anyway.",which.to_string());
- match export.write_all(which.to_string().as_bytes()) {
- Err(why) => {
- println!("Error writing to export: {}",why.description());
- process::exit(1);
- },
- Ok(_) => (),
- }
- }
- }
- }
- Ok(_) => (),
- }
- // wait around for 1/10 second for the gpio# directory to appear and populate.
- sleep(Duration::new(0,100_000_000));
- // open the in/out handle.
- let mut directionfile = match fs::File::create(&directionpath) {
- Err(why) => {
- println!("Error opening {}: {}",&directionpath,why.description());
- process::exit(1);
- },
- Ok(file) => file,
- };
- // open the value handle.
- let mut valuefile = match fs::File::create(&valuepath) {
- Err(why) => {
- println!("Error opening {}: {}",&valuepath,why.description());
- process::exit(1);
- },
- Ok(file) => file,
- };
- // produce a fiddleable GPIO pin object to be assigned to a variable.
- let mut result = GPIOPin {
- number: which,
- value: valuefile,
- direction: directionfile,
- };
- return result;
- }
- // Definition of methods for the GPIOPin object.
- // These allow simpler invocation of operations such as changing input/output direction and writing/reading the state.
- impl GPIOPin {
- // Takes no arguments, produces no outputs, and sets the pin to be an output.
- fn setoutput(&mut self) {
- match self.direction.write_all(b"out") {
- Err(why) => {
- println!("Error setting pin {} as output: {}",self.number,why.description());
- process::exit(1);
- },
- Ok(_) => (),
- }
- }
- // Takes no arguments, produces no outputs, and sets the pin to be an input.
- fn setinput(&mut self) {
- match self.direction.write_all(b"in") {
- Err(why) => {
- println!("Error setting pin {} as input: {}",self.number,why.description());
- process::exit(1);
- },
- Ok(_) => (),
- }
- }
- // Takes a boolean argument and sets the pin the the corresponding state, returning nothing.
- fn output(&mut self,val:bool) {
- if val {
- match self.value.write_all(b"1") {
- Err(why) => {
- println!("Error setting state of pin {}: {}",self.number,why.description());
- process::exit(1);
- },
- Ok(_) => (),
- }
- } else {
- match self.value.write_all(b"0") {
- Err(why) => {
- println!("Error setting state of pin {}: {}",self.number,why.description());
- process::exit(1);
- },
- Ok(_) => (),
- }
- }
- }
- // Takes no arguments, produces a boolean value corresponding to the state of the pin.
- fn input(&mut self) -> bool {
- let mut statebuffer:Vec<u8> = vec![];
- match self.value.read_to_end(&mut statebuffer) {
- Err(why) => {
- println!("Error getting state of pin {}: {}",self.number,why.description());
- process::exit(1);
- },
- Ok(_) => (),
- }
- if statebuffer[0] == 49 {
- return true;
- } else if statebuffer[0] == 48 {
- return false;
- } else {
- println!("Error getting state of pin {}: Got unknown symbol {}",self.number,statebuffer[0]);
- process::exit(1);
- }
- }
- }
- fn main() {
- // set the time between light state changes (1/2 flash period).
- let wait = Duration::new(0,500_000_000);
- // load the GPIO pin to use.
- let mut gpio18 = gpioload(18);
- // set the GPIO pin as an output.
- gpio18.setoutput();
- // sit here and blink until either the program is interrupted or the stars die.
- loop {
- // blink on, wait.
- gpio18.output(true);
- println!("on");
- sleep(wait);
- // blink off, wait.
- gpio18.output(false);
- println!("off");
- sleep(wait);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement