android系统下I2C read测试app

最近在调试Android系统下的I2C,主要用于读取数据,所以下面代码只有I2C读取。

关于Android系统下如何增加C语言app,可以参考:

Android增加C语言app方法-CSDN博客

Android版本:Android 13

内核版本:5.15

以下是I2C读取代码,在设备上验证通过:

#include <stdio.h>
#include <linux/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <string.h>
#include <errno.h>

/*********定义struct i2c_rdwr_ioctl_data和struct i2c_msg,要和内核一致*******/

/***********主程序***********/
int main(int argc, char* argv[])
{
    int fd = 0, ret;
    char *s_Dev = NULL;
    unsigned char s_Write[4];
    unsigned char *p_Read = NULL;
    unsigned short read_len = 0;
    unsigned char device_addr = 0x55; /*  设备地址 */
    unsigned char data_addr = 0x0;    /*  数据地址  */

    struct i2c_msg i2cmsg[2];
    int loop = 1;
    char *endptr;
    int result = 0;
    
    if(argc != 5)
    {
        printf("Usage: %s i2c-device slave_addr(Hex) reg_addr(Hex) lenth_to_read(Dec)\n", argv[0]);
        printf("Example: %s /dev/i2c-1 0x55 0x9c 3\n", argv[0]);

        result = -1;
        goto err;
    }

    s_Dev = argv[1];
    device_addr = strtol(argv[2], &endptr, 16);
    data_addr   = strtol(argv[3], &endptr, 16);
    read_len    = atoi(argv[4]);

    fd = open(s_Dev, O_RDWR);
    if (fd < 0)
    {
        printf("open failed [%s]\n", s_Dev);
        perror("open error");

        result = -2;
        goto err;
    }
    printf("open [%s] ok !\n", s_Dev);

    
    p_Read = malloc(read_len);
    if(NULL == p_Read)
    {
        printf("malloc [%d] error.\n", read_len);
        result = -3;
        goto err;
    }

    struct i2c_rdwr_ioctl_data msg_rdwr; // = {.msgs = i2cmsg, .nmsgs = 2};
    msg_rdwr.msgs = i2cmsg;
    msg_rdwr.nmsgs = 2;

    ioctl(fd, I2C_TIMEOUT, 1); /*超时时间*/
    ioctl(fd, I2C_RETRIES, 2); /*重复次数*/

    /**  read data begin  **/
    endptr = argv[1];
    s_Write[0] = data_addr;
    s_Write[1] = 0;
    
    msg_rdwr.msgs[0].addr = device_addr;    // 设备地址
    msg_rdwr.msgs[0].flags = 0;             // write
    msg_rdwr.msgs[0].buf = s_Write;         // 数据地址
    msg_rdwr.msgs[0].len = 1;
 
    msg_rdwr.msgs[1].addr = device_addr;   // 设备地址
    msg_rdwr.msgs[1].flags = 1;            // read
    msg_rdwr.msgs[1].buf = p_Read;         //读出的数据
    msg_rdwr.msgs[1].len = read_len;       //读出数据的长度

    ret = ioctl(fd, I2C_RDWR, (unsigned long)&msg_rdwr);
 
    if (ret < 0)
    {
        perror("ioctl error1");
        result = -4;
        goto err;
    }
    else
    {
        printf("ret[%d]\n", ret);
    }

    printf("write[len:%d]: \t", msg_rdwr.msgs[0].len);
    for(loop = 0; loop < msg_rdwr.msgs[0].len; loop++)
    {
    	printf(" %02x", s_Write[0]);
    }
    printf("\n");
    printf("read[len:%d]: \t", msg_rdwr.msgs[1].len);
    for(loop = 0; loop < msg_rdwr.msgs[1].len; loop++)
    {
    	printf(" %02x", p_Read[loop]);
    }
    printf("\n");
    /**  read data end  **/

err:
    if(NULL != p_Read)
    {
        free(p_Read);
    }
    if(fd > 0)
    {
        close(fd);
    }

    return result;
}

设备上验证:

逻辑分析仪抓到的:

1.以下是master给slave发送的,包括slave设备地址、CommandID(有些器件需要发送寄存器地址,更具slave设备的要求确定)

解码结果如下,地址解析出来是0xAA,应该是有点问题的,由于我发送的地址是0x55;有可能是逻辑分析仪把read/write位作为地址的最低bit了。

2. master收到slave的回复之后,发送CommandID:

逻辑分析仪解析结果如下:

3. slave根据master发送的CommandID,给master回复消息:

逻辑分析仪解析如下:

至此,I2C数据的读取就算完成了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值