應用程式層讀寫i2c裝置可讀寫8位,16位裝置地址小工具及源碼

來源:互聯網
上載者:User


#include "standard_i2c.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#if 0
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#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 <8/16> <dev> <reg> [value]\n", pname);
 return 0;
}

/* read ./iis 16 0x24 0x0111 */
/* write ./iis 16 0x24 0x0111 0x3 */

int main(int argc, char *argv[])
{
 unsigned char i2c_dev;
 unsigned int  i2c_reg;
 unsigned char value[4];
 unsigned int  readvalue;
 unsigned char reg_bit;
 int i;
 if(argc < 3)
 {
  usage(argv[0]);
  exit(1);
 }
 
 reg_bit=strtoll(argv[1], NULL, 0);
 i2c_dev=strtoll(argv[2], NULL, 0);
 i2c_reg=strtoll(argv[3], NULL, 0);

 printf("reg_bit %d \n",reg_bit);

 if(argc == 4)
 {
  if(16 == reg_bit){
   read_16bit_i2c(0, i2c_dev,i2c_reg, &value[0]);
  }else{
   read_8bit_i2c(0, i2c_dev,i2c_reg, &value[0], 1);
  }

  printf("read reg 0x%x value: 0x%x \n",i2c_reg,value[0]);
 }
 else if(argc == 5)
 {
  value[0]=strtoll(argv[4], NULL, 0);

  if(16 == reg_bit){
   write_16bit_i2c(0, i2c_dev,i2c_reg, &value[0]);
  }else{
   write_8bit_i2c(0, i2c_dev,i2c_reg, &value[0], 1);
  }
  printf("write reg 0x%x value: 0x%x \n",i2c_reg,value[0]);
 }
 
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.