Skip to content

Commit

Permalink
Add support for input pullups/pulldowns in config
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewdavidmackenzie committed May 22, 2024
1 parent 9d2cd39 commit 701e518
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 52 deletions.
33 changes: 28 additions & 5 deletions src/gpio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ use pin_descriptions::*;

mod pin_descriptions;

// An input can be configured to have an optional pull-up or pull-down
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]

Check warning on line 12 in src/gpio/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/gpio/mod.rs#L12

Added line #L12 was not covered by tests
pub enum InputPull {
PullUp,
PullDown,
}

// All the possible functions a pin can be given
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
#[allow(non_camel_case_types)]
Expand All @@ -16,7 +23,7 @@ pub enum PinFunction {
Power3V3,
Power5V,
Ground,
Input,
Input(Option<InputPull>),
Output(Option<bool>),
SDA1,
I2C,
Expand Down Expand Up @@ -115,8 +122,24 @@ mod test {
}

#[test]
fn load_one_pin_config() {
let pin_config = r#"{"configured_pins":[[1,"Input"]]}"#;
fn save_one_pin_config_input_no_pullup() {
let config = GPIOConfig {
configured_pins: vec![(1, PinFunction::Input(None))],
};

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":null}]]}"#;
let contents = fs::read_to_string(test_file).expect("Could not read test file");
assert_eq!(contents, pin_config);
}

#[test]
fn load_one_pin_config_input_no_pull() {
let pin_config = r#"{"configured_pins":[[1,{"Input":null}]]}"#;
let output_dir = tempdir().expect("Could not create a tempdir").into_path();
let test_file = output_dir.join("test.piggui");
let mut file = File::create(&test_file).expect("Could not create test file");
Expand All @@ -125,7 +148,7 @@ mod test {
let config = GPIOConfig::load(test_file.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].1, PinFunction::Input(None));
}

#[test]
Expand All @@ -140,7 +163,7 @@ mod test {
}

#[test]
fn save_one_pin_config_with_level() {
fn save_one_pin_config_output_with_level() {
let config = GPIOConfig {
configured_pins: vec![(7, PinFunction::Output(Some(true)))], // GPIO7 output set to 1
};
Expand Down
52 changes: 26 additions & 26 deletions src/gpio/pin_descriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub const PIN_3: PinDescription = PinDescription {
bcm_pin_number: Some(2),
name: "GPIO2",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::SDA1,
PinFunction::I2C,
Expand All @@ -40,7 +40,7 @@ pub const PIN_5: PinDescription = PinDescription {
bcm_pin_number: Some(3),
name: "GPIO3",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::SCL1,
PinFunction::I2C,
Expand All @@ -58,15 +58,15 @@ pub const PIN_7: PinDescription = PinDescription {
board_pin_number: 7,
bcm_pin_number: Some(4),
name: "GPIO4",
options: &[PinFunction::Input, PinFunction::Output(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};

pub const PIN_8: PinDescription = PinDescription {
board_pin_number: 8,
bcm_pin_number: Some(14),
name: "GPIO14",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::UART0_TXD,
],
Expand All @@ -84,7 +84,7 @@ pub const PIN_10: PinDescription = PinDescription {
bcm_pin_number: Some(15),
name: "GPIO15",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::UART0_RXD,
],
Expand All @@ -94,15 +94,15 @@ pub const PIN_11: PinDescription = PinDescription {
board_pin_number: 11,
bcm_pin_number: Some(17),
name: "GPIO17",
options: &[PinFunction::Input, PinFunction::Output(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};

pub const PIN_12: PinDescription = PinDescription {
board_pin_number: 12,
bcm_pin_number: Some(18),
name: "GPIO18",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::PCM_CLK,
],
Expand All @@ -112,7 +112,7 @@ pub const PIN_13: PinDescription = PinDescription {
board_pin_number: 13,
bcm_pin_number: Some(27),
name: "GPIO27",
options: &[PinFunction::Input, PinFunction::Output(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};

pub const PIN_14: PinDescription = PinDescription {
Expand All @@ -126,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(None)],
options: &[PinFunction::Input(None), 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(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};

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

pub const PIN_19: PinDescription = PinDescription {
board_pin_number: 19,
bcm_pin_number: Some(10),
name: "GPIO10",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::SPIO_MOSI,
],
Expand All @@ -173,7 +173,7 @@ pub const PIN_21: PinDescription = PinDescription {
bcm_pin_number: Some(9),
name: "GPIO9",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::SPIO_MISO,
],
Expand All @@ -183,15 +183,15 @@ pub const PIN_22: PinDescription = PinDescription {
board_pin_number: 22,
bcm_pin_number: Some(25),
name: "GPIO25",
options: &[PinFunction::Input, PinFunction::Output(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};

pub const PIN_23: PinDescription = PinDescription {
board_pin_number: 23,
bcm_pin_number: Some(11),
name: "GPIO11",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::SPIO_SCLK,
],
Expand All @@ -202,7 +202,7 @@ pub const PIN_24: PinDescription = PinDescription {
bcm_pin_number: Some(8),
name: "GPIO8",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::SPIO_CE0_N,
],
Expand All @@ -220,7 +220,7 @@ pub const PIN_26: PinDescription = PinDescription {
bcm_pin_number: Some(7),
name: "GPIO7",
options: &[
PinFunction::Input,
PinFunction::Input(None),
PinFunction::Output(None),
PinFunction::SPIO_CE1_N,
],
Expand Down Expand Up @@ -254,7 +254,7 @@ pub const PIN_29: PinDescription = PinDescription {
board_pin_number: 29,
bcm_pin_number: Some(5),
name: "GPIO5",
options: &[PinFunction::Input, PinFunction::Output(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};

pub const PIN_30: PinDescription = PinDescription {
Expand All @@ -268,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(None)],
options: &[PinFunction::Input(None), 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(None)],
options: &[PinFunction::Input(None), 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(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};

pub const PIN_34: PinDescription = PinDescription {
Expand All @@ -296,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(None)],
options: &[PinFunction::Input(None), 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(None)],
options: &[PinFunction::Input(None), 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(None)],
options: &[PinFunction::Input(None), 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(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};

pub const PIN_39: PinDescription = PinDescription {
Expand All @@ -331,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(None)],
options: &[PinFunction::Input(None), PinFunction::Output(None)],
};
36 changes: 15 additions & 21 deletions src/hw/pi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rppal::gpio::Gpio;
use rppal::gpio::OutputPin;

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

use super::Hardware;

Expand Down Expand Up @@ -34,32 +34,26 @@ impl Hardware for PiHW {
/// configure the Pi GPIO hardware to correspond to it
// TODO maybe change trait to allow errors

// TODO FIXME looks like get() uses BCM pin numbering...

fn apply_config(&mut self, config: &GPIOConfig) {
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(*bcm_pin_number)
.unwrap()
.into_input();
PinFunction::Input(pull) => {
let pin = Gpio::new().unwrap().get(*bcm_pin_number).unwrap();
let input = match pull {
None => pin.into_input(),
Some(InputPull::PullUp) => pin.into_input_pullup(),
Some(InputPull::PullDown) => pin.into_input_pulldown(),
};
self.configured_pins
.push((*bcm_pin_number, Pin::Input(input)))
}
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 mut output = Gpio::new()
.unwrap()
.get(*bcm_pin_number)
.unwrap()
.into_output();
if let Some(level) = value {
output.write(Level::from(*level));
}
let pin = Gpio::new().unwrap().get(*bcm_pin_number).unwrap();
let output = match value {
None => pin.into_output(),
Some(true) => pin.into_output_high(),
Some(false) => pin.into_output_low(),
};
self.configured_pins
.push((*bcm_pin_number, Pin::Output(output)))
}
Expand Down Expand Up @@ -89,7 +83,7 @@ impl Hardware for PiHW {
println!("GPIO Config has been applied to Pi hardware");
}

/// Return the state of the Input pins and other pins who's state is read from GPIO hardware
/// Return the state of the Input pins and other pins whose state is read from GPIO hardware
// TODO might deprecate this in favor of some sort of message or callback when an input changes
// its value, to trigger a UI update...
// messages will need to be able to capture other types of input, Image (SPIO), value from ADC
Expand Down

0 comments on commit 701e518

Please sign in to comment.