#include #include #include #include #include #include #include #include #include #include #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); int inode_write(int file, int dev_addr, int lenght); int inode_read(int file, int dev_addr, void *p_inode); 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, file, addr; int action; //in this variable will be (-r,-w,-e) char device[45]; int force; 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]; 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; char buff[2]; //={0x0,0x0}; 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 k; //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; unsigned 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 i, j, k, delka, addr_cnt; delka=0; addr_cnt=HEAD_SIZE; k=0; for(j=0;j 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;jdata_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 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; } stav++; } int inode_write(int file,int dev_addr,int lenght){ unsigned char buff[2]; 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; 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; char buff[2]; //={0x0,0x0}; 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