Skip to content

Commit

Permalink
Add support for optional Level for an Output in a saved config
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewdavidmackenzie committed May 22, 2024
1 parent 2a46bc7 commit 9d2cd39
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 47 deletions.
26 changes: 15 additions & 11 deletions src/gpio/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod pin_descriptions;

use pin_descriptions::*;
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io;
use std::io::{BufReader, Write};

use serde::{Deserialize, Serialize};

use pin_descriptions::*;

mod pin_descriptions;

// All the possible functions a pin can be given
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
#[allow(non_camel_case_types)]
Expand All @@ -15,7 +17,7 @@ pub enum PinFunction {
Power5V,
Ground,
Input,
Output,
Output(Option<bool>),
SDA1,
I2C,
SCL1,
Expand Down Expand Up @@ -97,13 +99,15 @@ pub struct GPIOState {

#[cfg(test)]
mod test {
use crate::gpio::{GPIOConfig, PinFunction};
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

use tempfile::tempdir;

use crate::gpio::{GPIOConfig, PinFunction};

#[test]
fn create_a_config() {
let config = GPIOConfig::default();
Expand Down Expand Up @@ -131,22 +135,22 @@ mod test {
path = path.join("tests/one_pin_config.piggui");
let config = GPIOConfig::load(path.to_str().unwrap()).unwrap();
assert_eq!(config.configured_pins.len(), 1);
assert_eq!(config.configured_pins[0].0, 1);
assert_eq!(config.configured_pins[0].1, PinFunction::Input);
assert_eq!(config.configured_pins[0].0, 7); // GPIO7
assert_eq!(config.configured_pins[0].1, PinFunction::Output(Some(true)));
}

#[test]
fn save_one_pin_config() {
fn save_one_pin_config_with_level() {
let config = GPIOConfig {
configured_pins: vec![(1, PinFunction::Input)],
configured_pins: vec![(7, PinFunction::Output(Some(true)))], // GPIO7 output set to 1
};

let output_dir = tempdir().expect("Could not create a tempdir").into_path();
let test_file = output_dir.join("test.piggui");

config.save(test_file.to_str().unwrap()).unwrap();

let pin_config = r#"{"configured_pins":[[1,"Input"]]}"#;
let pin_config = r#"{"configured_pins":[[7,{"Output":true}]]}"#;
let contents = fs::read_to_string(test_file).expect("Could not read test file");
assert_eq!(contents, pin_config);
}
Expand Down
110 changes: 81 additions & 29 deletions src/gpio/pin_descriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ pub const PIN_3: PinDescription = PinDescription {
board_pin_number: 3,
bcm_pin_number: Some(2),
name: "GPIO2",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::SDA1, PinFunction::I2C],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::SDA1,
PinFunction::I2C,
],
};

pub const PIN_4: PinDescription = PinDescription {
Expand All @@ -34,7 +39,12 @@ pub const PIN_5: PinDescription = PinDescription {
board_pin_number: 5,
bcm_pin_number: Some(3),
name: "GPIO3",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::SCL1, PinFunction::I2C],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::SCL1,
PinFunction::I2C,
],
};

pub const PIN_6: PinDescription = PinDescription {
Expand All @@ -48,14 +58,18 @@ pub const PIN_7: PinDescription = PinDescription {
board_pin_number: 7,
bcm_pin_number: Some(4),
name: "GPIO4",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_8: PinDescription = PinDescription {
board_pin_number: 8,
bcm_pin_number: Some(14),
name: "GPIO14",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::UART0_TXD],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::UART0_TXD,
],
};

pub const PIN_9: PinDescription = PinDescription {
Expand All @@ -69,28 +83,36 @@ pub const PIN_10: PinDescription = PinDescription {
board_pin_number: 10,
bcm_pin_number: Some(15),
name: "GPIO15",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::UART0_RXD],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::UART0_RXD,
],
};

pub const PIN_11: PinDescription = PinDescription {
board_pin_number: 11,
bcm_pin_number: Some(17),
name: "GPIO17",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_12: PinDescription = PinDescription {
board_pin_number: 12,
bcm_pin_number: Some(18),
name: "GPIO18",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::PCM_CLK],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::PCM_CLK,
],
};

pub const PIN_13: PinDescription = PinDescription {
board_pin_number: 13,
bcm_pin_number: Some(27),
name: "GPIO27",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_14: PinDescription = PinDescription {
Expand All @@ -104,14 +126,14 @@ pub const PIN_15: PinDescription = PinDescription {
board_pin_number: 15,
bcm_pin_number: Some(22),
name: "GPIO22",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_16: PinDescription = PinDescription {
board_pin_number: 16,
bcm_pin_number: Some(23),
name: "GPIO23",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_17: PinDescription = PinDescription {
Expand All @@ -125,14 +147,18 @@ pub const PIN_18: PinDescription = PinDescription {
board_pin_number: 18,
bcm_pin_number: Some(24),
name: "GPIO24",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_19: PinDescription = PinDescription {
board_pin_number: 19,
bcm_pin_number: Some(10),
name: "GPIO10",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::SPIO_MOSI],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::SPIO_MOSI,
],
};

pub const PIN_20: PinDescription = PinDescription {
Expand All @@ -146,28 +172,40 @@ pub const PIN_21: PinDescription = PinDescription {
board_pin_number: 21,
bcm_pin_number: Some(9),
name: "GPIO9",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::SPIO_MISO],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::SPIO_MISO,
],
};

pub const PIN_22: PinDescription = PinDescription {
board_pin_number: 22,
bcm_pin_number: Some(25),
name: "GPIO25",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_23: PinDescription = PinDescription {
board_pin_number: 23,
bcm_pin_number: Some(11),
name: "GPIO11",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::SPIO_SCLK],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::SPIO_SCLK,
],
};

pub const PIN_24: PinDescription = PinDescription {
board_pin_number: 24,
bcm_pin_number: Some(8),
name: "GPIO8",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::SPIO_CE0_N],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::SPIO_CE0_N,
],
};

pub const PIN_25: PinDescription = PinDescription {
Expand All @@ -181,28 +219,42 @@ pub const PIN_26: PinDescription = PinDescription {
board_pin_number: 26,
bcm_pin_number: Some(7),
name: "GPIO7",
options: &[PinFunction::Input, PinFunction::Output, PinFunction::SPIO_CE1_N],
options: &[
PinFunction::Input,
PinFunction::Output(None),
PinFunction::SPIO_CE1_N,
],
};

pub const PIN_27: PinDescription = PinDescription {
board_pin_number: 27,
bcm_pin_number: None,
name: "ID_SD",
options: &[PinFunction::ID_SD, PinFunction::I2C, PinFunction::ID, PinFunction::EEPROM],
options: &[
PinFunction::ID_SD,
PinFunction::I2C,
PinFunction::ID,
PinFunction::EEPROM,
],
};

pub const PIN_28: PinDescription = PinDescription {
board_pin_number: 28,
bcm_pin_number: None,
name: "ID_SC",
options: &[PinFunction::ID_SC, PinFunction::I2C, PinFunction::ID, PinFunction::EEPROM],
options: &[
PinFunction::ID_SC,
PinFunction::I2C,
PinFunction::ID,
PinFunction::EEPROM,
],
};

pub const PIN_29: PinDescription = PinDescription {
board_pin_number: 29,
bcm_pin_number: Some(5),
name: "GPIO5",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_30: PinDescription = PinDescription {
Expand All @@ -216,21 +268,21 @@ pub const PIN_31: PinDescription = PinDescription {
board_pin_number: 31,
bcm_pin_number: Some(6),
name: "GPIO6",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_32: PinDescription = PinDescription {
board_pin_number: 32,
bcm_pin_number: Some(12),
name: "GPIO12",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_33: PinDescription = PinDescription {
board_pin_number: 33,
bcm_pin_number: Some(13),
name: "GPIO13",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_34: PinDescription = PinDescription {
Expand All @@ -244,28 +296,28 @@ pub const PIN_35: PinDescription = PinDescription {
board_pin_number: 35,
bcm_pin_number: Some(19),
name: "GPIO19",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_36: PinDescription = PinDescription {
board_pin_number: 36,
bcm_pin_number: Some(16),
name: "GPIO16",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_37: PinDescription = PinDescription {
board_pin_number: 37,
bcm_pin_number: Some(26),
name: "GPIO26",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_38: PinDescription = PinDescription {
board_pin_number: 38,
bcm_pin_number: Some(20),
name: "GPIO20",
options: &[PinFunction::Input, PinFunction::Output],
options: &[PinFunction::Input, PinFunction::Output(None)],
};

pub const PIN_39: PinDescription = PinDescription {
Expand All @@ -279,5 +331,5 @@ pub const PIN_40: PinDescription = PinDescription {
board_pin_number: 40,
bcm_pin_number: Some(21),
name: "GPIO21",
options: &[PinFunction::Input, PinFunction::Output],
};
options: &[PinFunction::Input, PinFunction::Output(None)],
};
24 changes: 18 additions & 6 deletions src/hw/pi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,31 @@ impl Hardware for PiHW {
// TODO FIXME looks like get() uses BCM pin numbering...

fn apply_config(&mut self, config: &GPIOConfig) {
for (pin_number, pin_config) in &config.configured_pins {
for (bcm_pin_number, pin_config) in &config.configured_pins {
match pin_config {
PinFunction::Input => {
// TODO handle pull-up/down options
let input = Gpio::new().unwrap().get(*pin_number).unwrap().into_input();
self.configured_pins.push((*pin_number, Pin::Input(input)))
let input = Gpio::new()
.unwrap()
.get(*bcm_pin_number)
.unwrap()
.into_input();
self.configured_pins
.push((*bcm_pin_number, Pin::Input(input)))
}
PinFunction::Output => {
PinFunction::Output(value) => {
// TODO check if there are any options on Output pins
// TODO consider config being able to "save" the output value to set?
let output = Gpio::new().unwrap().get(*pin_number).unwrap().into_output();
let mut output = Gpio::new()
.unwrap()
.get(*bcm_pin_number)
.unwrap()
.into_output();
if let Some(level) = value {
output.write(Level::from(*level));
}
self.configured_pins
.push((*pin_number, Pin::Output(output)))
.push((*bcm_pin_number, Pin::Output(output)))
}
// TODO implement all of these
PinFunction::SDA1 => {}
Expand Down
Loading

0 comments on commit 9d2cd39

Please sign in to comment.