前言
最近项目中有块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上面