ectool version 0.2.1:
- Add hidapi feature - Add redox_hwio feature - Add feature documentation
This commit is contained in:
parent
8da8342e40
commit
726a0e0837
29
tool/Cargo.lock
generated
29
tool/Cargo.lock
generated
@ -1,32 +1,47 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
name = "cc"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hidapi"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "redox_hwio"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system76_ectool"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"hidapi 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.78 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_hwio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum cc 1.0.60 (registry+https://github.com/rust-lang/crates.io-index)" = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
|
||||
"checksum hidapi 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5c6ffb97f2ec5835ec73bcea5256fc2cd57a13c5958230778ef97f11900ba661"
|
||||
"checksum libc 0.2.78 (registry+https://github.com/rust-lang/crates.io-index)" = "aa7087f49d294270db4e1928fc110c976cd4b9e5a16348e0a1df09afa99e6c98"
|
||||
"checksum pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
|
||||
"checksum redox_hwio 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41aa2c4c67329a04106644cad336238aa5adecfd73d06fb10339d472ce6d8070"
|
||||
|
@ -1,11 +1,12 @@
|
||||
[package]
|
||||
name = "system76_ectool"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
edition = "2018"
|
||||
description = "System76 EC tool"
|
||||
license = "MIT"
|
||||
authors = ["Jeremy Soller <jeremy@system76.com>"]
|
||||
repository = "https://github.com/system76/ec"
|
||||
documentation = "https://docs.rs/system76_ectool"
|
||||
|
||||
[lib]
|
||||
name = "ectool"
|
||||
@ -16,9 +17,12 @@ required-features = ["std"]
|
||||
|
||||
[dependencies]
|
||||
libc = { version = "0.2", optional = true }
|
||||
redox_hwio = "0.1.3"
|
||||
hidapi = { version = "1.2", optional = true }
|
||||
redox_hwio = { version = "0.1.3", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
stable = ["redox_hwio/stable"]
|
||||
std = ["libc"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
76
tool/src/access/hid.rs
Normal file
76
tool/src/access/hid.rs
Normal file
@ -0,0 +1,76 @@
|
||||
use hidapi::HidDevice;
|
||||
|
||||
use crate::{
|
||||
Access,
|
||||
Error,
|
||||
};
|
||||
|
||||
/// Use USB HID access, only for USB ECs
|
||||
pub struct AccessHid {
|
||||
device: HidDevice,
|
||||
retries: u32,
|
||||
timeout: i32,
|
||||
}
|
||||
|
||||
impl AccessHid {
|
||||
/// Use hidapi device with specified retries and timeout for each try in milliseconds
|
||||
pub fn new(device: HidDevice, retries: u32, timeout: i32) -> Result<Self, Error> {
|
||||
//TODO: probe?
|
||||
Ok(Self {
|
||||
device,
|
||||
retries,
|
||||
timeout,
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn command_try(&mut self, cmd: u8, data: &mut [u8]) -> Result<Option<u8>, Error> {
|
||||
const HID_CMD: usize = 1;
|
||||
const HID_RES: usize = 2;
|
||||
const HID_DATA: usize = 3;
|
||||
|
||||
let mut hid_data = [0; 33];
|
||||
if data.len() + HID_DATA > hid_data.len() {
|
||||
return Err(Error::DataLength(data.len()));
|
||||
}
|
||||
|
||||
hid_data[HID_CMD] = cmd;
|
||||
for i in 0..data.len() {
|
||||
hid_data[HID_DATA + i] = data[i];
|
||||
}
|
||||
|
||||
let count = self.device.write(&hid_data).map_err(Error::Hid)?;
|
||||
if count != hid_data.len() {
|
||||
return Err(Error::Verify);
|
||||
}
|
||||
|
||||
let count = self.device.read_timeout(&mut hid_data[1..], self.timeout).map_err(Error::Hid)?;
|
||||
if count == hid_data.len() - 1 {
|
||||
for i in 0..data.len() {
|
||||
data[i] = hid_data[HID_DATA + i];
|
||||
}
|
||||
|
||||
Ok(Some(hid_data[HID_RES]))
|
||||
} else if count == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(Error::Verify)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Access for AccessHid {
|
||||
unsafe fn command(&mut self, cmd: u8, data: &mut [u8]) -> Result<u8, Error> {
|
||||
for _ in 0..self.retries {
|
||||
match self.command_try(cmd, data)? {
|
||||
Some(some) => return Ok(some),
|
||||
None => continue,
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::Timeout)
|
||||
}
|
||||
|
||||
fn data_size(&self) -> usize {
|
||||
32 - 2
|
||||
}
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
pub(crate) const SMFI_CMD_BASE: u16 = 0xE00;
|
||||
pub(crate) const SMFI_CMD_SIZE: usize = 0x100;
|
||||
const SMFI_CMD_BASE: u16 = 0xE00;
|
||||
const SMFI_CMD_SIZE: usize = 0x100;
|
||||
|
||||
pub(crate) const SMFI_DBG_BASE: u16 = 0xF00;
|
||||
pub(crate) const SMFI_DBG_SIZE: usize = 0x100;
|
||||
const SMFI_DBG_BASE: u16 = 0xF00;
|
||||
const SMFI_DBG_SIZE: usize = 0x100;
|
||||
|
||||
pub(crate) const SMFI_CMD_CMD: u8 = 0x00;
|
||||
pub(crate) const SMFI_CMD_RES: u8 = 0x01;
|
||||
pub(crate) const SMFI_CMD_DATA: u8 = 0x02;
|
||||
const SMFI_CMD_CMD: u8 = 0x00;
|
||||
const SMFI_CMD_RES: u8 = 0x01;
|
||||
const SMFI_CMD_DATA: u8 = 0x02;
|
||||
|
||||
#[cfg(feature = "redox_hwio")]
|
||||
pub use self::direct::AccessLpcDirect;
|
||||
#[cfg(feature = "redox_hwio")]
|
||||
mod direct;
|
||||
|
||||
#[cfg(all(feature = "std", target_os = "linux"))]
|
||||
|
@ -1,6 +1,19 @@
|
||||
use crate::Error;
|
||||
|
||||
#[cfg(feature = "hidapi")]
|
||||
pub use self::hid::AccessHid;
|
||||
#[cfg(feature = "hidapi")]
|
||||
mod hid;
|
||||
|
||||
#[cfg(any(
|
||||
feature = "redox_hwio",
|
||||
all(feature = "std", target_os = "linux")
|
||||
))]
|
||||
pub use self::lpc::*;
|
||||
#[cfg(any(
|
||||
feature = "redox_hwio",
|
||||
all(feature = "std", target_os = "linux")
|
||||
))]
|
||||
mod lpc;
|
||||
|
||||
/// Access method for running an EC command
|
||||
|
@ -21,5 +21,8 @@ pub enum Error {
|
||||
WouldBlock,
|
||||
/// Encountered a std::io::Error
|
||||
#[cfg(feature = "std")]
|
||||
Io(std::io::Error)
|
||||
Io(std::io::Error),
|
||||
/// Encountered a hidapi::Error
|
||||
#[cfg(feature = "hidapi")]
|
||||
Hid(hidapi::HidError),
|
||||
}
|
||||
|
@ -1,5 +1,19 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
//! Library for accessing System76 ECs
|
||||
//! First, construct an access method, using an object implementing the `Access` trait. Next, an Ec
|
||||
//! object can be contructed, which exposes the command interface.
|
||||
//!
|
||||
//! There are some differences between targets and features that are listed below:
|
||||
//! - `AccessHid` requires the `hidapi` feature. Only functional on USB ECs.
|
||||
//! - `AccessLpcDirect` requires the `redox_hwio` feature and a nightly compiler. This method is
|
||||
//! only recommended for use in firmware with LPC ECs, as mutual exclusion is not guaranteed.
|
||||
//! - `AccessLpcLinux` requires the `std` feature and `linux` target_os. Recommended for LPC ECs,
|
||||
//! as this method can utilize mutual exclusion.
|
||||
//! - `EcLegacy`, `Pmc`, and `SuperIo` all require the `redox_hwio` feature and a nightly
|
||||
//! compiler. It is only recommended to use these in firmware, as mutual exclusion is not
|
||||
//! guaranteed.
|
||||
|
||||
pub use self::access::*;
|
||||
mod access;
|
||||
|
||||
@ -12,16 +26,22 @@ mod error;
|
||||
pub use self::firmware::Firmware;
|
||||
mod firmware;
|
||||
|
||||
#[cfg(feature = "redox_hwio")]
|
||||
pub use self::legacy::EcLegacy;
|
||||
#[cfg(feature = "redox_hwio")]
|
||||
mod legacy;
|
||||
|
||||
#[cfg(feature = "redox_hwio")]
|
||||
pub use self::pmc::Pmc;
|
||||
#[cfg(feature = "redox_hwio")]
|
||||
mod pmc;
|
||||
|
||||
pub use self::spi::{Spi, SpiRom, SpiTarget};
|
||||
mod spi;
|
||||
|
||||
#[cfg(feature = "redox_hwio")]
|
||||
pub use self::super_io::SuperIo;
|
||||
#[cfg(feature = "redox_hwio")]
|
||||
mod super_io;
|
||||
|
||||
pub use self::timeout::Timeout;
|
||||
|
Loading…
x
Reference in New Issue
Block a user