mirror of
https://codeberg.org/ral/rwedid.git
synced 2024-08-16 09:59:49 +02:00
Autodetect number of blocks to handle
This commit is contained in:
parent
09114c1c3e
commit
a1d0e66ec5
7 changed files with 64 additions and 20 deletions
|
@ -1,8 +1,5 @@
|
|||
use clap::Parser;
|
||||
|
||||
// Size of EDID binary block
|
||||
pub const BLOCK_SIZE: usize = 128;
|
||||
|
||||
fn hex_address(a: &str) -> Result<u16, std::num::ParseIntError> {
|
||||
u16::from_str_radix(a.trim_start_matches("0x"), 16)
|
||||
}
|
||||
|
@ -18,7 +15,7 @@ pub struct Args {
|
|||
#[arg(short, long, default_value = "0x50", value_parser = hex_address)]
|
||||
pub address: u16,
|
||||
|
||||
/// Number of 128-byte blocks to read, defaults to reading the base block.
|
||||
#[arg(short, long, default_value_t = 1)]
|
||||
pub blocks: usize,
|
||||
/// Number of 128-byte blocks to read, defaults to autodetect from data
|
||||
#[arg(short, long, default_value = None)]
|
||||
pub blocks: Option<usize>,
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
use clap::Parser;
|
||||
use rwedid::args::*;
|
||||
use rwedid::i2c::*;
|
||||
use std::io::{self, Write};
|
||||
use rwedid::misc::*;
|
||||
use rwedid::std::*;
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
// Parse command line arguments
|
||||
let args = Args::parse();
|
||||
|
||||
// Read the data from the chip
|
||||
let bytes = read_from_bus(&args.device, args.address, BLOCK_SIZE * args.blocks)?;
|
||||
let bytes = block_by_block_read(args.blocks, |o, l| {
|
||||
read_from_bus(&args.device, args.address, o, l)
|
||||
})?;
|
||||
|
||||
// Write binary blob to stdout
|
||||
let mut stdout = io::stdout().lock();
|
||||
stdout.write_all(&bytes)
|
||||
write_to_std(&bytes)
|
||||
}
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
use clap::Parser;
|
||||
use rwedid::args::*;
|
||||
use rwedid::i2c::*;
|
||||
use std::io::{self, Read};
|
||||
use rwedid::misc::*;
|
||||
use rwedid::std::*;
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
// Parse command line arguments
|
||||
let args = Args::parse();
|
||||
|
||||
// Read binary from stdin
|
||||
let data_length = args.blocks * BLOCK_SIZE;
|
||||
let mut data = vec![0; data_length];
|
||||
|
||||
// Read binary blob from stdin
|
||||
io::stdin().read_exact(data.as_mut_slice())?;
|
||||
let data = block_by_block_read(args.blocks, |_, l| read_from_std(l))?;
|
||||
|
||||
// Write the data to the chip
|
||||
write_to_bus(&args.device, args.address, data.as_slice())
|
||||
|
|
|
@ -7,6 +7,7 @@ use std::time::Duration;
|
|||
pub fn read_from_bus(
|
||||
i2c_device: &str,
|
||||
slave_address: u16,
|
||||
memory_address: u8,
|
||||
data_length: usize,
|
||||
) -> Result<Vec<u8>, std::io::Error> {
|
||||
let mut data = vec![0; data_length];
|
||||
|
@ -14,7 +15,7 @@ pub fn read_from_bus(
|
|||
let mut dev = LinuxI2CDevice::new(i2c_device, slave_address)?;
|
||||
let mut msgs = [
|
||||
// Address to read from
|
||||
LinuxI2CMessage::write(&[0x00]),
|
||||
LinuxI2CMessage::write(&[memory_address]),
|
||||
// Read data into buffer
|
||||
LinuxI2CMessage::read(&mut data),
|
||||
];
|
||||
|
@ -34,9 +35,8 @@ pub fn write_to_bus(
|
|||
|
||||
// Write 8 bytes at a time
|
||||
for (i, chunk) in data.chunks_exact(8).into_iter().enumerate() {
|
||||
|
||||
// Memory address
|
||||
let memory_address : u8 = (i as u8) * 8;
|
||||
let memory_address: u8 = (i as u8) * 8;
|
||||
let mut msgs = [
|
||||
// Address to write to
|
||||
LinuxI2CMessage::write(&[memory_address]),
|
||||
|
@ -47,7 +47,7 @@ pub fn write_to_bus(
|
|||
dev.transfer(&mut msgs)?;
|
||||
|
||||
thread::sleep(Duration::from_millis(20));
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
pub mod args;
|
||||
pub mod i2c;
|
||||
pub mod misc;
|
||||
pub mod std;
|
||||
|
|
31
src/misc.rs
Normal file
31
src/misc.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Size of EDID binary block
|
||||
pub const BLOCK_SIZE: usize = 128;
|
||||
|
||||
pub fn block_by_block_read(
|
||||
blocks: Option<usize>,
|
||||
read: impl Fn(u8, usize) -> Result<Vec<u8>, std::io::Error>,
|
||||
) -> Result<Vec<u8>, std::io::Error> {
|
||||
match blocks {
|
||||
// Default: autodetect number of extension blocks
|
||||
None => {
|
||||
// Read first block (128 bytes)
|
||||
let data_base = read(0x00, BLOCK_SIZE)?;
|
||||
// Try to read remaining bytes
|
||||
let data_extensions = match data_base.len() {
|
||||
// Proper 128 byte block
|
||||
BLOCK_SIZE => {
|
||||
// Number of extension blocks that should follow
|
||||
let num_extensions: usize = data_base[BLOCK_SIZE - 2].into();
|
||||
// Read remaining blocks
|
||||
read(BLOCK_SIZE as u8, num_extensions * BLOCK_SIZE)?
|
||||
}
|
||||
// Something else, obviously broken
|
||||
_ => vec![],
|
||||
};
|
||||
// Return complete byte stream
|
||||
Ok([data_base, data_extensions].concat())
|
||||
}
|
||||
// Explicitly read as many blocks as specified by user
|
||||
Some(blocks) => read(0x00, blocks * BLOCK_SIZE),
|
||||
}
|
||||
}
|
15
src/std.rs
Normal file
15
src/std.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use std::io::{self, Read, Write};
|
||||
|
||||
pub fn read_from_std(data_length: usize) -> Result<Vec<u8>, std::io::Error> {
|
||||
// Buffer to read into
|
||||
let mut data = vec![0; data_length];
|
||||
// Read from stdin
|
||||
io::stdin().read_exact(data.as_mut_slice())?;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub fn write_to_std(data: &[u8]) -> Result<(), std::io::Error> {
|
||||
// Write data to stdout
|
||||
let mut stdout = io::stdout().lock();
|
||||
stdout.write_all(&data)
|
||||
}
|
Loading…
Reference in a new issue