📄 testi2c.c
字号:
//--------------------------------------------------------------------------
//Description
// use a AT24Cxx EEPROM to test i2c
//
//Copyright (C) 2006 INVENTEC(Tianjin) Co.,Ltd
//Author: xsh.han@inventec.itc
//--------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
/*
+--------------------------------------------------+
| NAME | SIZE | PAGESIZE | PAGENUM |ADDRESS|
+--------------------------------------------------+
| AT24C01 128B 8B 16 1B |
| AT24C02 256B 8B 32 1B |
| AT24C04 512B 16B 32 1B |
| AT24C08 1024B 16B 64 1B |
| AT24C16 2048B 16B 128 1B |
| AT24C32 4096B 32B 128 2B |
| AT24C64 8192B 32B 256 2B |
| AT24C128 16384B 64B 256 2B |
| AT24C256 32768B 64B 512 2B |
| AT24C512 65536B 128B 512 2B |
+--------------------------------------------------+
*/
//********************************************************************
struct st_iic_eeprominfo{
int size;
short pagesize;
short addrbytes;
}g_iic_eeprominfo[10] = {
{128, 8,1},
{256, 8,1},
{512, 16,1},
{1024, 16,1},
{2048, 16,1},
{4096, 32,2},
{8192, 32,2},
{16384, 64,2},
{32768, 64,2},
{65536,128,2},
};
struct st_iic_eeprom {
int address;
int type;
}g_iic_eeprom ={
0,
0xA0,
};
#define MAX_BUFF_SIZE 65536
unsigned char g_wrbuffer[MAX_BUFF_SIZE];
unsigned char g_rdbuffer[MAX_BUFF_SIZE];
//--------------------------------------------------------------------
//usage information
//--------------------------------------------------------------------
#define VERSION "for gladius"
void Usage(int status)
{
FILE *fp;
static char version[] = "I2C driver test program" VERSION "\n";
static char copyright[] ="copyright(c) 2006 INVENTEC(Tianjin) Co.,Ltd\n";
fp = (status == EXIT_SUCCESS) ? stdout : stderr;
fprintf(fp, version);
fprintf(fp, copyright);
fprintf(fp, "usage: testi2c [-a addr][-c types][-r][-w value][-e][-f][-h]\n");
fprintf(fp, " -a value slave address(hex,8bits)\n");
fprintf(fp, " -c types select i2c chip\n");
fprintf(fp, " 0-24c01,1-24c02,2-24c04,3-24c08,4-24c16\n");
fprintf(fp, " 5-24c32,6-24c64,7-24c128,8-24c256,9-24c512\n");
fprintf(fp, " -r addr read i2c eeprom,addr>0xffff for all\n");
fprintf(fp, " -w value write values to i2c eeprom\n");
fprintf(fp, " 0-0xFF : use value to fill\n");
fprintf(fp, " 0x100 : use 0.1.2.3... to fill\n");
fprintf(fp, " >0x100 : use random date to fill\n");
fprintf(fp, " -e clean i2c eeprom\n");
fprintf(fp, " -f write a file to eeprom\n");
fprintf(fp, " -l loop do loop test use random data\n");
fprintf(fp, " -h this helpful message\n");
exit(status);
}
//--------------------------------------------------------------------
//set device addrss
//--------------------------------------------------------------------
int set_slave_addres(int fd, u_char page)
{
//set slave address
if (ioctl(fd, I2C_SLAVE_FORCE, (g_iic_eeprom.address + (page << 1)) >> 1) < 0) {
printf("Can't set slave address\n");
return -1;
}
return 0;
}
//--------------------------------------------------------------------
//open driver & init it
//--------------------------------------------------------------------
#define NOUSE_DEVFS
int init_i2c(void)
{
int fd;
//open device file
#ifdef NOUSE_DEVFS
fd = open("/dev/i2c", O_RDWR);
if (fd < 0){
printf("i2c driver </dev/i2c> open fail\n");
return -1;
}
#else
fd = open("/dev/i2c/0", O_RDWR);
if (fd < 0){
printf("i2c driver </dev/i2c/0> open fail\n");
return -1;
}
#endif
//set slave address length, 7bit
if (ioctl(fd, I2C_TENBIT, 0) < 0) {
printf("Can't set slave address length\n");
close(fd);
return -1;
}
//set slave address
if (set_slave_addres(fd,0)!= 0) {
return -1;
}
return fd;
}
//--------------------------------------------------------------------
//read eeprom
//--------------------------------------------------------------------
int i2c_eeprom_read(int fd, int offset, u_char* buffer,int size)
{
int i=0;
int ret;
int result=0;
int tmp;
u_char wrbuff[8];
//Read from slave
printf("Read from offset:size = %04X:%04X\n",offset,size);
//write EEPROM start address
if (g_iic_eeprominfo[g_iic_eeprom.type].addrbytes==1){
wrbuff[0] = offset&0xff;
if (set_slave_addres(fd,(offset>>8))!=0) {
printf("Write slave address failed!\n");
return -1;
}
}else{ //2byte address
wrbuff[0] = (offset >> 8)&0xff;
wrbuff[1] = offset&0xff;
}
ret=write(fd, wrbuff, g_iic_eeprominfo[g_iic_eeprom.type].addrbytes);
if (ret != g_iic_eeprominfo[g_iic_eeprom.type].addrbytes) {
printf("Write offset address failed!\n");
return -1;
}
//Read from slave
i = 0;
while(i < size){
tmp = 0;
do {
i++;
tmp++;
}while(i<size && ((i+offset) % g_iic_eeprominfo[g_iic_eeprom.type].pagesize)!=0);
ret = read(fd, &buffer[i-tmp], tmp);
if (ret != tmp) {
result=-1;
break;
}
usleep(10); //must do this
}
if (result==0){
printf("read OK!\n");
}else{
printf("read FAIL at %04X!\n",(i+offset));
}
return result;
}
//--------------------------------------------------------------------
//write eeprom
//--------------------------------------------------------------------
int i2c_eeprom_write(int fd, int offset,u_char* buffer, int size)
{
int i;
int result=0;
int ret;
int tmp;
u_char wrbuff[300];
//write to slave
printf("Write from offset:size:data0 = %04X:%04X:%02X\n",offset,size,buffer[0]);
//write to eeprom
i = offset;
while(i < offset+size){
//set slave address
if (g_iic_eeprominfo[g_iic_eeprom.type].addrbytes==1){
wrbuff[0] = i&0xff;
if (set_slave_addres(fd,(i>>8))!=0) {
printf("Write slave address failed!\n");
result=-1;
break;
}
}else{ //2byte address
wrbuff[0] = (i >> 8)&0xff;
wrbuff[1] = i&0xff;
}
tmp = g_iic_eeprominfo[g_iic_eeprom.type].addrbytes;
do {
wrbuff[tmp] = buffer[i-offset];
i++;
tmp++;
}while(i<offset+size && (i % g_iic_eeprominfo[g_iic_eeprom.type].pagesize)!=0);
//write data
ret=write(fd, wrbuff,tmp);
if (ret != tmp) {
result=-1;
break;
}
usleep(10); //must do this
}
if (result==0){
printf("write OK!\n");
}else{
printf("write FAIL at %04X!\n",(i+offset));
}
return result;
}
//--------------------------------------------------------------------
//write eeprom
//--------------------------------------------------------------------
int print_it(u_char* rdbuff,int size)
{
int i;
int result=0;
printf("print data, size = %04X",size);
for (i = 0; i < size; i++){
if (i%16 ==0) {
printf("\r\n%04X:",i);
}
printf(" %02X",rdbuff[i]);
}
printf("\r\n");
return result;
}
//--------------------------------------------------------------------
//write eeprom
//--------------------------------------------------------------------
int check_it(u_char* wrbuff,u_char* rdbuff,int size)
{
int i,j;
int result=0;
printf("check eeprom, size = %04X",size);
for (i = 0; i < size; i++){
//if (i%16 ==0) {
// printf("\r\n%04X:",i);
//}
//printf(" %02X",rdbuff[i]);
if (wrbuff[i] != rdbuff[i]) {
result = -1;
break;
}
}
if (result==0) {
printf("\r\nCheck OK\r\n");
}else{
printf("\r\nCheck ERROR at %04X\r\n",i);
for(j=0; j<8 && i<size; j++,i++){
printf("addr=%04X,write=%02X,read=%02X\r\n",i,wrbuff[i],rdbuff[i]);
}
}
return result;
}
//--------------------------------------------------------------------
//fill buffer
//--------------------------------------------------------------------
int fill_data(u_char* wrbuff,int size,int data)
{
int i;
printf("fill buffer, size = %04X\r\n",size);
if (data<256) {
for (i = 0; i < size; i++){
wrbuff[i] = data;
}
return 0 ;
}
if (data==256){
for (i = 0; i < size; i++){
wrbuff[i] = i&0xFF;
}
return 0;
}
if (data>256){
for (i = 0; i < size; i++){
wrbuff[i] = rand()&0xff;
}
return 0;
}
return 0;
}
//--------------------------------------------------------------------
//write a file to chip,return size;
//--------------------------------------------------------------------
int fill_file(const char * filename)
{
int fd;
int result=0;
fd = open(filename, O_RDONLY);
if(fd < 0){
printf("Open file %s failed!",filename);
return -1;
}
result = read(fd, g_wrbuffer, MAX_BUFF_SIZE);
close(fd);
return result;
}
//--------------------------------------------------------------------
// do loop test
//--------------------------------------------------------------------
int loop_test(int loop)
{
int i;
int fd;
int ret=0;
fd = init_i2c();
if (!(fd > 0)) return -1;
for(i=0; i<loop; i++) {
printf("------------------\r\n");
printf("loop test %d/%d\r\n",i+1,loop);
printf("------------------\r\n");
fill_data(g_wrbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size,rand()+0x100);
i2c_eeprom_write(fd,0,g_wrbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
i2c_eeprom_read(fd,0,g_rdbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
ret = check_it(g_wrbuffer,g_rdbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
if (ret!=0) {
break;
}
}
close(fd);
printf("------------------\r\n");
if (ret==0) {
printf("LoopTest All OK!\r\n");
}else{
printf("LoopTest ERROR at %d\r\n",i);
}
printf("------------------\r\n");
return ret;
}
//--------------------------------------------------------------------
//main function
//--------------------------------------------------------------------
int main(int argc, char **argv)
{
int opt;
int data;
int size;
int fd;
struct timeval t_start;
struct timezone tz;
gettimeofday(&t_start, &tz);
srand(t_start.tv_usec);
//main loop process
while((opt = getopt(argc,argv,"a:c:r:w:ef:l:h")) != -1){
switch(opt){
case 'a'://set i2c eeprom slave address
data = strtol(optarg,NULL,16);
g_iic_eeprom.address = data&0xFF;
break;
case 'c'://set i2c eeprom type
data = atoi(optarg);
g_iic_eeprom.type = data%10;
break;
case 'r'://read i2c eeprom
data = strtol(optarg,NULL,16);
fd = init_i2c();
if (!(fd > 0)) return -1;
if (data>0xFFFF) {
i2c_eeprom_read(fd,0,g_rdbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
print_it(g_rdbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
}else{
i2c_eeprom_read(fd,data,g_rdbuffer,256);
print_it(g_rdbuffer,256);
}
close(fd);
break;
case 'w'://write eeprom
data = strtol(optarg,NULL,16);
fd = init_i2c();
if (!(fd > 0)) return -1;
fill_data(g_wrbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size,data);
i2c_eeprom_write(fd,0,g_wrbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
i2c_eeprom_read(fd,0,g_rdbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
check_it(g_wrbuffer,g_rdbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
close(fd);
break;
case 'e'://clean eeprom
fd = init_i2c();
if (!(fd > 0)) return -1;
fill_data(g_wrbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size,0xFF);
i2c_eeprom_write(fd,0,g_wrbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
i2c_eeprom_read(fd,0,g_rdbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
check_it(g_wrbuffer,g_rdbuffer,g_iic_eeprominfo[g_iic_eeprom.type].size);
close(fd);
break;
case 'f'://write a file
fd = init_i2c();
if (!(fd > 0)) return -1;
size = fill_file(optarg);
if (size>0) {
i2c_eeprom_write(fd,0,g_rdbuffer,size);
check_it(g_wrbuffer,g_rdbuffer,size);
};
close(fd);
break;
case 'l'://loop test
data = atoi(optarg);
loop_test(data);
break;
case 'h':
default:
Usage(EXIT_SUCCESS);
break;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -