⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testi2c.c

📁 iic驱动测试程序
💻 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 + -