mirror of
https://codeberg.org/ral/rwedid.git
synced 2024-08-16 09:59:49 +02:00
Add checksum check
This commit is contained in:
parent
a1d0e66ec5
commit
71e9ff9441
7 changed files with 60 additions and 27 deletions
|
@ -1,8 +1,8 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use rwedid::args::*;
|
use rwedid::args::Args;
|
||||||
use rwedid::i2c::*;
|
use rwedid::i2c::read_from_bus;
|
||||||
use rwedid::misc::*;
|
use rwedid::io::block_by_block_read;
|
||||||
use rwedid::std::*;
|
use rwedid::std::write_to_stdout;
|
||||||
|
|
||||||
fn main() -> Result<(), std::io::Error> {
|
fn main() -> Result<(), std::io::Error> {
|
||||||
// Parse command line arguments
|
// Parse command line arguments
|
||||||
|
@ -14,5 +14,5 @@ fn main() -> Result<(), std::io::Error> {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Write binary blob to stdout
|
// Write binary blob to stdout
|
||||||
write_to_std(&bytes)
|
write_to_stdout(&bytes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use rwedid::args::*;
|
use rwedid::args::Args;
|
||||||
use rwedid::i2c::*;
|
use rwedid::i2c::write_to_bus;
|
||||||
use rwedid::misc::*;
|
use rwedid::io::block_by_block_read;
|
||||||
use rwedid::std::*;
|
use rwedid::std::read_from_stdin;
|
||||||
|
|
||||||
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 blob from stdin
|
||||||
let data = block_by_block_read(args.blocks, |_, l| read_from_std(l))?;
|
let data = block_by_block_read(args.blocks, |_, l| read_from_stdin(l))?;
|
||||||
|
|
||||||
// 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, 0x00, data.as_slice())
|
||||||
}
|
}
|
||||||
|
|
15
src/checksum.rs
Normal file
15
src/checksum.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Compute and check the checksum over the bytes of a block.
|
||||||
|
pub fn checksum(bytes: &[u8]) -> u8 {
|
||||||
|
bytes.iter().fold(0u32, |x, y| x + (*y as u32)) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the checksum
|
||||||
|
pub fn valid_checksum(bytes: &[u8]) -> bool {
|
||||||
|
checksum(bytes) == 0x00
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the checksum to stdout
|
||||||
|
pub fn print_checksum(bytes: &[u8]) {
|
||||||
|
let cs = checksum(bytes);
|
||||||
|
eprintln!(" Checksum is: {cs}");
|
||||||
|
}
|
12
src/i2c.rs
12
src/i2c.rs
|
@ -1,6 +1,5 @@
|
||||||
use i2cdev::core::*;
|
use i2cdev::core::{I2CMessage, I2CTransfer};
|
||||||
use i2cdev::linux::{LinuxI2CDevice, LinuxI2CMessage};
|
use i2cdev::linux::{LinuxI2CDevice, LinuxI2CMessage};
|
||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -29,19 +28,20 @@ pub fn read_from_bus(
|
||||||
pub fn write_to_bus(
|
pub fn write_to_bus(
|
||||||
i2c_device: &str,
|
i2c_device: &str,
|
||||||
slave_address: u16,
|
slave_address: u16,
|
||||||
|
memory_address: u8,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
let mut dev = LinuxI2CDevice::new(i2c_device, slave_address)?;
|
let mut dev = LinuxI2CDevice::new(i2c_device, slave_address)?;
|
||||||
|
|
||||||
// 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).enumerate() {
|
||||||
// Memory address
|
// Memory address
|
||||||
let memory_address: u8 = (i as u8) * 8;
|
let address = memory_address + (i as u8) * 8;
|
||||||
let mut msgs = [
|
let mut msgs = [
|
||||||
// Address to write to
|
// Address to write to
|
||||||
LinuxI2CMessage::write(&[memory_address]),
|
LinuxI2CMessage::write(&[address]),
|
||||||
// Write data to chip
|
// Write data to chip
|
||||||
LinuxI2CMessage::write(&chunk),
|
LinuxI2CMessage::write(chunk),
|
||||||
];
|
];
|
||||||
|
|
||||||
dev.transfer(&mut msgs)?;
|
dev.transfer(&mut msgs)?;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// Size of EDID binary block
|
use crate::checksum::print_checksum;
|
||||||
|
|
||||||
|
/// Size of an EDID block in bytes.
|
||||||
pub const BLOCK_SIZE: usize = 128;
|
pub const BLOCK_SIZE: usize = 128;
|
||||||
|
|
||||||
pub fn block_by_block_read(
|
pub fn block_by_block_read(
|
||||||
|
@ -10,22 +12,37 @@ pub fn block_by_block_read(
|
||||||
None => {
|
None => {
|
||||||
// Read first block (128 bytes)
|
// Read first block (128 bytes)
|
||||||
let data_base = read(0x00, BLOCK_SIZE)?;
|
let data_base = read(0x00, BLOCK_SIZE)?;
|
||||||
|
print_checksum(data_base.as_slice());
|
||||||
|
|
||||||
// Try to read remaining bytes
|
// Try to read remaining bytes
|
||||||
let data_extensions = match data_base.len() {
|
let data_extensions = match data_base.len() {
|
||||||
// Proper 128 byte block
|
// Proper first block (128 bytes)
|
||||||
BLOCK_SIZE => {
|
BLOCK_SIZE => {
|
||||||
// Number of extension blocks that should follow
|
// Number of extension blocks that should follow
|
||||||
let num_extensions: usize = data_base[BLOCK_SIZE - 2].into();
|
let num_extensions: usize = data_base[BLOCK_SIZE - 2].into();
|
||||||
// Read remaining blocks
|
// Read remaining blocks
|
||||||
read(BLOCK_SIZE as u8, num_extensions * BLOCK_SIZE)?
|
match num_extensions {
|
||||||
|
0 => vec![],
|
||||||
|
_ => read(BLOCK_SIZE as u8, num_extensions * BLOCK_SIZE)?,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Something else, obviously broken
|
// Something else, probably broken
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
};
|
};
|
||||||
|
data_extensions.chunks_exact(BLOCK_SIZE).for_each(print_checksum);
|
||||||
|
|
||||||
// Return complete byte stream
|
// Return complete byte stream
|
||||||
Ok([data_base, data_extensions].concat())
|
Ok([data_base, data_extensions].concat())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicitly read as many blocks as specified by user
|
// Explicitly read as many blocks as specified by user
|
||||||
Some(blocks) => read(0x00, blocks * BLOCK_SIZE),
|
Some(blocks) => {
|
||||||
|
// Read blocks
|
||||||
|
let data = read(0x00, blocks * BLOCK_SIZE)?;
|
||||||
|
data.chunks_exact(BLOCK_SIZE).for_each(print_checksum);
|
||||||
|
|
||||||
|
// Return complete byte stream
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod args;
|
pub mod args;
|
||||||
|
pub mod checksum;
|
||||||
pub mod i2c;
|
pub mod i2c;
|
||||||
pub mod misc;
|
pub mod io;
|
||||||
pub mod std;
|
pub mod std;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
pub fn read_from_std(data_length: usize) -> Result<Vec<u8>, std::io::Error> {
|
pub fn read_from_stdin(data_length: usize) -> Result<Vec<u8>, std::io::Error> {
|
||||||
// Buffer to read into
|
// Buffer to read into
|
||||||
let mut data = vec![0; data_length];
|
let mut data = vec![0; data_length];
|
||||||
// Read from stdin
|
// Read from stdin
|
||||||
|
@ -8,8 +8,8 @@ pub fn read_from_std(data_length: usize) -> Result<Vec<u8>, std::io::Error> {
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_to_std(data: &[u8]) -> Result<(), std::io::Error> {
|
pub fn write_to_stdout(data: &[u8]) -> Result<(), std::io::Error> {
|
||||||
// Write data to stdout
|
// Write data to stdout
|
||||||
let mut stdout = io::stdout().lock();
|
let mut stdout = io::stdout().lock();
|
||||||
stdout.write_all(&data)
|
stdout.write_all(data)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue