ectool version 0.2.1:

- Add hidapi feature
- Add redox_hwio feature
- Add feature documentation
This commit is contained in:
Jeremy Soller 2020-10-02 08:56:30 -06:00 committed by Jeremy Soller
parent 8da8342e40
commit 726a0e0837
7 changed files with 151 additions and 18 deletions

29
tool/Cargo.lock generated
View File

@ -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"

View File

@ -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
View 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
}
}

View File

@ -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"))]

View File

@ -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

View File

@ -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),
}

View File

@ -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;