i2c-tools读写16位寄存器调试

1 篇文章 0 订阅
1 篇文章 0 订阅

最近在rk3399平台上更换调试了录音小板,原rk3399的es7243 修改新的adc小板,一开始硬件就有问题,但因为对硬件不熟悉,导致做了汗多无用功,

言归正传,换adc录音小板,首先应该用i2ctools 检测寄存器

 

 

硬件i2c ok的情况下能使用i2cdetect 能检测到设备,驱动里配置了地址就显示为UU,没有配置地址显示具体值,比如10

       一般寄存器都是8位地址的,i2ctools 里的i2cdump i2cget  i2cset,也是设置读取8位的地址,但这次调试的寄存器是16位地址,i2cdump i2cget  i2cset 都用不了,这时候就要用到i2ctransfer 了,I2C-Tools 4.0增加了i2ctransfer命令,可以对i2c设备指定定长度进行读写操作

比如在这个16位的寄存器里我们要看 0x0020 开始的寄存器值,向后读取16个字节

i2ctransfer -y -f 1 w2@0x1d 0x00 0x20 r16

读取了16个字节数据

w是写,2是写入2个字节,@0x1d 是寄存器地址,0x00 0x20 是寄存器要设置的地址的高低位,r是读取,16 是读取16个字节

如果我们想修改0x0020 的值可以如下指令

i2ctransfer -y -f 1 w4@0x1d 0x00 0x20 0x77 0x77

可以看到设置成功了

w是写,4是写入4个字节,@0x1d 是寄存器地址,0x00 0x20 是寄存器要设置的地址的高低位,0x77 0x77是要设置的值

 

加上代码写16位寄存器方法

static int i2c_write(struct i2c_client *client, u16 reg, u16 value)
{
	u8 data[4];

	data[0] = (reg& 0xFF00)>>8 ;
	data[1] = reg& 0x00FF;
    data[2] = (value& 0xFF00)>>8;
	data[3] = value& 0x00FF;
	if (i2c_master_send(client, data, 4) == 4){
		printk("send ok\n");
		return 0;
	}
	else{
		printk("send failed");
		return -EIO;
	}
		
}

int i2c_master_send(struct i2c_client *client,const char *buf ,int count) 
{ 
    int ret; 
    struct i2c_adapter *adap=client->adapter;  // 获取adapter信息 
    struct i2c_msg msg;                        // 定义一个临时的数据包 
 
    msg.addr = client->addr;                   // 将从机地址写入数据包 
    msg.flags = client->flags & I2C_M_TEN;     // 将从机标志并入数据包 
    msg.len = count;                           // 将此次发送的数据字节数写入数据包 
    msg.buf = (char *)buf;                     // 将发送数据指针写入数据包 
    ret = i2c_transfer(adap, &msg, 1);         // 调用平台接口发送数据 
 
     
    return (ret == 1) ? count : ret;           // 如果发送成功就返回字节数 
}

 

 

 

读取16位

static u16 i2c_read(struct i2c_client *client, u16 reg)
{
	struct i2c_msg xfer[2];
	u8 data[2];
	int ret;
	u16 result = -1;
    u8 reg_buf[2];
	reg_buf[0]= (reg& 0xFF00)>>8;
	reg_buf[1]= reg& 0x00FF;
	/* Write register */
	xfer[0].addr = client->addr;
	xfer[0].flags = 0;
	xfer[0].len = 2;
	xfer[0].buf = reg_buf;
	/* Read data */
	xfer[1].addr = client->addr;
	xfer[1].flags = I2C_M_RD;
	xfer[1].len = 2;
	xfer[1].buf = data;

	ret = i2c_transfer(client->adapter, xfer, 2);
	if (ret != 2) {
		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
		return 0;
	}
 
	result = *(u16 *)data;
	printk("read ok data[0] = 0x%0x , data[1] = 0x%0x\n",data[0],data[1]);
    //printk("***0x%x***\n",xfer[1].buf[0]);
	return result;
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值