Created
August 17, 2020 13:44
-
-
Save gquere/d532ffaa62e3a23753afd4f0080e4df0 to your computer and use it in GitHub Desktop.
dump I2C EEPROM memory from Linux device ioctl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <fcntl.h> | |
#include <linux/i2c-dev.h> | |
#define READ_SIZE (256) | |
#define NB_PAGES (256) | |
/* UTILS **********************************************************************/ | |
void hexprint(const uint8_t *input, const int input_length) | |
{ | |
int i = 0; | |
for (i = 0; i < input_length; i++) { | |
if (i%16 == 0) { | |
printf("\n"); | |
} | |
printf("%02x ", input[i]); | |
} | |
printf("\n"); | |
} | |
void dump_to_file(const char *output_file_path, | |
const uint8_t *buffer, const int buffer_length) | |
{ | |
int output_file = open(output_file_path, O_RDWR|O_APPEND|O_CREAT); | |
if (output_file < 0) { | |
printf("Failed opening output file %s\n", output_file_path); | |
return; | |
} | |
write(output_file, buffer, buffer_length); | |
} | |
/* MAIN ***********************************************************************/ | |
int main(int argc, char *argv[]) | |
{ | |
/* got these values from i2cdetect */ | |
const char *i2c_device = "/dev/i2c-2"; | |
const int device_address = 0x50; | |
/* open the i2c device file */ | |
int file = open(i2c_device, O_RDWR); | |
if (file < 0) { | |
printf("Failed opening %s\n", i2c_device); | |
return 1; | |
} | |
if (ioctl(file, I2C_SLAVE, device_address) < 0) { | |
printf("Failed addressing device at %02X\n", device_address); | |
close(file); | |
return 1; | |
} | |
int i = 0; | |
for (i = 0; i < NB_PAGES; i++) { | |
char buf[READ_SIZE] = {0}; | |
if (read(file, buf, READ_SIZE) != READ_SIZE) { | |
printf("Failed reading\n"); | |
close(file); | |
return 1; | |
} | |
//hexprint(buf, READ_SIZE); | |
dump_to_file(argv[1], buf, READ_SIZE); | |
} | |
close(file); | |
return 0; | |
} |
Check my fork.. it's even easier.. all that is missing is a simple write:
write(file,'\x00\x00',2); // ADDRESS
before the read cycle.
25c256 have 16 bit HI then LO, as address.
Smaller eeproms have only 8 so the write must be one byte only.
note: when writing back instead, you must write the address (2 bytes) followed by the data (32bytes maximum), and wait at least 3ms between the writes.
here is the full backup and restore program which now includes also the "aknowledge polling" (before I had just an ugly usleep function).
https://gist.github.com/Zibri/cf8ac0b311301aeeaa8910c7da824bff
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
not a problem.. I rewrote the program yesterday to dump and restore a 24c256 very easily and without most of i2c stuff.
I will soon publish it and if you like I will give you the link.
any way to READ a 24c256 you need first to write 2 BYTES, ADDRHI and ADDRLO, then just by using read() you can read it all 256 byte at a time.
to write it is trickier.. you need to write 34 bytes (or less) at a time where the first 2 are the address.
but you have to wait 2-3ms between the writes.
all codes present on github/staroverflow do not work! at least not on an lg tv which has an old linux kernel.
but in this way it works and I correctly dumped and restored the 24c256 eeprom.