Files
lm-sensors/prog/eepromer/eepromer.c
T
Kyosti Malkki 1cfe63804a (Kyösti) Cleanups
Copy sysctl enums to chip drivers from sensors.h for now,
   as seen in drivers included in 2.5 tree. File no longer included
   from kernel side.

   Apply i2c-proc change in CVS tagged -km2.

   Partial clean and sort of includes everywhere.

   Add i2c-dev.h, as a partial copy from i2c.
   Add to sensors.h from i2c-proc.h to compile things.
   Remove i2c-isa.h.

   Reflect header file changes to lib/ and prog/.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@1705 7894878c-1315-0410-8ee3-d5d059ff63e0
2003-01-21 20:01:27 +00:00

746 lines
14 KiB
C

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include "i2c-dev.h"
#define MAX_BLK_SIZE 64
#define EEPROM_SIZE 32768
#define READ 1
#define WRITE 0
#define ERASE 2
#define PHEADER 3
#define VER "eepromer v 0.4 (c) Daniel Smolik 2001\n"
#define HEAD_SIZE sizeof(struct mini_inode)
#define START_ADDR 0
#define FORCE 1
/*
To disable startup warning #undef WARNINC
*/
#define WARNINC
int block_write(int file,int dev_addr,int eeprom_addr,unsigned char *buf,int lenght);int block_write(int file,int dev_addr,int eeprom_addr,unsigned char *buf,int lenght);
int block_read(int file,int dev_addr,int eeprom_addr,unsigned char *buf);
/* block_read read block 64 bytes length and returns actual length of data*/
void help(void);
int init(char *device,int addr);
int content_write(int file, int addr);
int content_read(int file, int addr);
void pheader(int file, int addr);
void erase(int file,int addr,int eeprom_size);
void made_address(int addr,unsigned char *buf);
void warn(void);
void bar(void);
static int stav=0;
static struct mini_inode {
time_t timestamp;
int data_len;
char data[56];
} m_ind,*p_ind;
void help(void)
{
FILE *fptr;
char s[100];
fprintf(stderr,"Syntax: eepromer [-r|-w|-e|-p] -f /dev/i2c-X ADDRESS \n\n");
fprintf(stderr," ADDRESS is address of i2c device eg. 0x51\n");
if((fptr = fopen("/proc/bus/i2c", "r"))) {
fprintf(stderr," Installed I2C busses:\n");
while(fgets(s, 100, fptr))
fprintf(stderr, " %s", s);
fclose(fptr);
}
}
int main(int argc, char *argv[]){
int i,j,res,i2cbus,address,size,file;
long funcs;
struct i2c_msg *msgs,msg[2];
int nmsgs,addr;
char *pbuf;
int action; //in this variable will be (-r,-w,-e)
char device[45];
int force;
struct i2c_ioctl_rdwr_data {
struct i2c_msg *msgs; /* ptr to array of simple messages */
int nmsgs; /* number of messages to exchange */
} msgst,*pmsgst;
p_ind=&m_ind;
force=0;
for(i=1; i < argc;i++){
if(!strcmp("-r",argv[i])) {
action=READ;
break;
}
if(!strcmp("-e",argv[i])) {
action=ERASE;
break;
}
if(!strcmp("-w",argv[i])) {
action=WRITE;
break;
}
if(!strcmp("-p",argv[i])) {
action=PHEADER;
break;
}
if(!strcmp("-force",argv[i])) {
force=FORCE;
break;
}
if(!strcmp("-v",argv[i])) {
fprintf(stderr,VER);
exit(0);
break;
}
else {
fprintf(stderr,"Error: No action specified !\n");
help();
exit(1);
}
}
#ifdef WARNINC
if(force!=FORCE) warn();
#endif
if(argc < 5) {
fprintf(stderr,"Error: No i2c address specified !\n");
help();
exit(1);
}
for(i=1; i < argc;i++){
if(!strcmp("-f",argv[i])) {
strcpy(device,argv[i+1]);
break;
}
}
if(!strlen(device)) {
fprintf(stderr,"Error: No device specified !\n");
help();
exit(1);
}
if(! (addr=strtol(argv[4],NULL,16))) {
fprintf(stderr,"Error: Bad device address !\n");
help();
exit(1);
}
if(! (file=init(device,addr))){
fprintf(stderr,"Error: Init failed !\n");
exit(1);
}
switch(action){
case READ:
content_read(file,addr);
break;
case WRITE:
content_write(file,addr);
break;
case ERASE: erase(file,addr,EEPROM_SIZE);
break;
case PHEADER: pheader(file,addr);
break;
default:
fprintf(stderr,"Internal error!\n");
exit(1); break;
}
close(file);
exit(0);
}
/****************************************************************************/
/* Low level function */
/* */
/****************************************************************************/
int block_write(int file,int dev_addr,int eeprom_addr,unsigned char *buf,int lenght){
unsigned char buff[2];
struct i2c_msg msg[2];
char *pbuff;
int j;
struct i2c_ioctl_rdwr_data {
struct i2c_msg *msgs; /* ptr to array of simple messages */
int nmsgs; /* number of messages to exchange */
} msgst;
if ( lenght > (MAX_BLK_SIZE) ) {
fprintf(stderr,
"Error: Block too large:\n");
}
//bar();
made_address(eeprom_addr,buff);
msg[0].addr = dev_addr;
msg[0].flags = 0;
msg[0].len = 2;
msg[0].buf = buff;
msg[1].addr = dev_addr;
msg[1].flags = I2C_M_NOSTART;
msg[1].len = lenght;
msg[1].buf = buf;
msgst.msgs = msg;
msgst.nmsgs = 2;
if (ioctl(file,I2C_RDWR,&msgst) < 0){
fprintf(stderr,
"Error: Transaction failed: %s\n",
strerror(errno));
return 1;
}
return 0;
}
int block_read(int file,int dev_addr,int eeprom_addr,unsigned char *buf){
int ln,i,j;
char buff[2]; //={0x0,0x0};
char pom;
struct i2c_msg msg[2];
struct i2c_ioctl_rdwr_data {
struct i2c_msg *msgs; /* ptr to array of simple messages */
int nmsgs; /* number of messages to exchange */
} msgst;
made_address(eeprom_addr,buff);
ln=0;
//bar();
msg[0].addr = dev_addr;
msg[0].flags = 0;
msg[0].len = 2;
msg[0].buf = buff;
msg[1].addr = dev_addr;
msg[1].flags = I2C_M_RD;
msg[1].len = MAX_BLK_SIZE;
msg[1].buf = buf;
msgst.msgs = msg;
msgst.nmsgs = 2;
if (ln=ioctl(file,I2C_RDWR,&msgst) < 0){
fprintf(stderr,
"Error: Read error:%d\n",ln);
return ln;
}
return ln;
}
void made_address(int addr,unsigned char *buf){
int i,j,k;
char a;
//addr = addr & 0xFFFF; /*odstranim nepoterbne bity*/
k=addr;
buf[1]=(unsigned char) (k & 0xFF); //vyrobim druhy byte adresy
k=addr & 0xFF00 ;
buf[0]= ((unsigned char) (k >> 8)) & 0x7F;
return;
}
int init(char *device,int addr) {
int file;
long funcs;
if ((file = open(device,O_RDWR)) < 0) {
fprintf(stderr,"Error: Could not open file %s\n",
device);
return 0;
}
/* check adapter functionality */
if (ioctl(file,I2C_FUNCS,&funcs) < 0) {
fprintf(stderr,
"Error: Could not get the adapter functionality matrix: %s\n",
strerror(errno));
close(file);
return 0;
}
/* The I2C address */
if (ioctl(file,I2C_SLAVE,addr) < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */
fprintf(stderr,
"Error: Cannot communicate with slave: %s\n",
strerror(errno));
close(file);
return 0;
}
return file;
}
int content_write(int file, int addr){
unsigned char buf[MAX_BLK_SIZE];
unsigned char pom;
int dat,i,j,k,delka,addr_cnt ;
delka=0;
addr_cnt=HEAD_SIZE;
k=0;
for(j=0;j<=MAX_BLK_SIZE;j++)buf[j]=0;
i=0;
for(;;) {
delka=fread(&pom,1,1,stdin);
if( delka > 0 ){
buf[i]=pom;
}
if(i==(MAX_BLK_SIZE-1) || (delka < 1)) {
if(block_write(file,addr,addr_cnt,buf,delka<1?i:(i+1)) !=0) {
fprintf(stderr,"Block write failed\n");
return 1;
}
//printf("i:%d\n",i);
addr_cnt=addr_cnt + i + (delka==1?1:0); //+i
for(j=0;j<=MAX_BLK_SIZE;j++)buf[j]=0;
i=0;
if(delka<1) {
//pisu EOF
if(inode_write(file,addr,(addr_cnt-HEAD_SIZE)) !=0) {
fprintf(stderr,"Inode write failed\n");
return 1;
}
break;
}
} else i++;
}
return;
}
int content_read(int file, int addr){
unsigned char buf[MAX_BLK_SIZE];
unsigned char pom;
int dat,i,j,k,delka,addr_cnt ;
delka=0;
k=0;
inode_read(file,addr,p_ind );
for(i=HEAD_SIZE;i<= (HEAD_SIZE + p_ind->data_len);i=i+MAX_BLK_SIZE ) {
if(block_read(file,addr,i,buf) !=0) {
fprintf(stderr,"Block read failed\n");
return 1;
}
if( (HEAD_SIZE + p_ind->data_len - i) < MAX_BLK_SIZE ) {
k= HEAD_SIZE + p_ind->data_len - i;
}else {
k=MAX_BLK_SIZE;
}
for(j=0;j<k ;j++){
putc(buf[j],stdout);
}
}
return;
}
void erase(int file, int addr,int eeprom_size){
unsigned char buf[MAX_BLK_SIZE];
unsigned char pom;
int dat,i,j,k,delka,addr_cnt ;
delka=0;
k=0;
for(j=0;j<=MAX_BLK_SIZE;j++)buf[j]=0;
for(i=0;i<eeprom_size;i=i+MAX_BLK_SIZE) {
if(block_write(file,addr,i,buf,MAX_BLK_SIZE) !=0) {
fprintf(stderr,"Block write failed\n");
return;
}
}
return;
}
void bar(void){
if( stav > 70 ) stav=0;
switch(stav) {
case 10: fwrite("\\",1,1,stderr);
fflush(stderr);
rewind(stderr);
break;
case 20: fwrite("|",1,1,stderr);
fflush(stderr);
rewind(stderr);
break;
case 30: fwrite("/",1,1,stderr);
fflush(stderr);
rewind(stderr);
break;
case 40: fwrite("-",1,1,stderr);
fflush(stderr);
rewind(stderr);
break;
case 50: fwrite("\\",1,1,stderr);
fflush(stderr);
rewind(stderr);
break;
case 60: fwrite("|",1,1,stderr);
fflush(stderr);
rewind(stderr);
break;
case 70: fwrite("/",1,1,stderr);
fflush(stderr);
rewind(stderr);
break;
default:
}
stav++;
}
int inode_write(int file,int dev_addr,int lenght){
unsigned char buff[2];
struct i2c_msg msg[2];
char *pbuff;
int j;
struct i2c_ioctl_rdwr_data {
struct i2c_msg *msgs; /* ptr to array of simple messages */
int nmsgs; /* number of messages to exchange */
} msgst;
m_ind.timestamp=time(NULL);
m_ind.data_len=lenght;
//bar();
made_address(START_ADDR,buff);
msg[0].addr = dev_addr;
msg[0].flags = 0;
msg[0].len = 2;
msg[0].buf = buff;
msg[1].addr = dev_addr;
msg[1].flags = I2C_M_NOSTART;
msg[1].len = sizeof(struct mini_inode);
msg[1].buf = (char *) &m_ind;
msgst.msgs = msg;
msgst.nmsgs = 2;
if (ioctl(file,I2C_RDWR,&msgst) < 0){
fprintf(stderr,
"Error: Transaction failed: %s\n",
strerror(errno));
return 1;
}
return 0;
}
int inode_read(int file,int dev_addr,void *p_inode ){
#define POK 32
int ln,i;
char buff[2]; //={0x0,0x0};
char pom;
struct i2c_msg msg[2];
struct i2c_ioctl_rdwr_data {
struct i2c_msg *msgs; /* ptr to array of simple messages */
int nmsgs; /* number of messages to exchange */
} msgst;
made_address(START_ADDR,buff);
ln=0;
//bar();
msg[0].addr = dev_addr;
msg[0].flags = 0;
msg[0].len = 2;
msg[0].buf = buff;
msg[1].addr = dev_addr;
msg[1].flags = I2C_M_RD;
msg[1].len = sizeof(struct mini_inode);
msg[1].buf = p_inode;
msgst.msgs = msg;
msgst.nmsgs = 2;
if (ln=ioctl(file,I2C_RDWR,&msgst) < 0){
fprintf(stderr,
"Error: Read error:%d\n",ln);
return ln;
}
return ln;
}
void pheader(int file,int dev_addr){
struct tm *p_tm;
char time_buf[15],*p_buf;
p_buf=time_buf;
inode_read(file,dev_addr,p_ind );
p_tm=localtime(&p_ind->timestamp);
strftime(p_buf,sizeof(time_buf),"%Y%m%d%H%M%S",p_tm);
printf("LEN=%d,TIME=%s\n",p_ind->data_len,p_buf);
return;
}
#ifdef WARNINC
void warn(void)
{
fprintf(stderr,"\n\n!!!!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!!!\n");
fprintf(stderr,"This program is intended for use on eeproms\nusing external busses such as i2c-pport.\n");
fprintf(stderr,"Do not use this on your SDRAM DIMM EEPROMS\nunless you REALLY REALLY know what you are\ndoing!!! Doing so will render your SDRAM\nUSELESS and leave your system UNBOOTABLE!!!\n");
fprintf(stderr,"To disable this warning use -force\n");
fprintf(stderr,"\n\nPress ENTER to continue or hit Control-C NOW !!!!\n\n\n");
getchar();
}
#endif