i2c-tools讀寫16位寄存器調試

最近在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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章