1
0
Fork 0
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:
Ral 2023-06-06 00:19:43 +02:00
parent 09114c1c3e
commit a1d0e66ec5
7 changed files with 64 additions and 20 deletions

View file

@ -1,8 +1,5 @@
use clap::Parser; use clap::Parser;
// Size of EDID binary block
pub const BLOCK_SIZE: usize = 128;
fn hex_address(a: &str) -> Result<u16, std::num::ParseIntError> { fn hex_address(a: &str) -> Result<u16, std::num::ParseIntError> {
u16::from_str_radix(a.trim_start_matches("0x"), 16) 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)] #[arg(short, long, default_value = "0x50", value_parser = hex_address)]
pub address: u16, pub address: u16,
/// Number of 128-byte blocks to read, defaults to reading the base block. /// Number of 128-byte blocks to read, defaults to autodetect from data
#[arg(short, long, default_value_t = 1)] #[arg(short, long, default_value = None)]
pub blocks: usize, pub blocks: Option<usize>,
} }

View file

@ -1,16 +1,18 @@
use clap::Parser; use clap::Parser;
use rwedid::args::*; use rwedid::args::*;
use rwedid::i2c::*; use rwedid::i2c::*;
use std::io::{self, Write}; use rwedid::misc::*;
use rwedid::std::*;
fn main() -> Result<(), std::io::Error> { fn main() -> Result<(), std::io::Error> {
// Parse command line arguments // Parse command line arguments
let args = Args::parse(); let args = Args::parse();
// Read the data from the chip // 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 // Write binary blob to stdout
let mut stdout = io::stdout().lock(); write_to_std(&bytes)
stdout.write_all(&bytes)
} }

View file

@ -1,18 +1,15 @@
use clap::Parser; use clap::Parser;
use rwedid::args::*; use rwedid::args::*;
use rwedid::i2c::*; use rwedid::i2c::*;
use std::io::{self, Read}; use rwedid::misc::*;
use rwedid::std::*;
fn main() -> Result<(), std::io::Error> { fn main() -> Result<(), std::io::Error> {
// Parse command line arguments // Parse command line arguments
let args = Args::parse(); let args = Args::parse();
// Read binary from stdin // Read binary from stdin
let data_length = args.blocks * BLOCK_SIZE; let data = block_by_block_read(args.blocks, |_, l| read_from_std(l))?;
let mut data = vec![0; data_length];
// Read binary blob from stdin
io::stdin().read_exact(data.as_mut_slice())?;
// Write the data to the chip // Write the data to the chip
write_to_bus(&args.device, args.address, data.as_slice()) write_to_bus(&args.device, args.address, data.as_slice())

View file

@ -7,6 +7,7 @@ use std::time::Duration;
pub fn read_from_bus( pub fn read_from_bus(
i2c_device: &str, i2c_device: &str,
slave_address: u16, slave_address: u16,
memory_address: u8,
data_length: usize, data_length: usize,
) -> Result<Vec<u8>, std::io::Error> { ) -> Result<Vec<u8>, std::io::Error> {
let mut data = vec![0; data_length]; 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 dev = LinuxI2CDevice::new(i2c_device, slave_address)?;
let mut msgs = [ let mut msgs = [
// Address to read from // Address to read from
LinuxI2CMessage::write(&[0x00]), LinuxI2CMessage::write(&[memory_address]),
// Read data into buffer // Read data into buffer
LinuxI2CMessage::read(&mut data), LinuxI2CMessage::read(&mut data),
]; ];
@ -34,7 +35,6 @@ pub fn write_to_bus(
// Write 8 bytes at a time // Write 8 bytes at a time
for (i, chunk) in data.chunks_exact(8).into_iter().enumerate() { for (i, chunk) in data.chunks_exact(8).into_iter().enumerate() {
// Memory address // Memory address
let memory_address: u8 = (i as u8) * 8; let memory_address: u8 = (i as u8) * 8;
let mut msgs = [ let mut msgs = [
@ -47,7 +47,7 @@ pub fn write_to_bus(
dev.transfer(&mut msgs)?; dev.transfer(&mut msgs)?;
thread::sleep(Duration::from_millis(20)); thread::sleep(Duration::from_millis(20));
}; }
Ok(()) Ok(())
} }

View file

@ -1,2 +1,4 @@
pub mod args; pub mod args;
pub mod i2c; pub mod i2c;
pub mod misc;
pub mod std;

31
src/misc.rs Normal file
View 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
View 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)
}