前言
最近項目中有塊rockchip的板子需要同時適配兩塊LCD,但是沒看到RK平臺本身有這個功能,所以我們想到通過TP本身提供的sensor id去判斷,然後做相應的初始化動作。
所以我們需要先看一下在uboot中怎麼去獲取TP的sensor id值。
正文
TP本身是有寄存器給我們去獲取一些信息,包括sensor id:
如紅色框起來的地方,讀取寄存器0x814A的低4位就可以知道sensor id了。
我的TP是通過I2C去和CPU通信的,所以我們就可以通過I2C提供的接口去讀取TP寄存器的值:
/*
* Read/Write interface:
* chip: I2C chip address, range 0..127
* addr: Memory (register) address within the chip
* alen: Number of bytes to use for addr (typically 1, 2 for larger
* memories, 0 for register type devices with only one
* register)
* buffer: Where to read/write the data
* len: How many bytes to read/write
*
* Returns: 0 on success, not 0 on failure
*/
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len);
通過上面的註釋我們可以知道:
chip: 從設備的地址,這裏就是TP的地址
addr: 想要讀取的寄存器地址,我這裏就是0X814A
alen: 寄存器地址的長度,單位爲字節,所以0X814A的長度爲2
buffer: 保存讀取後內容的緩衝區
len: 需要讀取的字節數,不要大於buffer的長度
知道函數的參數意義後,我們就很容易去寫代碼了,但是首先我們需要知道TP作爲從設備的地址是多少。從TP的datasheet我們可以看到如下信息:
爲什麼會有0x28和0x29兩個呢?熟悉I2C協議的同學應該知道,從設備的地址其實只有高7位,最低位代表的是讀還是寫,所以真正的從設備地址應該是0x28/0x29的高7位,也就是b00010100=0x14。(I2C的協議可以參考我另外一篇文章:I2C協議原理簡述)
uint8_t sensor_id;
uint8_t buf;
char sensor_id_str[32];
i2c_set_bus_num(1);
i2c_read(0x14, 0x814A, 2, &buf, 1);
sensor_id = buf & 0x0f;
printf("sensor_id = 0x%x\n", sensor_id);
上面還有一個函數需要解釋一下
/*
* i2c_set_bus_num:
*
* Change the active I2C bus. Subsequent read/write calls will
* go to this one.
*
* bus - bus index, zero based
*
* Returns: 0 on success, not 0 on failure
*
*/
int i2c_set_bus_num(unsigned int bus);
板子上一般會有多個I2C總線,所以在讀取I2C從設備的信息時,需要用i2c_set_bus_num()函數去切換到需要的總線上,比如我的TP就在I2C1上面