I2C调试小结

文章首发:http://user.qzone.qq.com/276546441/blog/1303712793


1、硬件部分

I2C物理组成上,只有两根线,一根时钟线,一根数据线,线的具体位置原理图都为标注的,找ISCLISDA管脚即可。I2C的时钟线不像一般总线的时钟,时刻都存在,只有当总线上有数据发送时,才会产生时钟信号;数据线在没有数据传送时,一直为高电平,故如果发送数据时发现返回总线忙的错误,原因一般为数据线上电平被拉低了。

调试I2C信号时,示波器需要设置为触发式,如果需要查看发送数据是否正确,最好用两个探头同时测时钟与数据信号,这样可以方便看出捕获的数据值。


2、软件部分

硬件了解清楚,便需要注意软件部分了。软件部分分为驱动程序与应用程序。接下来我们分别描述。


2.1 驱动程序

由于操作系统的存在,应用软件和硬件打交道需要通过驱动来进行。笔者使用的设备都基于Linux系统,故本文描述内容基于Linux系统。

驱动部分需要了解两个方面内容:I2C设备体系结构和I2C协议含义。

驱动一般分为总线驱动与设备驱动。由于Linux内核是开源的,所有有人都可以定制内核来适应自己的硬件系统来使用。所以一般情况下,我们要写的设备的总线驱动最新内核中都会包含的,有兴趣的可以通过阅读内核代码来了解其工作原理。

设备驱动只需按总线驱动的要求构造数据结构,实现操作函数注册设备即可。代码结构可以参考已有的驱动代码(附录中提供了一种简单协议的I2C驱动代码,有兴趣可以参考一下),复用已有框架代码,实现自己的设备对应的协议便可以。

I2C直观来说只是通信通道,芯片需要设置寄存器数据时,可以自定义通信协议,应用程序按照协议规定组织好数据发给I2C总线即可。协议制定时,不同芯片的协议有可能不同,常见的协议是 | I2C地址 寄存器地址 节数据 |,这些协议在芯片手册中都会有明确说明。比如某款镜头的协议如下图:

图表 1 I2C写时序


        图表 1为该镜头的写操作协议(时序),由图可知,该镜头在I2C体系中的地址是0xBA(说白了也就是协议头),设备地址为了区分读写操作,一个字节中的前七位为设备地址,当最后一位是0时为写操作,值是1时为读操作,紧跟着的一个字节是寄存器地址0x09,然后是写入寄存器的两字节值0000 0010 1000 0100,所以在写这镜头寄存器时给I2C总线发送的数据为0xBA 0x09 0x02 0x84,发送完后,镜头解析完命令便把地址为0x09寄存器的值设置为0x0284

图表 2I2C读时序

图表 2为该镜头的读操作协议(时序),进行读操作之前需要先写入要读的寄存器地址,这便是0xBA 0x09的作用,然后直接读操作,0xBB便是对0xBA地址的I2C设备进行读操作,读出两字节内容,便是0x09对应的寄存器值。

而另一款镜头的协议则有些复杂。见下图。

图表 3:写时序

这个协议的制定格式为设备地址 | 44字节数据 |44字节数据的协议有明确的说明文档,只要按照文档说明组织内容即可达到自己想要的操作。


2.2 应用程序

应用程序主要通过驱动的IOCONTRL接口操作I2C,按手册提供的协议说明发送命令即可,可以参考附录中应用程序部分代码。

    3 附录

	3.1 简单I2C协议驱动代码
	
	#include <dev_i2c.h>
	#include <linux/config.h>
	#include <linux/module.h>
	#include <linux/init.h>
	#include <linux/fs.h>           /* everything... */
	#include <linux/cdev.h>
	#include <linux/mm.h>
	#include <linux/i2c.h>
	#include <linux/kernel.h>       /* printk() */
	#include <linux/slab.h>         /* kmalloc() */
	#include <asm/uaccess.h>        /* copy_*_user */
	
	
	static unsigned short gI2C_curAddr;
	
	typedef struct {
	
	  int devAddr;
	
	  struct i2c_client client;   //!< Data structure containing general access routines.
	  struct i2c_driver driver;   //!< Data structure containing information specific to each client.
	  
	  char name[20];
	  int nameSize;
	  int users;
	  
	} I2C_Obj;
	
	typedef struct {
	
	  struct cdev cdev;             /* Char device structure    */
	  int     major;
	  struct semaphore semLock;
	    
	  I2C_Obj *pObj[I2C_DEV_MAX_ADDR];
	
	  uint8_t reg[I2C_TRANSFER_BUF_SIZE_MAX];
	  uint8_t buffer[I2C_TRANSFER_BUF_SIZE_MAX*4];
	  
	} I2C_Dev;
	
	I2C_Dev gI2C_dev;
	
	int I2C_detectClient(struct i2c_adapter *adapter, int address)
	{
	    I2C_Obj *pObj;
	    struct i2c_client *client;
	    int err = 0;
	    
	    #ifdef I2C_DEBUG
	    printk(KERN_INFO "I2C: I2C_detectClient() at address %x ...\n", address);
	    #endif
	        
	    if(address > I2C_DEV_MAX_ADDR) {
	      printk( KERN_ERR "I2C: ERROR: Invalid device address %x\n", address);        
	      return -1;
	    }
	      
	    pObj = gI2C_dev.pObj[address];
	    if(pObj==NULL) {
	      printk( KERN_ERR "I2C: ERROR: Object not found for address %x\n", address);    
	      return -1;
	    }
	
	    client = &pObj->client;
	
	    if(client->adapter)
	      return -EBUSY;  /* our client is already attached */
	
	    memset(client, 0x00, sizeof(struct i2c_client));
	    client->addr = pObj->devAddr;
	    client->adapter = adapter;
	    client->driver = &pObj->driver;
	
	    #ifdef I2C_DEBUG
	    printk(KERN_INFO "I2C: i2c_attach_client() ...\n");
	    #endif
	
	    if((err = i2c_attach_client(client)))
	    {
	        printk( KERN_ERR "I2C: ERROR: Couldn't attach %s (address=%x)\n", pObj->name, pObj->devAddr);
	        client->adapter = NULL;
	        return err;
	    }
	    
	    #ifdef I2C_DEBUG
	    printk( KERN_INFO "I2C: %s client registered at address %x !\n", pObj->name, pObj->devAddr );
	    #endif
	
	    return 0;
	}
	
	int I2C_detachClient(struct i2c_client *client)
	{
	    int err;
	
	    if(!client->adapter)
	        return -ENODEV; /* our client isn't attached */
	
	    if((err = i2c_detach_client(client))) {
	        printk( KERN_ERR "Client deregistration failed (address=%x), client not detached.\n", client->addr);
	        return err;
	    }
	
	    client->adapter = NULL;
	
	    return 0;
	}
	
	int I2C_attachAdapter(struct i2c_adapter *adapter)
	{
	    #ifdef I2C_DEBUG
	    printk(KERN_INFO "I2C: I2C_attachAdapter() ...\n");
	    #endif
	    
	    return I2C_detectClient(adapter, gI2C_curAddr);
	}
	
	void *I2C_create(int devAddr) {
	
	    int ret;
	    struct i2c_driver *driver;
	    struct i2c_client *client = client;
	    
	    I2C_Obj *pObj;
	
	    #ifdef I2C_DEBUG
	    printk(KERN_INFO "I2C: Driver registration in progress for address %x...\n", devAddr);
	    #endif
	    
	    devAddr >>= 1;
	    
	    if(devAddr>I2C_DEV_MAX_ADDR)
	      return NULL;
	   
	    if(gI2C_dev.pObj[devAddr]!=NULL) {
	      // already allocated, increment user count, and return the allocated handle
	      
	      gI2C_dev.pObj[devAddr]->users++;
	      
	      return gI2C_dev.pObj[devAddr];
	    }
	    
	    pObj = (void*)kmalloc( sizeof(I2C_Obj), GFP_KERNEL);
	
	    gI2C_dev.pObj[devAddr] = pObj;
	
	    memset(pObj, 0, sizeof(I2C_Obj));
	  
	    pObj->client.adapter = NULL;
	    pObj->users++;
	    
	    pObj->devAddr = devAddr;
	    
	    gI2C_curAddr = pObj->devAddr;
	    
	    driver = &pObj->driver;
	
	    pObj->nameSize=0;
	    pObj->name[pObj->nameSize++] = 'I';
	    pObj->name[pObj->nameSize++] = '2';
	    pObj->name[pObj->nameSize++] = 'C';
	    pObj->name[pObj->nameSize++] = '_';   
	    pObj->name[pObj->nameSize++] = 'A' + ((pObj->devAddr >> 0) & 0xF);
	    pObj->name[pObj->nameSize++] = 'B' + ((pObj->devAddr >> 4) & 0xF);
	    pObj->name[pObj->nameSize++] = 0;
	
	    driver->driver.name = pObj->name;
	    driver->id = I2C_DRIVERID_MISC;
	    driver->attach_adapter = I2C_attachAdapter;
	    driver->detach_client = I2C_detachClient;
	
	    #ifdef I2C_DEBUG
	    printk(KERN_INFO "I2C: i2c_add_driver() ...\n");
	    #endif
	
	    if((ret = i2c_add_driver(driver)))
	    {
	        printk( KERN_ERR "I2C: ERROR: Driver registration failed (address=%x), module not inserted.\n", pObj->devAddr);
	    }
	    
	    #ifdef I2C_DEBUG
	    printk(KERN_INFO "I2C: Driver registration successful (address=%x)\n", pObj->devAddr);
	    #endif
	    
	    if(ret<0) {
	
	      gI2C_dev.pObj[pObj->devAddr] = NULL;
	    
	      kfree(pObj);    
	
	      return NULL;
	    }
	    
	    return pObj;
	}
	
	int I2C_delete(I2C_Obj *pObj)
	{
	  if(pObj==NULL)
	    return -1;
	  
	  pObj->users--;
	  
	  if(pObj->users<=0) {
	    if(pObj->client.adapter!=NULL) {
	      if(i2c_del_driver(&pObj->driver))
	      printk(KERN_ERR "I2C: ERROR: Driver remove failed (address=%x), module not removed.\n", pObj->devAddr);
	
	      pObj->client.adapter = NULL;
	
	      gI2C_dev.pObj[pObj->devAddr] = NULL;
	    
	      kfree(pObj);    
	    }
	  }
	
	  return 0;
	}
	
	int I2C_read(I2C_Obj *pObj, uint8_t *reg, uint8_t *buffer, uint8_t count, uint8_t dataSize)
	{
	  uint8_t i;
	  int err;
	  struct i2c_client *client;
		struct i2c_msg msg[1];
		unsigned char data[1];
	
	  if(pObj==NULL)
	    return -ENODEV;
	
	  client = &pObj->client;
	  if(!client->adapter)
	    return -ENODEV;  
	
	  if(dataSize<=0||dataSize>4)
	    return -1;
	    
	  for(i=0; i<count; i++) {
			msg->addr  = client->addr;
			msg->flags = 0;
			msg->len   = 1;
			msg->buf   = data;
			data[0]    = reg[i];
			err = i2c_transfer(client->adapter, msg, 1);
			if(err<0) {
			  printk( KERN_ERR " i2c_transfer(0x%x, %x)\n", msg->addr, msg->buf[0]);
			}
	
			if (err >= 0) 
			{
				msg->flags = I2C_M_RD;
	      msg->len   = dataSize;
				err = i2c_transfer(client->adapter, msg, 1);
				if (err >= 0) 
				{
				  if(dataSize==1) {
	  				buffer[i] = data[0];
	  		  } else 
	  		  if(dataSize==2) {
	  		    buffer[2*i]   = data[1];
	  		    buffer[2*i+1] = data[0];  		    
	  		  }
				}
			}
	    if (err<0)
	      return -ENODEV;
	  }
	  
	  return 0;
	}
	
	int I2C_write(I2C_Obj *pObj, uint8_t *reg, uint8_t *buffer, uint8_t count, uint8_t dataSize)
	{
	  uint8_t i;
	  int err;
	  struct i2c_client *client;
		struct i2c_msg msg[1];
		unsigned char data[8];
	
	  if(pObj==NULL)
	    return -ENODEV;
	
	  client = &pObj->client;
	  if(!client->adapter)
	    return -ENODEV;  
	  
	  if(dataSize<=0||dataSize>4)
	    return -1;
	    
	  for(i=0; i<count; i++) {
	  
	    msg->addr = client->addr;
			msg->flags= 0;
			msg->buf  = data;
			
			data[0] = reg[i];
			
			if(dataSize==1) {
	  		data[1]  = buffer[i];
	  		msg->len = 2;  		
	    }	else	
			if(dataSize==2) {
	  		data[1] = buffer[2*i+1];
	  		data[2] = buffer[2*i];
	  		msg->len = 3;
			} 
			err = i2c_transfer(client->adapter, msg, 1);
	    if( err < 0 )
	      return err;
	  }
	  
	  return 0;
	}
	
	int I2C_devOpen(struct inode *inode, struct file *filp)
	{
	  int minor, major;
	
	  minor = iminor(inode);
	  major = imajor(inode);
	
	#ifdef I2C_DEBUG
	  printk(KERN_INFO "I2C: I2C_devOpen()   , %4d, %2d \n", major, minor);
	#endif
	
	  filp->private_data = NULL;
	
	  return 0;                /* success */
	}
	
	int I2C_devRelease(struct inode *inode, struct file *filp)
	{
	  I2C_Obj *pObj;
	
	  pObj = (I2C_Obj *)filp->private_data;
	  
	  if(pObj==NULL)
	    return 0;
	
	#ifdef I2C_DEBUG
	  printk(KERN_INFO "I2C: I2C_devRelease(), %x, %d \n", pObj->devAddr, pObj->users);
	#endif
	
	  I2C_delete(pObj);
	
	  return 0;
	}
	
	int I2C_devIoctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
	{
	  I2C_Obj *pObj;
	  int status=0;
	  I2C_TransferPrm transferPrm;
	  
	  pObj = (I2C_Obj *)filp->private_data;
	
	#ifdef I2C_DEBUG
	  printk(KERN_INFO "I2C: I2C_devIoctl() \n");
	#endif
	
	  if(!I2C_IOCTL_CMD_IS_VALID(cmd))
	    return -1;
	
	  cmd = I2C_IOCTL_CMD_GET(cmd);
	
	  down_interruptible(&gI2C_dev.semLock);      
	  
	  switch(cmd)
	  {
	    case I2C_CMD_SET_DEV_ADDR:
	      filp->private_data = I2C_create(arg);
	      if(filp->private_data==NULL)
	        status = -1;
	      break;
	      
	    case I2C_CMD_WRITE:
	      
	      status = copy_from_user(&transferPrm, (void *)arg, sizeof(transferPrm));
	      if(status==0) {
	        status = copy_from_user(gI2C_dev.reg, transferPrm.reg, transferPrm.count);  
	        status |= copy_from_user(gI2C_dev.buffer, transferPrm.value, transferPrm.count*transferPrm.dataSize);  
	        if(status==0) {
	          status = I2C_write(pObj, gI2C_dev.reg, gI2C_dev.buffer, transferPrm.count, transferPrm.dataSize);
	        }
	      }
	            
	      break;
	    case I2C_CMD_READ:  
	    
	      status = copy_from_user(&transferPrm, (void *)arg, sizeof(transferPrm));
	      if(status==0) {
	        status = copy_from_user(gI2C_dev.reg, transferPrm.reg, transferPrm.count);        
	        if(status==0) {
	          status = I2C_read(pObj, gI2C_dev.reg, gI2C_dev.buffer, transferPrm.count, transferPrm.dataSize);
	          if(status==0) {
	            status = copy_to_user(transferPrm.value, gI2C_dev.buffer, transferPrm.count*transferPrm.dataSize);
	          }
	        }
	      }
	      
	      break;
	    default:
	      status = -1;
	      break;    
	  }
	
	  up(&gI2C_dev.semLock);      
	
	  return status;
	}
	
	
	struct file_operations gI2C_devFileOps = {
	  .owner = THIS_MODULE,
	  .open = I2C_devOpen,
	  .release = I2C_devRelease,
	  .ioctl = I2C_devIoctl,
	};
	
	int I2C_devInit(void)
	{
	  int     result, i;
	  dev_t   dev = 0;
	
	#ifdef I2C_DEBUG
	  printk(KERN_INFO "I2C: I2C_devInit() \n");
	#endif
	
	  result = alloc_chrdev_region(&dev, 0, 1, I2C_DRV_NAME);
	
	  if (result < 0) {
	    printk(KERN_WARNING "I2C: can't get device major num \n");
	    return result;
	  }
	  
	  for(i=0; i<I2C_DEV_MAX_ADDR; i++)
	  {
	    gI2C_dev.pObj[i]=NULL;
	  }
	
	  gI2C_dev.major = MAJOR(dev);
	  
	  sema_init(&gI2C_dev.semLock, 1);
	
	  cdev_init(&gI2C_dev.cdev, &gI2C_devFileOps);
	
	  gI2C_dev.cdev.owner = THIS_MODULE;
	  gI2C_dev.cdev.ops = &gI2C_devFileOps;
	
	  result = cdev_add(&gI2C_dev.cdev, dev, 1);
	
	  if (result)
	    printk(KERN_WARNING "I2C: Error [%d] while adding device [%s] \n", result, I2C_DRV_NAME);
	
	  printk(KERN_INFO "I2C: Module install successful, device major num = %d \n", gI2C_dev.major);
	
	  return result;
	}
	
	void I2C_devExit(void)
	{
	  dev_t   devno = MKDEV(gI2C_dev.major, 0);
	
	#ifdef I2C_DEBUG
	  printk(KERN_INFO "I2C: I2C_devExit() \n");
	#endif
	
	  cdev_del(&gI2C_dev.cdev);
	
	  unregister_chrdev_region(devno, 1);
	}
	
	3.2 应用程序
	
	
	#include <drv_i2c.h>
	#include <dev_i2c.h>
	#include <sys/ioctl.h>
	#include <fcntl.h>
	#include <unistd.h>
	
	int DRV_i2cOpen(DRV_I2cHndl *hndl, Uint8 devAddr)
	{
	  char deviceName[20];
	  Uint32 cmd;
	  int status;
	
	  sprintf(deviceName, "/dev/%s", I2C_DRV_NAME);
	
	  hndl->fd = open(deviceName, O_RDWR);
	  if(hndl->fd<0)
	    return OSA_EFAIL;
	  
	  cmd = I2C_IOCTL_CMD_MAKE(I2C_CMD_SET_DEV_ADDR);
	  status = ioctl(hndl->fd, cmd, devAddr);
	  
	  if(status<0)
	    close(hndl->fd);
	    
	  return status;
	}
	
	int DRV_i2cRead8(DRV_I2cHndl *hndl, Uint8 *reg, Uint8 *value, Uint8 count)
	{
	  I2C_TransferPrm prm;
	  Uint32 cmd;
	  int status;
	  
	  prm.dataSize = 1;
	  prm.reg = reg;
	  prm.count = count;
	  prm.value = value;
	  
	  cmd = I2C_IOCTL_CMD_MAKE(I2C_CMD_READ);
	  status = ioctl(hndl->fd, cmd, &prm);
	
	  return status;  
	}
	
	int DRV_i2cWrite8(DRV_I2cHndl *hndl, Uint8 *reg, Uint8 *value, Uint8 count)
	{
	  I2C_TransferPrm prm;
	  Uint32 cmd;
	  int status;
	   
	  prm.dataSize = 1;   
	  prm.reg = reg;
	  prm.count = count;
	  prm.value = value;
	  
	  cmd = I2C_IOCTL_CMD_MAKE(I2C_CMD_WRITE);
	  status = ioctl(hndl->fd, cmd, &prm);
	  
	  return status;  
	}
	
	int DRV_i2cRead16(DRV_I2cHndl *hndl, Uint8 *reg, Uint16 *value, Uint8 count)
	{
	  I2C_TransferPrm prm;
	  Uint32 cmd;
	  int status;
	  
	  prm.dataSize = 2;
	  prm.reg = reg;
	  prm.count = count;
	  prm.value = value;
	  
	  cmd = I2C_IOCTL_CMD_MAKE(I2C_CMD_READ);
	  status = ioctl(hndl->fd, cmd, &prm);
	
	  return status;  
	}
	
	int DRV_i2cWrite16(DRV_I2cHndl *hndl, Uint8 *reg, Uint16 *value, Uint8 count)
	{
	  I2C_TransferPrm prm;
	  Uint32 cmd;
	  int status;
	   
	  prm.dataSize = 2;   
	  prm.reg = reg;
	  prm.count = count;
	  prm.value = value;
	  
	  cmd = I2C_IOCTL_CMD_MAKE(I2C_CMD_WRITE);
	  status = ioctl(hndl->fd, cmd, &prm);
	  
	  return status;  
	}
	
	int DRV_i2cClose(DRV_I2cHndl *hndl)
	{
	  return close(hndl->fd);
	}
	
	int DRV_i2cTestShowUsage(char *str)
	{
	  OSA_printf(" \n");
	  OSA_printf(" I2C Test Utility, \r\n");
	  OSA_printf(" Usage: %s -r|-w <devAddrInHex> <regAddrInHex> <regValueInHex or numRegsToReadInDec> <regSizeInBytes>\r\n", str);
	  OSA_printf(" \n");
	  return 0;
	}
	
	int DRV_i2cTestMain(int argc, char **argv)
	{
	  DRV_I2cHndl i2cHndl;
	  Uint8 devAddr, numRegs;
	  Bool doRead;
	  Uint8 dataSize=1;
	  int status, i;
	  
	  static Uint8 regAddr[256], regValue8[256];
	  static Uint16 regValue16[256];      
	  
	  if(argc<3) {
	    DRV_i2cTestShowUsage(argv[0]);
	    return -1;
	  }
	  
	  if(strcmp(argv[1], "-r")==0)
	    doRead=TRUE;
	  else  
	  if(strcmp(argv[1], "-w")==0)
	    doRead=FALSE;
	  else {
	    DRV_i2cTestShowUsage(argv[0]);
	    return -1;  
	  }
	  
	  devAddr = 0;
	  numRegs = 4;
	  regValue8[0] = 0;
	  regValue16[0] = 0;
	  regAddr[0] = 0;  
	
	  if(argc>2)
	    devAddr = xstrtoi(argv[2]);
	    
	  if(argc>3)
	    regAddr[0] = xstrtoi(argv[3]);
	
	  if(argc>5) 
	    dataSize = atoi(argv[5]);
	  
	  if(dataSize>2 || dataSize<=0)
	    dataSize=1;
	
	  if(argc>4) {
	    if(doRead)
	      numRegs = atoi(argv[4]);
	    else {
	      if(dataSize==1)
	        regValue8[0] = xstrtoi(argv[4]);
	      else
	      if(dataSize==2)      
	        regValue16[0] = xstrtoi(argv[4]);      
	    }
	  }
	    
	  if(devAddr==0) {
	    OSA_printf(" I2C: Invalid device address\n");
	    DRV_i2cTestShowUsage(argv[0]);
	    return -1;  
	  }
	  
	//  OSA_printf(" I2C: Opening I2C at device address %x ...\n", devAddr);
	  
	  status = DRV_i2cOpen(&i2cHndl, devAddr);
	  
	  if(status != OSA_SOK) {
	    OSA_ERROR("DRV_i2cOpen(%d)", devAddr);
	    return status;
	  }
	    
	  if(status==OSA_SOK)
	  {
	    #if 1
	    if(doRead) {
	      for(i=1; i<numRegs; i++)
	        regAddr[i] = regAddr[0]+i;
	      
	      if(dataSize==1)
	        status = DRV_i2cRead8(&i2cHndl, regAddr, regValue8, numRegs);
	      else
	      if(dataSize==2)      
	        status = DRV_i2cRead16(&i2cHndl, regAddr, regValue16, numRegs);
	
	      OSA_printf(" \n");      
	      if(status==OSA_SOK) {
	        for(i=0; i<numRegs; i++) {
	          if(dataSize==1) {
	            OSA_printf(" I2C: 0x%02x = 0x%02x \n", regAddr[i], regValue8[i] );          
	          } else
	          if(dataSize==2)
	            OSA_printf(" I2C: 0x%02x = 0x%04x \n", regAddr[i], regValue16[i] );          
	          
	        }
	      } else {
	        OSA_printf(" I2C: Read ERROR !!!\n");          
	      }
	      OSA_printf(" \n");              
	      
	    } else {
	      OSA_printf(" \n");              
	          
	      if(dataSize==1) {   
	
	        status = DRV_i2cWrite8(&i2cHndl, regAddr, regValue8, 1);
	        if(status==OSA_SOK) {
	          status = DRV_i2cRead8(&i2cHndl, regAddr, regValue8, 1);
	        }        
	      }
	      else
	      if(dataSize==2) {   
	        status = DRV_i2cWrite16(&i2cHndl, regAddr, regValue16, 1);
	        if(status==OSA_SOK) {
	          status = DRV_i2cRead16(&i2cHndl, regAddr, regValue16, 1);        
	        }
	      }
	      
	      if(status==OSA_SOK) {
	        if(dataSize==1) {
	          OSA_printf(" I2C: 0x%02x = 0x%02x \n", regAddr[0], regValue8[0] );          
	        } else
	        if(dataSize==2)
	          OSA_printf(" I2C: 0x%02x = 0x%04x \n", regAddr[0], regValue16[0] );                  
	      } else {
	        OSA_printf(" I2C: Write ERROR !!!\n");          
	      }
	      OSA_printf(" \n");                    
	      
	    }
	    #endif
	    
	    DRV_i2cClose(&i2cHndl);
	  }


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值