I2C用户态工具

我们可以根据设备节点来操作响应的i2c,以便应用层实现对i2c读写操作。内核态和用户态操作都可以在外设驱动指南pdf中有相应的说明。本示例可以当作一个工具使用。当然对于i2c工具很多,比如海思tools封装好的i2c_read和i2c_write,另外还有开源工具i2c-tools(busybox编译出来有这个工具)。

/**
* Copyright (C), 2016, 
* All rights reserved.
*
* @file      maincpp
* @brief  
* @author    初创
* @date      2019.12.14
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>


struct i2c_msg {
         __u16 addr; // slave address
         __u16 flags;
        #define I2C_M_TEN                          0x0010       //10bit地址
        #define I2C_M_RD                           0x0001  //读取数据标志,清零表示写
        #define I2C_M_NOSTART                 x4000         //不发送起始位
        #define I2C_M_REV_DIR_ADDR       0x2000       // 反转读写标志
        #define I2C_M_IGNORE_NAK           x1000    //忽略I2C器件的ack和nack信号
        #define I2C_M_NO_RD_ACK            0x0800       //读操作时
        #define I2C_M_RECV_LEN             0x0400   //length will be first received byte
         __u16 len; // msg length
         __u8 *buf; // pointer to msg data
};
		

/*****************************************************************************
 Prototype    : atoul
 Description  : 10进制字符串转换为无符号数字。
 Input  args  : IN char *str 10进制字符串
                不接受符号
 Output args  : U32* pulValue, 转换后的数字
 Return value : int  HI_SUCCESS 转换成功
                        HI_FAILURE 转换失败
 Calls        : isdigit
                
 Called  By   : 
                
 History        : 
 1.Date         : 2005年7月10日
   Author       : t41030
   Modification : Created function
*****************************************************************************/
int atoul( char *str, unsigned long * pulValue)
{
    unsigned long ulResult=0;

    while (*str)
    {
        if (isdigit((int)*str))
        {
            /*最大支持到0xFFFFFFFF(4294967295), 
               X * 10 + (*str)-48 <= 4294967295
               所以, X = 429496729 */
            if ((ulResult<429496729) || ((ulResult==429496729) && (*str<'6')))
            {
                ulResult = ulResult*10 + (*str)-48;
            }
            else
            {
                *pulValue = ulResult;
                return -1;
            }
        }
        else
        {
            *pulValue=ulResult;
            return -1;
        }
        str++;
    }
    *pulValue=ulResult;
    return 0;
}

/*****************************************************************************
 Prototype    : atoulx
 Description  : 16进制字符串转换为无符号数字。输入的16进制字符串不包括前缀0x
 Input  args  : IN char *str 16进制字符串, 不包括前缀0x. 如ABCDE
 Output args  : U32* pulValue, 转换后的数字
 Return value : int  HI_SUCCESS 转换成功
                        HI_FAILURE 转换失败
 Calls        : toupper
                isdigit
                
 Called  By   : 
                
 History        : 
 1.Date         : 2005年7月10日
   Author       : t41030
   Modification : Created function
*****************************************************************************/

#define ASC2NUM(ch) (ch - '0')
#define HEXASC2NUM(ch) (ch - 'A' + 10)

int  atoulx(char *str, unsigned long * pulValue)
{
    unsigned long  ulResult=0;
    unsigned char ch;

    while (*str)
    {
        ch=toupper(*str);
        if (isdigit(ch) || ((ch >= 'A') && (ch <= 'F' )))
        {
            if (ulResult < 0x200000000)
            {
                ulResult = (ulResult << 4) + ((ch<='9')?(ASC2NUM(ch)):(HEXASC2NUM(ch)));
            }
            else
            {
                *pulValue=ulResult;
                return -1;
            }
        }
        else
        {
            *pulValue=ulResult;
            return -1;
        }
        str++;
    }
    
    *pulValue=ulResult;
    return 0;
}

int g_fd;

int StrToNumber( char *str ,  unsigned long * pulValue)
{
    /*判断是否16进制的字符串*/
    if ( *str == '0' && (*(str+1) == 'x' || *(str+1) == 'X') )
    {
        if (*(str+2) == '\0')
        {
            return -1;
        }
        else
        {
            return atoulx(str+2,pulValue);
        }
    }
    else
    {
        return atoul(str,pulValue);
    }
}

int main(int argc, char *argv[])
{
    

	char acDevFile[16] = {0};
	unsigned long u8DevNum;
	unsigned long u8devaddr;
	unsigned long u8reg_width;
	unsigned long u8reg;
	unsigned long u8value;
	
    if(argc < 4)
	{
		printf("\n usage: %s <i2c-num> <addr> <reg_width> <reg> <value> . sample: %s  0x1 0x36 0x01 0xf4 (0x10)\n", argv[0], argv[0]);
		printf("cmd 1-4\n");
		
	}
	
	StrToNumber(argv[1], &u8DevNum);
	StrToNumber(argv[2], &u8devaddr);
	StrToNumber(argv[3], &u8reg_width);
	StrToNumber(argv[4], &u8reg);
	if(argc == 6)
	{
		StrToNumber(argv[5], &u8value);
	}
	
	snprintf(acDevFile, sizeof(acDevFile),  "/dev/i2c-%u", u8DevNum);
	
	g_fd = open(acDevFile, O_RDWR, S_IRUSR | S_IWUSR);;
    if(g_fd <= 0)
    {
		printf("open %s failed \n", acDevFile);
        return -1;
    }
int ret = ioctl(g_fd, I2C_SLAVE_FORCE, (u8devaddr >> 1));
    if (ret < 0) {
        printf("I2C_SLAVE_FORCE error!\n");
        close(g_fd);
        g_fd = -1;
        return ret;
    }
	
	if(argc == 6)
	{
		int idx = 0;
		char buf[8];

		/**reg 2Byte*/
		if(u8reg_width == 2)
		{
			buf[idx] = (u8reg >> 8) & 0xff;
			idx++;
			buf[idx] = u8reg & 0xff;
			idx++;
		}
		else
		{
			buf[idx] = u8reg & 0xff;
			idx++;
		}
		
		/**value 1Byte*/
		buf[idx] = u8value & 0xff;
		idx++;
		
		ret = write(g_fd, buf, 3);
		if (ret < 0) {
			printf("I2C_WRITE error!\n");
			return -1;
		}
	}
    else
	{
		#if 1
		unsigned char buf[4];
		struct i2c_rdwr_ioctl_data rdwr;
		struct i2c_msg msg[2];
		unsigned int data;
		memset(buf, 0x0, 4);
		
		msg[0].addr = u8devaddr>>1;
		msg[0].flags = 0;
		msg[0].buf = buf;
		if(u8reg_width == 2)
		{
			msg[0].len = 2;
			buf[0] = (u8reg >> 8) & 0xff;
			buf[1] = u8reg & 0xff;
		}
		else
		{
			buf[0] = u8reg & 0xff;
			msg[0].len = 1;
		}
		
		msg[1].addr = u8devaddr>>1;
		msg[1].flags = 0;
		msg[1].flags |= I2C_M_RD;
		msg[1].len = 1;
		msg[1].buf = buf;
		rdwr.msgs = &msg[0];
		rdwr.nmsgs = 2;
        ret = ioctl(g_fd, I2C_RDWR, &rdwr);
		if (ret != 2) {
			printf("CMD_I2C_READ error!\n");
			ret = -1;
			return -1;
		}
	
		data = buf[0];

		printf("0x%x: 0x%x\n", u8reg, data);
		#endif
	}
	


	close(g_fd);
    
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值