Skip to content

Commit 18ab45c

Browse files
committed
Add --charge-rate-limit
Usually the user won't want to specify a mA value to limit the charge current. Setting a charge rate 0.0-1.0 is more useful. ``` PS C:\Users\Daniel\clone\framework-system-private> sudo .\target\debug\framework_tool.exe --power Charger Status AC is: connected Charger Voltage: 17800mV Charger Current: 2740mA 0.6998723C Chg Input Current:2848mA Battery SoC: 94% Battery Status AC is: connected Battery is: connected Battery LFCC: 4021 mAh (Last Full Charge Capacity) Battery Capacity: 3751 mAh 66.512 Wh Charge level: 93% Battery charging PS C:\Users\Daniel\clone\framework-system-private> sudo .\target\debug\framework_tool.exe --charge-rate-limit 0.5 Requested Rate: 0.5C Design Current: 3915mA Limiting Current to: 1957mA PS C:\Users\Daniel\clone\framework-system-private> sudo .\target\debug\framework_tool.exe --power Charger Status AC is: connected Charger Voltage: 17800mV Charger Current: 1956mA 0.49961686C Chg Input Current:2848mA Battery SoC: 94% Battery Status AC is: connected Battery is: connected Battery LFCC: 4021 mAh (Last Full Charge Capacity) Battery Capacity: 3754 mAh 66.584 Wh Charge level: 93% Battery charging ``` Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 1c1c59d commit 18ab45c

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

framework_lib/src/chromium_ec/mod.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
1111
use crate::ec_binary;
1212
use crate::os_specific;
13+
use crate::power;
1314
use crate::smbios;
1415
#[cfg(feature = "uefi")]
1516
use crate::uefi::shell_get_execution_break_flag;
@@ -407,6 +408,29 @@ impl CrosEc {
407408
}
408409
}
409410

411+
pub fn set_charge_rate_limit(&self, rate: f32, battery_soc: Option<f32>) -> EcResult<()> {
412+
let power_info = power::power_info(self).ok_or(EcError::DeviceError(
413+
"Failed to get battery info".to_string(),
414+
))?;
415+
let battery = power_info
416+
.battery
417+
.ok_or(EcError::DeviceError("No battery present".to_string()))?;
418+
println!("Requested Rate: {}C", rate);
419+
println!("Design Current: {}mA", battery.design_capacity);
420+
let current = (rate * (battery.design_capacity as f32)) as u32;
421+
println!("Limiting Current to: {}mA", current);
422+
if let Some(battery_soc) = battery_soc {
423+
let battery_soc = battery_soc as u8;
424+
EcRequestCurrentLimitV1 {
425+
current,
426+
battery_soc,
427+
}
428+
.send_command(self)
429+
} else {
430+
EcRequestCurrentLimitV0 { current }.send_command(self)
431+
}
432+
}
433+
410434
pub fn set_fp_led_percentage(&self, percentage: u8) -> EcResult<()> {
411435
// Sending bytes manually because the Set command, as opposed to the Get command,
412436
// does not return any data
@@ -1096,7 +1120,7 @@ impl CrosEc {
10961120
}
10971121
}
10981122

1099-
pub fn get_charge_state(&self) -> EcResult<()> {
1123+
pub fn get_charge_state(&self, power_info: &power::PowerInfo) -> EcResult<()> {
11001124
let res = EcRequestChargeStateGetV0 {
11011125
cmd: ChargeStateCmd::GetState as u8,
11021126
param: 0,
@@ -1113,6 +1137,10 @@ impl CrosEc {
11131137
);
11141138
println!(" Charger Voltage: {}mV", { res.chg_voltage });
11151139
println!(" Charger Current: {}mA", { res.chg_current });
1140+
if let Some(battery) = &power_info.battery {
1141+
let charge_rate = (res.chg_current as f32) / (battery.design_capacity as f32);
1142+
println!(" {:.2}C", charge_rate);
1143+
}
11161144
println!(" Chg Input Current:{}mA", { res.chg_input_current });
11171145
println!(" Battery SoC: {}%", { res.batt_state_of_charge });
11181146

framework_lib/src/commandline/clap_std.rs

+11
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ struct ClapCli {
160160
#[clap(num_args = ..2)]
161161
charge_current_limit: Vec<u32>,
162162

163+
/// Get or set max charge current limit
164+
#[arg(long)]
165+
#[clap(num_args = ..2)]
166+
charge_rate_limit: Vec<f32>,
167+
163168
/// Get GPIO value by name
164169
#[arg(long)]
165170
get_gpio: Option<String>,
@@ -318,6 +323,11 @@ pub fn parse(args: &[String]) -> Cli {
318323
1 => Some((args.charge_current_limit[0], None)),
319324
_ => None,
320325
};
326+
let charge_rate_limit = match args.charge_rate_limit.len() {
327+
2 => Some((args.charge_rate_limit[0], Some(args.charge_rate_limit[1]))),
328+
1 => Some((args.charge_rate_limit[0], None)),
329+
_ => None,
330+
};
321331

322332
Cli {
323333
verbosity: args.verbosity.log_level_filter(),
@@ -372,6 +382,7 @@ pub fn parse(args: &[String]) -> Cli {
372382
expansion_bay: args.expansion_bay,
373383
charge_limit: args.charge_limit,
374384
charge_current_limit,
385+
charge_rate_limit,
375386
get_gpio: args.get_gpio,
376387
fp_led_level: args.fp_led_level,
377388
fp_brightness: args.fp_brightness,

framework_lib/src/commandline/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ pub struct Cli {
176176
pub expansion_bay: bool,
177177
pub charge_limit: Option<Option<u8>>,
178178
pub charge_current_limit: Option<(u32, Option<u32>)>,
179+
pub charge_rate_limit: Option<(f32, Option<f32>)>,
179180
pub get_gpio: Option<String>,
180181
pub fp_led_level: Option<Option<FpBrightnessArg>>,
181182
pub fp_brightness: Option<Option<u8>>,
@@ -765,6 +766,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
765766
print_err(handle_charge_limit(&ec, maybe_limit));
766767
} else if let Some((limit, soc)) = args.charge_current_limit {
767768
print_err(ec.set_charge_current_limit(limit, soc));
769+
} else if let Some((limit, soc)) = args.charge_rate_limit {
770+
print_err(ec.set_charge_rate_limit(limit, soc));
768771
} else if let Some(gpio_name) = &args.get_gpio {
769772
print!("Getting GPIO value {}: ", gpio_name);
770773
if let Ok(value) = ec.get_gpio(gpio_name) {

framework_lib/src/commandline/uefi.rs

+30
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub fn parse(args: &[String]) -> Cli {
8989
expansion_bay: false,
9090
charge_limit: None,
9191
charge_current_limit: None,
92+
charge_rate_limit: None,
9293
get_gpio: None,
9394
fp_led_level: None,
9495
fp_brightness: None,
@@ -296,6 +297,35 @@ pub fn parse(args: &[String]) -> Cli {
296297
None
297298
};
298299
found_an_option = true;
300+
} else if arg == "--charge-rate-limit" {
301+
cli.charge_rate_limit = if args.len() > i + 2 {
302+
let limit = args[i + 1].parse::<f32>();
303+
let soc = args[i + 2].parse::<f32>();
304+
if let (Ok(limit), Ok(soc)) = (limit, soc) {
305+
Some((limit, Some(soc)))
306+
} else {
307+
println!(
308+
"Invalid values for --charge-rate-limit: '{} {}'. Must be u32 integers.",
309+
args[i + 1],
310+
args[i + 2]
311+
);
312+
None
313+
}
314+
} else if args.len() > i + 1 {
315+
if let Ok(limit) = args[i + 1].parse::<f32>() {
316+
Some((limit, None))
317+
} else {
318+
println!(
319+
"Invalid values for --charge-rate-limit: '{}'. Must be an integer.",
320+
args[i + 1],
321+
);
322+
None
323+
}
324+
} else {
325+
println!("--charge-rate-limit requires one or two. [limit] [soc] or [limit]");
326+
None
327+
};
328+
found_an_option = true;
299329
} else if arg == "--get-gpio" {
300330
cli.get_gpio = if args.len() > i + 1 {
301331
Some(args[i + 1].clone())

framework_lib/src/power.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,8 @@ pub fn is_standalone(ec: &CrosEc) -> bool {
471471
}
472472

473473
pub fn get_and_print_power_info(ec: &CrosEc) -> i32 {
474-
print_err_ref(&ec.get_charge_state());
475474
if let Some(power_info) = power_info(ec) {
475+
print_err_ref(&ec.get_charge_state(&power_info));
476476
print_battery_information(&power_info);
477477
if let Some(_battery) = &power_info.battery {
478478
return 0;

0 commit comments

Comments
 (0)