This repository has been archived by the owner on Mar 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Jan Sarenik
committed
Apr 21, 2016
0 parents
commit f1be58a
Showing
8 changed files
with
944 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/*************************************************************************** | ||
copyright : (C) by 2003-2004 Stefano Barbato | ||
email : [email protected] | ||
$Id: 24cXX.c,v 1.5 2004/02/29 11:05:28 tat Exp $ | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
#include <stdio.h> | ||
#include <fcntl.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <linux/fs.h> | ||
#include <sys/types.h> | ||
#include <sys/ioctl.h> | ||
#include <errno.h> | ||
#include <assert.h> | ||
#include <string.h> | ||
#include "24cXX.h" | ||
|
||
static int i2c_write_1b(struct eeprom *e, __u8 buf) | ||
{ | ||
int r; | ||
// we must simulate a plain I2C byte write with SMBus functions | ||
r = i2c_smbus_write_byte(e->fd, buf); | ||
if(r < 0) | ||
fprintf(stderr, "Error i2c_write_1b: %s\n", strerror(errno)); | ||
usleep(10); | ||
return r; | ||
} | ||
|
||
static int i2c_write_2b(struct eeprom *e, __u8 buf[2]) | ||
{ | ||
int r; | ||
// we must simulate a plain I2C byte write with SMBus functions | ||
r = i2c_smbus_write_byte_data(e->fd, buf[0], buf[1]); | ||
if(r < 0) | ||
fprintf(stderr, "Error i2c_write_2b: %s\n", strerror(errno)); | ||
usleep(10); | ||
return r; | ||
} | ||
|
||
static int i2c_write_3b(struct eeprom *e, __u8 buf[3]) | ||
{ | ||
int r; | ||
// we must simulate a plain I2C byte write with SMBus functions | ||
// the __u16 data field will be byte swapped by the SMBus protocol | ||
r = i2c_smbus_write_word_data(e->fd, buf[0], buf[2] << 8 | buf[1]); | ||
if(r < 0) | ||
fprintf(stderr, "Error i2c_write_3b: %s\n", strerror(errno)); | ||
usleep(10); | ||
return r; | ||
} | ||
|
||
|
||
#define CHECK_I2C_FUNC( var, label ) \ | ||
do { if(0 == (var & label)) { \ | ||
fprintf(stderr, "\nError: " \ | ||
#label " function is required. Program halted.\n\n"); \ | ||
exit(1); } \ | ||
} while(0); | ||
|
||
int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom* e) | ||
{ | ||
int funcs, fd, r; | ||
e->fd = e->addr = 0; | ||
e->dev = 0; | ||
|
||
fd = open(dev_fqn, O_RDWR); | ||
if(fd <= 0) | ||
{ | ||
fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno)); | ||
return -1; | ||
} | ||
|
||
// get funcs list | ||
if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0)) | ||
{ | ||
fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno)); | ||
return -1; | ||
} | ||
|
||
|
||
// check for req funcs | ||
CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE ); | ||
CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE ); | ||
CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE_DATA ); | ||
CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE_DATA ); | ||
CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_WORD_DATA ); | ||
CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_WORD_DATA ); | ||
|
||
// set working device | ||
if( ( r = ioctl(fd, I2C_SLAVE, addr)) < 0) | ||
{ | ||
fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno)); | ||
return -1; | ||
} | ||
e->fd = fd; | ||
e->addr = addr; | ||
e->dev = dev_fqn; | ||
e->type = type; | ||
return 0; | ||
} | ||
|
||
int eeprom_close(struct eeprom *e) | ||
{ | ||
close(e->fd); | ||
e->fd = -1; | ||
e->dev = 0; | ||
e->type = EEPROM_TYPE_UNKNOWN; | ||
return 0; | ||
} | ||
|
||
#if 0 | ||
int eeprom_24c32_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data) | ||
{ | ||
__u8 buf[3] = { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data }; | ||
return i2c_write_3b(e, buf); | ||
} | ||
|
||
|
||
int eeprom_24c32_read_current_byte(struct eeprom* e) | ||
{ | ||
ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer | ||
return i2c_smbus_read_byte(e->fd); | ||
} | ||
|
||
int eeprom_24c32_read_byte(struct eeprom* e, __u16 mem_addr) | ||
{ | ||
int r; | ||
ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer | ||
__u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff }; | ||
r = i2c_write_2b(e, buf); | ||
if (r < 0) | ||
return r; | ||
r = i2c_smbus_read_byte(e->fd); | ||
return r; | ||
} | ||
#endif | ||
|
||
|
||
int eeprom_read_current_byte(struct eeprom* e) | ||
{ | ||
ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer | ||
return i2c_smbus_read_byte(e->fd); | ||
} | ||
|
||
int eeprom_read_byte(struct eeprom* e, __u16 mem_addr) | ||
{ | ||
int r; | ||
ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer | ||
if(e->type == EEPROM_TYPE_8BIT_ADDR) | ||
{ | ||
__u8 buf = mem_addr & 0x0ff; | ||
r = i2c_write_1b(e, buf); | ||
} else if(e->type == EEPROM_TYPE_16BIT_ADDR) { | ||
__u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff }; | ||
r = i2c_write_2b(e, buf); | ||
} else { | ||
fprintf(stderr, "ERR: unknown eeprom type\n"); | ||
return -1; | ||
} | ||
if (r < 0) | ||
return r; | ||
r = i2c_smbus_read_byte(e->fd); | ||
return r; | ||
} | ||
|
||
int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data) | ||
{ | ||
if(e->type == EEPROM_TYPE_8BIT_ADDR) { | ||
__u8 buf[2] = { mem_addr & 0x00ff, data }; | ||
return i2c_write_2b(e, buf); | ||
} else if(e->type == EEPROM_TYPE_16BIT_ADDR) { | ||
__u8 buf[3] = | ||
{ (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data }; | ||
return i2c_write_3b(e, buf); | ||
} | ||
fprintf(stderr, "ERR: unknown eeprom type\n"); | ||
return -1; | ||
} | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/*************************************************************************** | ||
copyright : (C) by 2003-2004 Stefano Barbato | ||
email : [email protected] | ||
$Id: 24cXX.h,v 1.6 2004/02/29 11:05:28 tat Exp $ | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
#ifndef _24CXX_H_ | ||
#define _24CXX_H_ | ||
#include "i2c-dev.h" | ||
|
||
#define EEPROM_TYPE_UNKNOWN 0 | ||
#define EEPROM_TYPE_8BIT_ADDR 1 | ||
#define EEPROM_TYPE_16BIT_ADDR 2 | ||
|
||
struct eeprom | ||
{ | ||
char *dev; // device file i.e. /dev/i2c-N | ||
int addr; // i2c address | ||
int fd; // file descriptor | ||
int type; // eeprom type | ||
}; | ||
|
||
/* | ||
* opens the eeprom device at [dev_fqn] (i.e. /dev/i2c-N) whose address is | ||
* [addr] and set the eeprom_24c32 [e] | ||
*/ | ||
int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom*); | ||
/* | ||
* closees the eeprom device [e] | ||
*/ | ||
int eeprom_close(struct eeprom *e); | ||
/* | ||
* read and returns the eeprom byte at memory address [mem_addr] | ||
* Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) | ||
*/ | ||
int eeprom_read_byte(struct eeprom* e, __u16 mem_addr); | ||
/* | ||
* read the current byte | ||
* Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) | ||
*/ | ||
int eeprom_read_current_byte(struct eeprom *e); | ||
/* | ||
* writes [data] at memory address [mem_addr] | ||
* Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) | ||
*/ | ||
int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data); | ||
|
||
#endif | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
29.02.2004, 0.7.6 | ||
- better error handling | ||
- read_from_eeprom bug fixed, thanks to Marek Michalkiewicz | ||
02.12.2003, 0.7.5 | ||
- help switch (-h) added | ||
- 8bit addressing is now the default (safest) | ||
- 16bit mode switch added (-16) | ||
- quiet mode has been added (-q) | ||
28.11.2003, 0.7.4 | ||
- force switch added (-f) | ||
- big warning will be displayed before reading/writing, user must | ||
confirm | ||
- i2c-dev.h has been (re)included into the distribution package because | ||
user space functions have been removed from the original i2c-dev.h | ||
by the dev team. | ||
21.11.2003, 0.7.3 | ||
- ChangeLog added | ||
- WARNING file added | ||
- support for 8bit addressing EEPROMs (-8 command line switch) | ||
- better code documentation | ||
- i2c-dev.h is no more included into the dist package. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
CFLAGS=-g -I. -Wall -O2 | ||
|
||
all: eeprog | ||
|
||
clean: | ||
rm -f eeprog 24cXX.o | ||
|
||
eeprog: eeprog.o 24cXX.o | ||
|
||
eeprog-static: eeprog.o 24cXX.o | ||
$(CC) -static -o $@ $? |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Important! See the WARNING file. | ||
|
||
eeprog reads and writes 24Cxx EEPROMs connected to I2C serial bus. | ||
|
||
It uses the SMBus protocol used by most of the recent chipsets. Don't forget to load | ||
your i2c chipset and the i2c-dev drivers. | ||
|
||
Use -8 switch for EEPROM smaller then 24C16 (8bit addressing mode). | ||
|
||
Again, it's really important that you read the WARNING file. | ||
|
||
Type "make" to compile. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Writing on unknown EEPROMs can brake your computer. | ||
|
||
DIMMs contain an EEPROM and if you overwrite it somehow your computer | ||
will not boot anymore. | ||
|
||
Reading using 16bit addressing (i.e. not using the -8 switch) on a 8bit EEPROM | ||
can actually WRITE to the EEPROM. Be careful. | ||
|
||
The following chips use 8bit mode: | ||
24C01 | ||
24C02 | ||
24C04 | ||
24C08 | ||
24C16 | ||
|
||
Bigger ones use 16bit addressing so you must not use -8. | ||
|
||
More could need it, check data sheets. | ||
|
||
If you are not sure about what you're doing DON'T use this tool. |
Oops, something went wrong.