tool: Add --access
argument to work with sim or hid
This commit is contained in:
parent
7c5ba4e62c
commit
49b79f665b
@ -13,7 +13,7 @@ name = "ectool"
|
|||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "system76_ectool"
|
name = "system76_ectool"
|
||||||
required-features = ["std"]
|
required-features = ["std", "hidapi"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2"
|
clap = "2"
|
||||||
@ -22,7 +22,7 @@ hidapi = { version = "1.2", default-features = false, features = ["linux-static-
|
|||||||
redox_hwio = { version = "0.1.3", optional = true }
|
redox_hwio = { version = "0.1.3", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std", "hidapi"]
|
||||||
std = ["libc"]
|
std = ["libc"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
|
102
tool/src/main.rs
102
tool/src/main.rs
@ -1,7 +1,9 @@
|
|||||||
use clap::{Arg, App, AppSettings, SubCommand};
|
use clap::{Arg, App, AppSettings, SubCommand};
|
||||||
use ectool::{
|
use ectool::{
|
||||||
Access,
|
Access,
|
||||||
|
AccessHid,
|
||||||
AccessLpcLinux,
|
AccessLpcLinux,
|
||||||
|
AccessLpcSim,
|
||||||
Ec,
|
Ec,
|
||||||
Error,
|
Error,
|
||||||
Firmware,
|
Firmware,
|
||||||
@ -10,6 +12,7 @@ use ectool::{
|
|||||||
SpiRom,
|
SpiRom,
|
||||||
SpiTarget,
|
SpiTarget,
|
||||||
};
|
};
|
||||||
|
use hidapi::HidApi;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
fs,
|
fs,
|
||||||
@ -19,14 +22,8 @@ use std::{
|
|||||||
thread,
|
thread,
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe fn ec() -> Result<Ec<AccessLpcLinux>, Error> {
|
unsafe fn console(ec: &mut Ec<Box<dyn Access>>) -> Result<(), Error> {
|
||||||
let access = AccessLpcLinux::new(Duration::new(1, 0))?;
|
|
||||||
Ec::new(access)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn console() -> Result<(), Error> {
|
|
||||||
//TODO: driver support for reading debug region?
|
//TODO: driver support for reading debug region?
|
||||||
let mut ec = ec()?;
|
|
||||||
let access = ec.access();
|
let access = ec.access();
|
||||||
|
|
||||||
let mut head = access.read_debug(0)? as usize;
|
let mut head = access.read_debug(0)? as usize;
|
||||||
@ -61,7 +58,7 @@ unsafe fn flash_read<S: Spi>(spi: &mut SpiRom<S, StdTimeout>, rom: &mut [u8], se
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn flash_inner(ec: &mut Ec<AccessLpcLinux>, firmware: &Firmware, target: SpiTarget, scratch: bool) -> Result<(), Error> {
|
unsafe fn flash_inner(ec: &mut Ec<Box<dyn Access>>, firmware: &Firmware, target: SpiTarget, scratch: bool) -> Result<(), Error> {
|
||||||
let rom_size = 128 * 1024;
|
let rom_size = 128 * 1024;
|
||||||
|
|
||||||
let mut new_rom = firmware.data.to_vec();
|
let mut new_rom = firmware.data.to_vec();
|
||||||
@ -138,7 +135,7 @@ unsafe fn flash_inner(ec: &mut Ec<AccessLpcLinux>, firmware: &Firmware, target:
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn flash(path: &str, target: SpiTarget) -> Result<(), Error> {
|
unsafe fn flash(ec: &mut Ec<Box<dyn Access>>, path: &str, target: SpiTarget) -> Result<(), Error> {
|
||||||
let scratch = true;
|
let scratch = true;
|
||||||
|
|
||||||
//TODO: remove unwraps
|
//TODO: remove unwraps
|
||||||
@ -147,7 +144,6 @@ unsafe fn flash(path: &str, target: SpiTarget) -> Result<(), Error> {
|
|||||||
println!("file board: {:?}", str::from_utf8(firmware.board));
|
println!("file board: {:?}", str::from_utf8(firmware.board));
|
||||||
println!("file version: {:?}", str::from_utf8(firmware.version));
|
println!("file version: {:?}", str::from_utf8(firmware.version));
|
||||||
|
|
||||||
let mut ec = ec()?;
|
|
||||||
let data_size = ec.access().data_size();
|
let data_size = ec.access().data_size();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -179,7 +175,7 @@ unsafe fn flash(path: &str, target: SpiTarget) -> Result<(), Error> {
|
|||||||
eprintln!("Sync");
|
eprintln!("Sync");
|
||||||
let _ = process::Command::new("sync").status();
|
let _ = process::Command::new("sync").status();
|
||||||
|
|
||||||
let res = flash_inner(&mut ec, &firmware, target, scratch);
|
let res = flash_inner(ec, &firmware, target, scratch);
|
||||||
eprintln!("Result: {:X?}", res);
|
eprintln!("Result: {:X?}", res);
|
||||||
|
|
||||||
eprintln!("Sync");
|
eprintln!("Sync");
|
||||||
@ -198,8 +194,7 @@ unsafe fn flash(path: &str, target: SpiTarget) -> Result<(), Error> {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn info() -> Result<(), Error> {
|
unsafe fn info(ec: &mut Ec<Box<dyn Access>>) -> Result<(), Error> {
|
||||||
let mut ec = ec()?;
|
|
||||||
let data_size = ec.access().data_size();
|
let data_size = ec.access().data_size();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -225,41 +220,31 @@ unsafe fn info() -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn print(message: &[u8]) -> Result<(), Error> {
|
unsafe fn print(ec: &mut Ec<Box<dyn Access>>, message: &[u8]) -> Result<(), Error> {
|
||||||
let mut ec = ec()?;
|
|
||||||
|
|
||||||
ec.print(message)?;
|
ec.print(message)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn fan_get(index: u8) -> Result<(), Error> {
|
unsafe fn fan_get(ec: &mut Ec<Box<dyn Access>>, index: u8) -> Result<(), Error> {
|
||||||
let mut ec = ec()?;
|
|
||||||
|
|
||||||
let duty = ec.fan_get(index)?;
|
let duty = ec.fan_get(index)?;
|
||||||
println!("{}", duty);
|
println!("{}", duty);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn fan_set(index: u8, duty: u8) -> Result<(), Error> {
|
unsafe fn fan_set(ec: &mut Ec<Box<dyn Access>>, index: u8, duty: u8) -> Result<(), Error> {
|
||||||
let mut ec = ec()?;
|
|
||||||
|
|
||||||
ec.fan_set(index, duty)
|
ec.fan_set(index, duty)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn keymap_get(layer: u8, output: u8, input: u8) -> Result<(), Error> {
|
unsafe fn keymap_get(ec: &mut Ec<Box<dyn Access>>, layer: u8, output: u8, input: u8) -> Result<(), Error> {
|
||||||
let mut ec = ec()?;
|
|
||||||
|
|
||||||
let value = ec.keymap_get(layer, output, input)?;
|
let value = ec.keymap_get(layer, output, input)?;
|
||||||
println!("{:04X}", value);
|
println!("{:04X}", value);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn keymap_set(layer: u8, output: u8, input: u8, value: u16) -> Result<(), Error> {
|
unsafe fn keymap_set(ec: &mut Ec<Box<dyn Access>>, layer: u8, output: u8, input: u8, value: u16) -> Result<(), Error> {
|
||||||
let mut ec = ec()?;
|
|
||||||
|
|
||||||
ec.keymap_set(layer, output, input, value)
|
ec.keymap_set(layer, output, input, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +258,11 @@ fn validate_from_str<T: FromStr>(s: String) -> Result<(), String>
|
|||||||
fn main() {
|
fn main() {
|
||||||
let matches = App::new("system76_ectool")
|
let matches = App::new("system76_ectool")
|
||||||
.setting(AppSettings::SubcommandRequired)
|
.setting(AppSettings::SubcommandRequired)
|
||||||
|
.arg(Arg::with_name("access")
|
||||||
|
.long("access")
|
||||||
|
.possible_values(&["lpc-linux", "lpc-sim", "hid"])
|
||||||
|
.default_value("lpc-linux")
|
||||||
|
)
|
||||||
.subcommand(SubCommand::with_name("console"))
|
.subcommand(SubCommand::with_name("console"))
|
||||||
.subcommand(SubCommand::with_name("fan")
|
.subcommand(SubCommand::with_name("fan")
|
||||||
.arg(Arg::with_name("index")
|
.arg(Arg::with_name("index")
|
||||||
@ -317,8 +307,46 @@ fn main() {
|
|||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
|
let get_ec = || -> Result<_, Error> {
|
||||||
|
unsafe {
|
||||||
|
match matches.value_of("access").unwrap() {
|
||||||
|
"lpc-linux" => {
|
||||||
|
let access = AccessLpcLinux::new(Duration::new(1, 0))?;
|
||||||
|
Ok(Ec::new(access)?.into_dyn())
|
||||||
|
},
|
||||||
|
"lpc-sim" => {
|
||||||
|
let access = AccessLpcSim::new(Duration::new(1, 0))?;
|
||||||
|
Ok(Ec::new(access)?.into_dyn())
|
||||||
|
},
|
||||||
|
"hid" => {
|
||||||
|
let api = HidApi::new()?;
|
||||||
|
for info in api.device_list() {
|
||||||
|
match (info.vendor_id(), info.product_id(), info.interface_number()) {
|
||||||
|
// System76 launch_1
|
||||||
|
(0x3384, 0x0001, 1) => {
|
||||||
|
let device = info.open_device(&api)?;
|
||||||
|
let access = AccessHid::new(device, 10, 100)?;
|
||||||
|
return Ok(Ec::new(access)?.into_dyn());
|
||||||
|
}
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(hidapi::HidError::OpenHidDeviceError.into())
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut ec = match get_ec() {
|
||||||
|
Ok(ec) => ec,
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to connect to EC: {:X?}", err);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
("console", Some(_sub_m)) => match unsafe { console() } {
|
("console", Some(_sub_m)) => match unsafe { console(&mut ec) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to read console: {:X?}", err);
|
eprintln!("failed to read console: {:X?}", err);
|
||||||
@ -329,14 +357,14 @@ fn main() {
|
|||||||
let index = sub_m.value_of("index").unwrap().parse::<u8>().unwrap();
|
let index = sub_m.value_of("index").unwrap().parse::<u8>().unwrap();
|
||||||
let duty_opt = sub_m.value_of("duty").map(|x| x.parse::<u8>().unwrap());
|
let duty_opt = sub_m.value_of("duty").map(|x| x.parse::<u8>().unwrap());
|
||||||
match duty_opt {
|
match duty_opt {
|
||||||
Some(duty) => match unsafe { fan_set(index, duty) } {
|
Some(duty) => match unsafe { fan_set(&mut ec, index, duty) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to set fan {} to {}: {:X?}", index, duty, err);
|
eprintln!("failed to set fan {} to {}: {:X?}", index, duty, err);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
None => match unsafe { fan_get(index) } {
|
None => match unsafe { fan_get(&mut ec, index) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to get fan {}: {:X?}", index, err);
|
eprintln!("failed to get fan {}: {:X?}", index, err);
|
||||||
@ -347,7 +375,7 @@ fn main() {
|
|||||||
},
|
},
|
||||||
("flash", Some(sub_m)) => {
|
("flash", Some(sub_m)) => {
|
||||||
let path = sub_m.value_of("path").unwrap();
|
let path = sub_m.value_of("path").unwrap();
|
||||||
match unsafe { flash(&path, SpiTarget::Main) } {
|
match unsafe { flash(&mut ec, &path, SpiTarget::Main) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to flash '{}': {:X?}", path, err);
|
eprintln!("failed to flash '{}': {:X?}", path, err);
|
||||||
@ -357,7 +385,7 @@ fn main() {
|
|||||||
},
|
},
|
||||||
("flash_backup", Some(sub_m)) => {
|
("flash_backup", Some(sub_m)) => {
|
||||||
let path = sub_m.value_of("path").unwrap();
|
let path = sub_m.value_of("path").unwrap();
|
||||||
match unsafe { flash(&path, SpiTarget::Backup) } {
|
match unsafe { flash(&mut ec, &path, SpiTarget::Backup) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to flash '{}': {:X?}", path, err);
|
eprintln!("failed to flash '{}': {:X?}", path, err);
|
||||||
@ -365,7 +393,7 @@ fn main() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
("info", Some(_sub_m)) => match unsafe { info() } {
|
("info", Some(_sub_m)) => match unsafe { info(&mut ec) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to read info: {:X?}", err);
|
eprintln!("failed to read info: {:X?}", err);
|
||||||
@ -378,7 +406,7 @@ fn main() {
|
|||||||
let input = sub_m.value_of("input").unwrap().parse::<u8>().unwrap();
|
let input = sub_m.value_of("input").unwrap().parse::<u8>().unwrap();
|
||||||
match sub_m.value_of("value") {
|
match sub_m.value_of("value") {
|
||||||
Some(value_str) => match u16::from_str_radix(value_str.trim_start_matches("0x"), 16) {
|
Some(value_str) => match u16::from_str_radix(value_str.trim_start_matches("0x"), 16) {
|
||||||
Ok(value) => match unsafe { keymap_set(layer, output, input, value) } {
|
Ok(value) => match unsafe { keymap_set(&mut ec, layer, output, input, value) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to set keymap {}, {}, {} to {}: {:X?}", layer, output, input, value, err);
|
eprintln!("failed to set keymap {}, {}, {} to {}: {:X?}", layer, output, input, value, err);
|
||||||
@ -390,7 +418,7 @@ fn main() {
|
|||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => match unsafe { keymap_get(layer, output, input) } {
|
None => match unsafe { keymap_get(&mut ec, layer, output, input) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to get keymap {}, {}, {}: {:X?}", layer, output, input, err);
|
eprintln!("failed to get keymap {}, {}, {}: {:X?}", layer, output, input, err);
|
||||||
@ -402,7 +430,7 @@ fn main() {
|
|||||||
("print", Some(sub_m)) => for arg in sub_m.values_of("message").unwrap() {
|
("print", Some(sub_m)) => for arg in sub_m.values_of("message").unwrap() {
|
||||||
let mut arg = arg.to_owned();
|
let mut arg = arg.to_owned();
|
||||||
arg.push('\n');
|
arg.push('\n');
|
||||||
match unsafe { print(&arg.as_bytes()) } {
|
match unsafe { print(&mut ec, &arg.as_bytes()) } {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("failed to print '{}': {:X?}", arg, err);
|
eprintln!("failed to print '{}': {:X?}", arg, err);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user