use i2c::{BulkTransfer, Message};
use std::error::Error;
const EEPROM_ADDR: u16 = 0x50;
const BLOCK_SIZE: usize = 16;
fn main() -> Result<(), Box<dyn Error>> {
let bytes_to_read = match std::env::args().nth(1) {
Some(val) => val.parse::<u16>()?,
None => return Err("Missing argument".into()),
};
let mut bus = i2c_tiny_usb::I2c::open_single_device()?;
let mut offset: u16 = 0;
while offset < bytes_to_read {
let mut read_buf = [0u8; BLOCK_SIZE];
let addr_bytes16 = offset.to_be_bytes();
let addr_bytes = if addr_bytes16[0] == 0 {
&addr_bytes16[1..]
} else {
&addr_bytes16
};
bus.i2c_transfer(&mut [
Message::Write {
address: EEPROM_ADDR,
data: addr_bytes,
flags: Default::default(),
},
Message::Read {
address: EEPROM_ADDR,
data: &mut read_buf,
flags: Default::default(),
},
])?;
print_hexdump_line(offset as u32, &read_buf);
offset += BLOCK_SIZE as u16;
}
Ok(())
}
fn print_hexdump_line(base_offset: u32, data: &[u8]) {
assert!(data.len() == BLOCK_SIZE);
print!("{:04x} ", base_offset);
for (i, byte) in data.iter().enumerate() {
if i == 8 {
print!(" ");
}
print!("{:02x} ", byte);
}
print!(" |");
for byte in data.iter() {
let c = if byte.is_ascii_graphic() || *byte == b' ' {
*byte as char
} else {
'.'
};
print!("{}", c);
}
println!("|");
}