[RK3399][Android7.1]应用笔记 - I2C应用

平台 内核版本 安卓版本
RK3399 Linux4.4 Android7.1

节点权限确认

RK平台支持的I2C节点位于/dev下:

ll /dev/i2c*

应用访问I2C节点

我们以I2c0为例:

#define I2C_FILE_NAME "/dev/i2c-0"

i2c应用最本质的操作就是对通过i2c接口对外设模块进行寄存器的操作:

应用程序通过i2c_rdwr_ioctl_data结构体来给内核传递消息,结构体定义如下:

struct i2c_rdwr_ioctl_data {

       struct i2c_msg __user *msgs; /* pointers to i2c_msgs */

       __u32 nmsgs; /* number of i2c_msgs */

};

static int get_i2c_register(int file, unsigned short addr, 
                            unsigned char reg, 
                            unsigned char *val, 
                            int len) {

	unsigned char outbuf;
	struct i2c_rdwr_ioctl_data packets;
	struct i2c_msg messages[2];

    /*     
    * In order to read a register, we first do a "dummy write" by writing     
    * * 0 bytes to the register we want to read from.  This is similar to     
    * * the packet in set_i2c_register, except it's 1 byte rather than 2.    
    * */ 
	outbuf = reg;
	messages[0].addr  = addr;
	messages[0].flags = 0;
	messages[0].len   = sizeof(outbuf);
	messages[0].buf   = &outbuf;
	
    /* The data will get returned in this structure */
    messages[1].addr  = addr;    
    messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;    
    messages[1].len   = len;    
    messages[1].buf   = val;

    /* Send the request to the kernel and get the result back */    
    packets.msgs      = messages;    
    packets.nmsgs     = 2;    
    if(ioctl(file, I2C_RDWR, &packets) < 0) {        
        perror("Unable to send data");        
        return 1;    
    }
}

static int set_i2c_register(int file, unsigned char addr,
                            unsigned char reg,                            
                            unsigned char *value,    
                            int len) {
      unsigned char *outbuf = (unsigned char *)malloc(sizeof(unsigned char)*(len+1));
      if(outbuf==NULL) { 
          perror("MALLOC"); 
          return -1; 
      }
      struct i2c_rdwr_ioctl_data packets;
      struct i2c_msg messages[1];
      messages[0].addr  = addr;    
      messages[0].flags = 0;    
      messages[0].len   = len+1;    
      messages[0].buf   = outbuf;
      
      /* The first byte indicates which register we'll write */    
      outbuf[0] = reg;
      /*      
       * The second byte indicates the value to write.  Note that for many     
       * * devices, we can write multiple, sequential registers at once by     
       * * simply making outbuf bigger.     
       * */ 
      memcpy(outbuf+1, value, len);
      /* Transfer the i2c packets to the kernel and verify it worked */ 
      packets.msgs  = messages;    
      packets.nmsgs = 1;    
      if(ioctl(file, I2C_RDWR, &packets) < 0) {        
          perror("Unable to send data");        
          return 1;    
      }
    return 0; 
}
发布了295 篇原创文章 · 获赞 99 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/qq_33487044/article/details/104747844