ectool version 0.2.1:
- Add hidapi feature - Add redox_hwio feature - Add feature documentation
This commit is contained in:
committed by
Jeremy Soller
parent
8da8342e40
commit
726a0e0837
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;
|
||||
|
Reference in New Issue
Block a user