6 releases
Uses new Rust 2024
| 0.3.3 | Nov 22, 2025 |
|---|---|
| 0.3.2 | Jun 17, 2025 |
| 0.2.0 | Jun 13, 2025 |
| 0.1.0 | Jun 8, 2025 |
#266 in Embedded development
75KB
1.5K
SLoC
ehatrom — library for working with Raspberry Pi HAT EEPROM
ehatrom is a Rust library for reading, writing, and generating EEPROM content for Raspberry Pi HAT (Hardware Attached on Top) via I2C. It supports correct serialization/deserialization of the structure, working with atoms (VendorInfo, GPIO Map, DTBlob, custom), reading/writing with 2-byte offset and page write, and convenient content output.
Features
- Read and write Raspberry Pi HAT EEPROM via I2C (with page write and 2-byte offset support)
- Serialization and parsing of EEPROM structure according to the official Raspberry Pi HAT specification
- Convenient content output, including string fields
- CLI example for reading/writing/dumping EEPROM
- Support for custom atoms and CRC32 integrity check
- Large EEPROM support with configurable buffer size via
EHATROM_BUFFER_SIZEenvironment variable - Page-based reading implementation (32 bytes per read) for better compatibility with real EEPROM chips
Structures
EepromHeader— EEPROM headerAtomHeader— atom headerVendorInfoAtom— vendor and product infoGpioMapAtom— GPIO map (28 pins per bank)DtBlobAtom— device tree blobEeprom— full EEPROM structure
Why 28 pins in GpioMapAtom?
28 pins correspond to GPIO0–GPIO27 of the standard 40-pin Raspberry Pi header. This is exactly the number of user GPIOs available on regular models. For extended boards (Compute Module), a second atom (GpioMapBank1) can be added.
Usage Example
use ehatrom::{Eeprom, VendorInfoAtom, GpioMapAtom};
// Create VendorInfoAtom
let vendor_info = VendorInfoAtom::new(
0x1234, // vendor_id
0x5678, // product_id
1, // product_ver
"MyVendor", // vendor (any string length)
"MyHAT", // product (any string length)
[0u8; 16], // uuid
);
// Fill GPIO map: all unused (0), GPIO4 — input (0x01), GPIO17 — output (0x02)
let mut pins = [0u8; 28];
pins[4] = 0x01; // GPIO4 — input
pins[17] = 0x02; // GPIO17 — output
let gpio_map = GpioMapAtom { flags: 0, pins };
let mut eeprom = Eeprom {
header: Default::default(),
vendor_info,
gpio_map_bank0: gpio_map,
dt_blob: None,
gpio_map_bank1: None,
custom_atoms: Vec::new(),
};
eeprom.update_header();
// Serialization to bytes
let bytes = eeprom.serialize();
// Serialization with CRC32
let bytes_with_crc = eeprom.serialize_with_crc();
// Write to EEPROM via I2C
// ehatrom::write_to_eeprom_i2c(&bytes_with_crc, "/dev/i2c-1", 0x50)?;
// Read from EEPROM with CRC check
// let mut buf = vec![0u8; 256];
// ehatrom::read_from_eeprom_i2c(&mut buf, "/dev/i2c-1", 0x50, 0)?;
// if Eeprom::verify_crc(&buf) {
// let eeprom = Eeprom::from_bytes(&buf[..buf.len()-4])?;
// println!("{:?}", eeprom);
// } else {
// println!("CRC check failed!");
// }
// Add a custom atom (e.g., with settings or serial number)
let custom_data = b"serial:1234567890".to_vec();
eeprom.add_custom_atom(0x80, custom_data);
// Add a custom atom with settings (e.g., API address)
let api_url = b"api_url:https://api.example.com/v1".to_vec();
eeprom.add_custom_atom(0x80, api_url);
let api_key = b"api_key:SECRET123456".to_vec();
eeprom.add_custom_atom(0x81, api_key);
Setting EEPROM Version
By default, the version is set to 1. To set a custom version (for example, 2):
let mut eeprom = Eeprom { header: Default::default(), /* ... */ };
eeprom.set_version(2); // set version to 2
Or, using the builder pattern:
let mut eeprom = Eeprom { header: Default::default(), /* ... */ };
// ... fill other fields ...
eeprom.set_version(3); // set version to 3
pins field format
Each byte of the pins array defines the function of the corresponding GPIO:
- 0x00 — unused
- 0x01 — input
- 0x02 — output
- ... (see HAT EEPROM specification)
Platform Support
- The core library (EEPROM structures, serialization, CRC, etc.) is cross-platform and works on any OS (Linux, macOS, Windows, etc.).
- I2C EEPROM read/write functions (
write_to_eeprom_i2c,read_from_eeprom_i2c) are available only on Linux (using the i2cdev crate). - The I2C reading implementation uses page-based reading (32 bytes per read operation) for better compatibility with real EEPROM chips that don't support reading large blocks at once.
- Buffer size for I2C operations is configurable via the
EHATROM_BUFFER_SIZEenvironment variable (default is 32KB, but can be set to any value up to several megabytes). - On other platforms, you can use all parsing/serialization features, but direct I2C access is not available.
Dependencies
See also: update_and_run.md for usage automation.
Command-line interface (CLI)
A full-featured CLI is available starting from version 0.3.0:
Usage: ehatrom <read|write|show|detect> [options]
Commands:
read [i2c-dev] <output.bin> Read EEPROM via I2C and save to file
write [i2c-dev] <input.bin> Write EEPROM from file to I2C device
show <input.bin> Show parsed EEPROM info from file (debug format)
detect [i2c-dev] Auto-detect HAT EEPROM on specific device (default: /dev/i2c-0)
detect --all Scan all available I2C devices for HAT EEPROM
Examples:
# Read EEPROM to file (uses default /dev/i2c-0 and address 0x50)
sudo ehatrom read dump.bin
# Read EEPROM from specific I2C device
sudo ehatrom read /dev/i2c-1 dump.bin
# Read large EEPROM with custom buffer size (default is 32KB)
EHATROM_BUFFER_SIZE=1048576 sudo ehatrom read large_eeprom.bin # 1MB buffer
# Write EEPROM from file (uses default /dev/i2c-0 and address 0x50)
sudo ehatrom write dump.bin
# Write EEPROM to specific I2C device
sudo ehatrom write /dev/i2c-1 dump.bin
# Show EEPROM info (debug format)
./ehatrom show dump.bin
# Auto-detect HAT EEPROM and show info
sudo ehatrom detect # Uses /dev/i2c-0 by default (HAT EEPROM standard)
sudo ehatrom detect /dev/i2c-1 # Use specific I2C bus if needed
sudo ehatrom detect --all # Scan all I2C devices automatically
Advanced Detection Features
The detect --all command automatically finds all available I2C devices in /dev (like /dev/i2c-0, /dev/i2c-1, etc.) and scans each one for HAT EEPROM. This is especially useful when you're not sure which I2C bus your HAT is connected to:
# Scan all I2C devices - shows which devices are available and which contain HAT EEPROM
sudo ehatrom detect --all
# Use a larger buffer for detecting EEPROMs larger than 32KB
EHATROM_BUFFER_SIZE=1048576 sudo ehatrom detect # 1MB buffer
- All errors and usage info are printed to stderr.
- Requires root for I2C access on Linux.
Links
License
MIT
Dependencies
~0–295KB