#include "standard_i2c.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if 0
#include
#include
#else
#define I2C_M_WT 0x0000 /* write data, from master to slave */
#define I2C_M_RD 0x0001 /* read data, from slave to master */
#define I2C_ADDR (0x48>>1)
#define I2C_ADDR_16BIT 1 // 1:16bit i2c_addr 0:8bit i2c_addr
#define I2C_RETRIES 0x0701 /*设置收不到ACK时的重试次数 */
#define I2C_TIMEOUT 0x0702 /* 设置超时时限的jiffies */
#define I2C_SLAVE 0x0703 /*设置从机地址 */
#define I2C_SLAVE_FORCE 0x0706 /* 强制设置从机地址 */
#define I2C_TENBIT 0x0704 /*选择地址位长:=0 for 7bit , != 0 for 10 bit */
#define I2C_FUNCS 0x0705 /*获取适配器支持的功能 */
#define I2C_RDWR 0x0707 /*Combined R/W transfer (one STOP only) */
#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */
#define I2C_SMBUS 0x0720 /*SMBus transfer */
#define I2C_SMBUS_BYTE_DATA 2
#define I2C_SMBUS_READ 1
#define I2C_SMBUS_WRITE 0
#define I2C_SMBUS_BLOCK_DATA 5
#define I2C_SMBUS_I2C_BLOCK_DATA 8
#define I2C_SLAVE_FORCE 0x0706
#define I2C_SMBUS_BLOCK_MAX 32
// exact-width types
typedef char s8;
typedef short s16;
typedef int s32;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef float f32;
typedef double f64;
union i2c_smbus_data {
unsigned char byte;
unsigned short word;
unsigned char block[I2C_SMBUS_BLOCK_MAX + 2];
};
struct i2c_smbus_ioctl_data {
char read_write;
unsigned char command;
int size;
union i2c_smbus_data *data;
};
struct i2c_msg {
u16 addr; /* slave address */
u16 flags;
u16 len; /* msg length */
u8 *buf; /* pointer to msg data */
} ;
/* In ./include/linux/i2c-dev.h */
struct i2c_rdwr_ioctl_data {
/* pointers to i2c_msgs */
struct i2c_msg *msgs;
/* number of i2c_msgs */
u32 nmsgs;
};
#endif
int Standard_i2c_open(int index)
{
char dev_name[32];
sprintf(dev_name, "/dev/i2c-%d", index);
return open(dev_name, O_RDWR);
}
#if I2C_ADDR_16BIT
int write_16bit_i2c(int bus_index, u8 device_addr/*8bits*/, u32 register_addr, unsigned char *pBuffer)
{
struct i2c_rdwr_ioctl_data e2prom_data;
int i2c_dev_fd = -1;
char reg_buf[3]={0,0,0};
int ret;
/**/
i2c_dev_fd = Standard_i2c_open(bus_index);
if(i2c_dev_fd < 0)
{
printf("standard_i2c_read Standard_i2c_open Failed\n");
goto _OVER_;
}
ioctl(i2c_dev_fd,I2C_TIMEOUT,1);/*超时时间*/
ioctl(i2c_dev_fd,I2C_RETRIES,2);/*重复次数*/
e2prom_data.nmsgs=1;
e2prom_data.msgs=(struct i2c_msg*)malloc(e2prom_data.nmsgs*sizeof(struct i2c_msg));
if(!e2prom_data.msgs)
{
perror("malloc error");
goto _OVER_;
}
reg_buf[0] = (register_addr >> 8) & 0xFF; //e2prom数据地址 16bit
reg_buf[1] = register_addr & 0xFF ; //e2prom数据地址
reg_buf[2] = pBuffer[0] ; //写一个数据
(e2prom_data.msgs[0]).len=3; //
(e2prom_data.msgs[0]).addr=I2C_ADDR; // e2prom 设备地址
(e2prom_data.msgs[0]).flags=I2C_M_WT; //write
(e2prom_data.msgs[0]).buf = reg_buf;
ret=ioctl(i2c_dev_fd,I2C_RDWR,(unsigned long)&e2prom_data);
if(ret<0)
{
perror("ioctl error2");
goto _OVER_;
}
printf("** %x ** \n",pBuffer[0]);
_OVER_:
if(i2c_dev_fd >= 0)
{
close(i2c_dev_fd);
}
if(e2prom_data.msgs != NULL)
{
free(e2prom_data.msgs);
}
}
int read_16bit_i2c(int bus_index, u8 device_addr/*8bits*/, u32 register_addr, unsigned char *pBuffer)
{
struct i2c_rdwr_ioctl_data e2prom_data;
int i2c_dev_fd = -1;
char reg_buf[2]={0,0},buf[2]={0,0};
int ret;
/**/
i2c_dev_fd = Standard_i2c_open(bus_index);
if(i2c_dev_fd < 0)
{
printf("standard_i2c_read Standard_i2c_open Failed\n");
goto _OVER_;
}
ioctl(i2c_dev_fd,I2C_TIMEOUT,1);/*超时时间*/
ioctl(i2c_dev_fd,I2C_RETRIES,2);/*重复次数*/
e2prom_data.nmsgs=2;
e2prom_data.msgs=(struct i2c_msg*)malloc(e2prom_data.nmsgs*sizeof(struct i2c_msg));
if(!e2prom_data.msgs)
{
perror("malloc error");
goto _OVER_;
}
reg_buf[0] = (register_addr >> 8) & 0xFF; //e2prom数据地址 16bit
reg_buf[1] = register_addr & 0xFF ; //e2prom数据地址
e2prom_data.nmsgs=2;
(e2prom_data.msgs[0]).len=2; //e2prom 要写的字节数
(e2prom_data.msgs[0]).addr=I2C_ADDR; // e2prom 设备地址
(e2prom_data.msgs[0]).flags=I2C_M_WT; //write
(e2prom_data.msgs[0]).buf = reg_buf;
(e2prom_data.msgs[1]).len=1; //读出的数据个数
(e2prom_data.msgs[1]).addr=I2C_ADDR; // e2prom 设备地址
(e2prom_data.msgs[1]).flags=I2C_M_RD;//read
(e2prom_data.msgs[1]).buf=buf;
ret=ioctl(i2c_dev_fd,I2C_RDWR,(unsigned long)&e2prom_data);
if(ret<0)
{
perror("ioctl error2");
goto _OVER_;
}
printf("***0x%x***\n",(e2prom_data.msgs[1]).buf[0]);
pBuffer[0] = (e2prom_data.msgs[1]).buf[0];
_OVER_:
if(i2c_dev_fd >= 0)
{
close(i2c_dev_fd);
}
if(e2prom_data.msgs != NULL)
{
free(e2prom_data.msgs);
}
}
#else
int read_8bit_i2c(int bus_index, unsigned char device_addr/*8bits*/, unsigned char register_addr, unsigned char *pBuffer, int byte_number)
{
struct i2c_smbus_ioctl_data ioctl_data;
union i2c_smbus_data smbus_data;
int ret_val = -1;
int i2c_dev_fd = -1;
int index = 0;
/**/
if(byte_number >= I2C_SMBUS_BLOCK_MAX)
{
printf("standard_i2c_read Invalid parameter(%d >= %d)\n", byte_number, I2C_SMBUS_BLOCK_MAX);
return -1;
}
/**/
i2c_dev_fd = Standard_i2c_open(index);
if(i2c_dev_fd < 0)
{
printf("standard_i2c_read Standard_i2c_open Failed\n");
goto _OVER_;
}
/*set address*/
ioctl(i2c_dev_fd, I2C_TENBIT, 0);
if(ioctl(i2c_dev_fd, I2C_SLAVE_FORCE, (device_addr >> 1) & 0x7f) < 0)
{
perror("i2c ioctl:");
printf("standard_i2c_read ioctl(I2C_SLAVE) Failed\n");
goto _OVER_;
}
/**/
smbus_data.block[0] = byte_number;
ioctl_data.read_write = I2C_SMBUS_READ;
ioctl_data.command = register_addr;
ioctl_data.size = I2C_SMBUS_I2C_BLOCK_DATA;
ioctl_data.data = &smbus_data;
if(ioctl(i2c_dev_fd, I2C_SMBUS, &ioctl_data) != 0)
{
printf("standard_i2c_read ioctl(I2C_SMBUS) Failed(%d)\n", index);
goto _OVER_;
}
if(smbus_data.block[0] != byte_number)
{
printf("standard_i2c_read ioctl read Failed(%d)(%d)\n", smbus_data.block[0], byte_number);
goto _OVER_;
}
for(index = 0; index < byte_number; index ++)
{
pBuffer[index] = smbus_data.block[index + 1];
}
ret_val = 0;
_OVER_:
if(i2c_dev_fd >= 0)
{
close(i2c_dev_fd);
}
return ret_val;
}
int write_8bit_i2c(int bus_index, unsigned char device_addr/*8bits*/, unsigned char register_addr, unsigned char *pBuffer, int byte_number)
{
struct i2c_smbus_ioctl_data ioctl_data;
union i2c_smbus_data smbus_data;
int ret_val = -1;
int i2c_dev_fd = -1;
int index = 0;
/**/
if(byte_number >= I2C_SMBUS_BLOCK_MAX)
{
printf("standard_i2c_write ioctl Invalid parameter(%d)\n", byte_number);
return -1;
}
i2c_dev_fd = Standard_i2c_open(bus_index);
if(i2c_dev_fd < 0)
{
printf("standard_i2c_write Standard_i2c_open Failed\n");
goto _OVER_;
}
/*set address*/
ioctl(i2c_dev_fd, I2C_TENBIT, 0);
if(ioctl(i2c_dev_fd, I2C_SLAVE_FORCE, (device_addr >> 1) & 0x7f) < 0)
{
perror("i2c ioctl:");
printf("standard_i2c_write ioctl(I2C_SLAVE) Failed\n");
goto _OVER_;
}
/**/
smbus_data.block[0] = byte_number;
for(index = 0; index < byte_number; index ++)
{
smbus_data.block[index + 1] = pBuffer[index];
}
/**/
ioctl_data.read_write = I2C_SMBUS_WRITE;
ioctl_data.command = register_addr;
ioctl_data.size = I2C_SMBUS_I2C_BLOCK_DATA;
ioctl_data.data = &smbus_data;
/**/
if(ioctl(i2c_dev_fd, I2C_SMBUS, &ioctl_data) != 0)
{
printf("standard_i2c_write ioctl(I2C_SMBUS) Failed(%d)\n", index);
goto _OVER_;
}
ret_val = 0;
_OVER_:
if(i2c_dev_fd >= 0)
{
close(i2c_dev_fd);
}
return ret_val;
}
#endif
int usage(char *pname)
{
printf("%s
return 0;
}
int main(int argc, char *argv[])
{
unsigned char i2c_dev;
unsigned int i2c_reg;
unsigned char value[4];
unsigned int readvalue;
int i;
if(argc < 3)
{
usage(argv[0]);
exit(1);
}
i2c_dev=strtoll(argv[1], NULL, 0);
i2c_reg=strtoll(argv[2], NULL, 0);
if(argc == 3)
{
#ifdef I2C_ADDR_16BIT
read_16bit_i2c(0, i2c_dev,i2c_reg, &value[0]);
#else
read_8bit_i2c(0, i2c_dev,i2c_reg, &value[0], 1);
#endif
printf("read reg 0x%x value: 0x%x \n",i2c_reg,value[0]);
}
else if(argc == 4)
{
value[0]=strtoll(argv[3], NULL, 0);
#ifdef I2C_ADDR_16BIT
write_16bit_i2c(0, i2c_dev,i2c_reg, &value[0]);
#else
write_8bit_i2c(0, i2c_dev,i2c_reg, &value[0], 1);
#endif
printf("write reg 0x%x value: 0x%x \n",i2c_reg,value[0]);
}
}