5.1MINI2440 i2c驱动学习

 

MINI2440i2c驱动学习一

int main(int argc, chr** argv)
{
 struct eeprom e;
 fprintf(stderr, "Open /dev/i2c/0 with 8bit mode\n");
 die_if(eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e) < 0,
   "unable to open eeprom device file "
   "(check that the file exists and that it's readable)");
   
   
  fprintf(stderr, "  Reading 256 bytes from 0x0\n");
  read_from_eeprom(&e, 0, 256); 
  
   
   
  
  
 eeprom_close(&e);

 return 0;
}

eeprom_open()函数中设置了打开i2c

int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom* e)
{
 int funcs, fd, r;
 e->fd = e->addr = 0;
 e->dev = 0;
 
 fd = open(dev_fqn, O_RDWR);
 if(fd <= 0)
 {
  fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));
  return -1;
 }

 // get funcs list
 if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0))
 {
  fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));
  return -1;
 }

 
 // check for req funcs
 CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE );
 CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE );
 CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE_DATA );
 CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE_DATA );
 CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_WORD_DATA );
 CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_WORD_DATA );

 // set working device
 if( ( r = ioctl(fd, I2C_SLAVE, addr)) < 0)
 {
  fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));
  return -1;
 }
 e->fd = fd;
 e->addr = addr;
 e->dev = dev_fqn;
 e->type = type;
 return 0;
}

关键函数是fd = open(dev_fqn, O_RDWR);
函数到这里就打开了设备,现在就是要读写E2prom

fprintf(stderr, "  Reading 256 bytes from 0x0\n");
read_from_eeprom(&e, 0, 512);



int eeprom_read_byte(struct eeprom* e, __u16 mem_addr)
{
 int r;
 ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
 if(e->type == EEPROM_TYPE_8BIT_ADDR)
 {
  __u8 buf =  mem_addr & 0x0ff;
  r = i2c_write_1b(e, buf);
 } else if(e->type == EEPROM_TYPE_16BIT_ADDR) {
  __u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };
  r = i2c_write_2b(e, buf);
 } else {
  fprintf(stderr, "ERR: unknown eeprom type\n");
  return -1;
 }
 if (r < 0)
  return r;
 r = i2c_smbus_read_byte(e->fd);
 return r;
}

i2c_write_1b()这个函数是在总线上写要读的地址

static int i2c_write_1b(struct eeprom *e, __u8 buf)
{
 int r;
 // we must simulate a plain I2C byte write with SMBus functions
 r = i2c_smbus_write_byte(e->fd, buf);
 if(r < 0)
  fprintf(stderr, "Error i2c_write_1b: %s\n", strerror(errno));
 usleep(10);
 return r;
}

i2c_smbus_read_byte(e->fd);
这个函数是在读这个地址上的值

static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
{
 union i2c_smbus_data data;
 if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
                      I2C_SMBUS_BYTE_DATA,&data))
  return -1;
 else
  return 0x0FF & data.byte;
}

static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
                                     int size, union i2c_smbus_data *data)
{
 struct i2c_smbus_ioctl_data args;

 args.read_write = read_write;
 args.command = command;
 args.size = size;
 args.data = data;
 return ioctl(file,I2C_SMBUS,&args);
}

到这个就完成了读eeprom指定地址上的值

接下来就是换写函数(已被)

write_to_eeprom()

static int write_to_eeprom(struct eeprom *e, int addr)
{
 int i;
 for(i=0, addr=0; i<256;addr++)
 {
  if( (i % 16) == 0 )
   printf("\n %.4x|  ", addr);
  else if( (i % 8) == 0 )
   printf("  ");
  printf("%.2x ", i);
  fflush(stdout);
  die_if(eeprom_write_byte(e, addr, i), "write error");
 }
 fprintf(stderr, "\n\n");
 return 0;
}

这里主要看eeprom_write_byte(e, addr, i),

int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data)
{
 if(e->type == EEPROM_TYPE_8BIT_ADDR) {
  __u8 buf[2] = { mem_addr & 0x00ff, data };
  return i2c_write_2b(e, buf);
 } else if(e->type == EEPROM_TYPE_16BIT_ADDR) {
  __u8 buf[3] =
   { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };
  return i2c_write_3b(e, buf);
 }
 fprintf(stderr, "ERR: unknown eeprom type\n");
 return -1;
}

static int i2c_write_2b(struct eeprom *e, __u8 buf[2])
{
 int r;
 // we must simulate a plain I2C byte write with SMBus functions
 r = i2c_smbus_write_byte_data(e->fd, buf[0], buf[1]);
 if(r < 0)
  fprintf(stderr, "Error i2c_write_2b: %s\n", strerror(errno));
 usleep(10);
 return r;
}

static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)
{
 union i2c_smbus_data data;
 data.byte = value;
 return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
                         I2C_SMBUS_BYTE_DATA, &data);
}

到这里就完成了写

先到这里,后来在看底层驱动

 

原文链接不详,侵删

上一篇:02 Spark架构与运行流程


下一篇:dos命令记录以及dos下通过进程id查找工作路径