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 rwedid::args::*;
|
||||
use rwedid::i2c::*;
|
||||
use rwedid::misc::*;
|
||||
use rwedid::std::*;
|
||||
use rwedid::args::Args;
|
||||
use rwedid::i2c::read_from_bus;
|
||||
use rwedid::io::block_by_block_read;
|
||||
use rwedid::std::write_to_stdout;
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
// Parse command line arguments
|
||||
|
@ -14,5 +14,5 @@ fn main() -> Result<(), std::io::Error> {
|
|||
})?;
|
||||
|
||||
// Write binary blob to stdout
|
||||
write_to_std(&bytes)
|
||||
write_to_stdout(&bytes)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use clap::Parser;
|
||||
use rwedid::args::*;
|
||||
use rwedid::i2c::*;
|
||||
use rwedid::misc::*;
|
||||
use rwedid::std::*;
|
||||
use rwedid::args::Args;
|
||||
use rwedid::i2c::write_to_bus;
|
||||
use rwedid::io::block_by_block_read;
|
||||
use rwedid::std::read_from_stdin;
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
// Parse command line arguments
|
||||
let args = Args::parse();
|
||||
|
||||
// Read binary from stdin
|
||||
let data = block_by_block_read(args.blocks, |_, l| read_from_std(l))?;
|
||||
// Read binary blob from stdin
|
||||
let data = block_by_block_read(args.blocks, |_, l| read_from_stdin(l))?;
|
||||
|
||||
// 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 std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
|
@ -29,19 +28,20 @@ pub fn read_from_bus(
|
|||
pub fn write_to_bus(
|
||||
i2c_device: &str,
|
||||
slave_address: u16,
|
||||
memory_address: u8,
|
||||
data: &[u8],
|
||||
) -> Result<(), std::io::Error> {
|
||||
let mut dev = LinuxI2CDevice::new(i2c_device, slave_address)?;
|
||||
|
||||
// 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
|
||||
let memory_address: u8 = (i as u8) * 8;
|
||||
let address = memory_address + (i as u8) * 8;
|
||||
let mut msgs = [
|
||||
// Address to write to
|
||||
LinuxI2CMessage::write(&[memory_address]),
|
||||
LinuxI2CMessage::write(&[address]),
|
||||
// Write data to chip
|
||||
LinuxI2CMessage::write(&chunk),
|
||||
LinuxI2CMessage::write(chunk),
|
||||
];
|
||||
|
||||
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 fn block_by_block_read(
|
||||
|
@ -10,22 +12,37 @@ pub fn block_by_block_read(
|
|||
None => {
|
||||
// Read first block (128 bytes)
|
||||
let data_base = read(0x00, BLOCK_SIZE)?;
|
||||
print_checksum(data_base.as_slice());
|
||||
|
||||
// Try to read remaining bytes
|
||||
let data_extensions = match data_base.len() {
|
||||
// Proper 128 byte block
|
||||
// Proper first block (128 bytes)
|
||||
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)?
|
||||
match num_extensions {
|
||||
0 => vec![],
|
||||
_ => read(BLOCK_SIZE as u8, num_extensions * BLOCK_SIZE)?,
|
||||
}
|
||||
}
|
||||
// Something else, obviously broken
|
||||
// Something else, probably broken
|
||||
_ => vec![],
|
||||
};
|
||||
data_extensions.chunks_exact(BLOCK_SIZE).for_each(print_checksum);
|
||||
|
||||
// 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),
|
||||
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 checksum;
|
||||
pub mod i2c;
|
||||
pub mod misc;
|
||||
pub mod io;
|
||||
pub mod std;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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
|
||||
let mut data = vec![0; data_length];
|
||||
// Read from stdin
|
||||
|
@ -8,8 +8,8 @@ pub fn read_from_std(data_length: usize) -> Result<Vec<u8>, std::io::Error> {
|
|||
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
|
||||
let mut stdout = io::stdout().lock();
|
||||
stdout.write_all(&data)
|
||||
stdout.write_all(data)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue