Skip to content

--get-gpio: Return all GPIOs if no name was passed #142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ Options:
--expansion-bay Show status of the expansion bay (Framework 16 only)
--charge-limit [<CHARGE_LIMIT>]
Get or set max charge limit
--get-gpio <GET_GPIO>
Get GPIO value by name
--get-gpio [<GET_GPIO>]
Get GPIO value by name or all, if no name provided
--fp-led-level [<FP_LED_LEVEL>]
Get or set fingerprint LED brightness level [possible values: high, medium, low, ultra-low, auto]
--fp-brightness [<FP_BRIGHTNESS>]
Expand Down
55 changes: 55 additions & 0 deletions framework_lib/src/chromium_ec/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,61 @@ impl EcRequest<EcResponseGpioGetV0> for EcRequestGpioGetV0 {
}
}

pub enum GpioGetSubCommand {
ByName = 0,
Count = 1,
Info = 2,
}

#[repr(C, packed)]
pub struct EcRequestGpioGetV1Count {
pub subcmd: u8,
}

#[repr(C, packed)]
pub struct EcRequestGpioGetV1ByName {
pub subcmd: u8,
pub name: [u8; 32],
}

#[repr(C, packed)]
pub struct EcRequestGpioGetV1Info {
pub subcmd: u8,
pub index: u8,
}

#[repr(C)]
pub struct EcResponseGpioGetV1Info {
pub val: u8,
pub name: [u8; 32],
pub flags: u32,
}

impl EcRequest<EcResponseGpioGetV0> for EcRequestGpioGetV1Count {
fn command_id() -> EcCommands {
EcCommands::GpioGet
}
fn command_version() -> u8 {
1
}
}
impl EcRequest<EcResponseGpioGetV0> for EcRequestGpioGetV1ByName {
fn command_id() -> EcCommands {
EcCommands::GpioGet
}
fn command_version() -> u8 {
1
}
}
impl EcRequest<EcResponseGpioGetV1Info> for EcRequestGpioGetV1Info {
fn command_id() -> EcCommands {
EcCommands::GpioGet
}
fn command_version() -> u8 {
1
}
}

#[repr(C, packed)]
pub struct EcRequestReboot {}

Expand Down
35 changes: 35 additions & 0 deletions framework_lib/src/chromium_ec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,41 @@ impl CrosEc {
Ok(res.val == 1)
}

pub fn get_all_gpios(&self) -> EcResult<u8> {
let res = EcRequestGpioGetV1Count {
subcmd: GpioGetSubCommand::Count as u8,
}
.send_command(self)?;
let gpio_count = res.val;

debug!("Found {} GPIOs", gpio_count);

for index in 0..res.val {
let res = EcRequestGpioGetV1Info {
subcmd: GpioGetSubCommand::Info as u8,
index,
}
.send_command(self)?;

let name = std::str::from_utf8(&res.name)
.map_err(|utf8_err| {
EcError::DeviceError(format!("Failed to decode GPIO name: {:?}", utf8_err))
})?
.trim_end_matches(char::from(0))
.to_string();

if log_enabled!(Level::Info) {
// Same output as ectool
println!("{:>32}: {:>2} 0x{:04X}", res.val, name, { res.flags });
} else {
// Simple output, just name and level high/low
println!("{:<32} {}", name, res.val);
}
}

Ok(gpio_count)
}

pub fn adc_read(&self, adc_channel: u8) -> EcResult<i32> {
let res = EcRequestAdcRead { adc_channel }.send_command(self)?;
Ok(res.adc_value)
Expand Down
4 changes: 2 additions & 2 deletions framework_lib/src/commandline/clap_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ struct ClapCli {
#[clap(num_args = ..=2)]
charge_rate_limit: Vec<f32>,

/// Get GPIO value by name
/// Get GPIO value by name or all, if no name provided
#[arg(long)]
get_gpio: Option<String>,
get_gpio: Option<Option<String>>,

/// Get or set fingerprint LED brightness level
#[arg(long)]
Expand Down
16 changes: 10 additions & 6 deletions framework_lib/src/commandline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ pub struct Cli {
pub charge_limit: Option<Option<u8>>,
pub charge_current_limit: Option<(u32, Option<u32>)>,
pub charge_rate_limit: Option<(f32, Option<f32>)>,
pub get_gpio: Option<String>,
pub get_gpio: Option<Option<String>>,
pub fp_led_level: Option<Option<FpBrightnessArg>>,
pub fp_brightness: Option<Option<u8>>,
pub kblight: Option<Option<u8>>,
Expand Down Expand Up @@ -791,11 +791,15 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
} else if let Some((limit, soc)) = args.charge_rate_limit {
print_err(ec.set_charge_rate_limit(limit, soc));
} else if let Some(gpio_name) = &args.get_gpio {
print!("Getting GPIO value {}: ", gpio_name);
if let Ok(value) = ec.get_gpio(gpio_name) {
println!("{:?}", value);
if let Some(gpio_name) = gpio_name {
print!("GPIO {}: ", gpio_name);
if let Ok(value) = ec.get_gpio(gpio_name) {
println!("{:?}", value);
} else {
println!("Not found");
}
} else {
println!("Not found");
print_err(ec.get_all_gpios());
}
} else if let Some(maybe_led_level) = &args.fp_led_level {
print_err(handle_fp_led_level(&ec, *maybe_led_level));
Expand Down Expand Up @@ -1120,7 +1124,7 @@ Options:
--expansion-bay Show status of the expansion bay (Framework 16 only)
--charge-limit [<VAL>] Get or set battery charge limit (Percentage number as arg, e.g. '100')
--charge-current-limit [<VAL>] Get or set battery current charge limit (Percentage number as arg, e.g. '100')
--get-gpio <GET_GPIO> Get GPIO value by name
--get-gpio <GET_GPIO> Get GPIO value by name or all, if no name provided
--fp-led-level [<VAL>] Get or set fingerprint LED brightness level [possible values: high, medium, low]
--fp-brightness [<VAL>]Get or set fingerprint LED brightness percentage
--kblight [<KBLIGHT>] Set keyboard backlight percentage or get, if no value provided
Expand Down
4 changes: 2 additions & 2 deletions framework_lib/src/commandline/uefi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,9 @@ pub fn parse(args: &[String]) -> Cli {
found_an_option = true;
} else if arg == "--get-gpio" {
cli.get_gpio = if args.len() > i + 1 {
Some(args[i + 1].clone())
Some(Some(args[i + 1].clone()))
} else {
None
Some(None)
};
found_an_option = true;
} else if arg == "--kblight" {
Expand Down
Loading