上一期介绍了一下tinkerboard2 Android11下面适配DSI屏幕的方式(https://blog.csdn.net/chenchen00000000/article/details/124721846),这一期来介绍一下如何支持触摸与屏幕自动旋转。触摸与屏幕自动旋转是Android设备上面的标配功能。
硬件准备
上一期文章中提到,深圳风火轮作为华硕tinkerboard官方合作伙伴,推出了这款屏幕转接板,将屏幕的接口转换为tinkerboard2上面的DSI接口,同时引出了供电,触摸等引脚。屏幕转接板如下图。
在上一期的接线基础上,要接上触摸相关的几根线
TP_RST为触摸复位脚,接GPIO2_C2,也就是tinkerboard2 40PIN排针的36脚
TP_INT为触摸中断脚,接GPIO2_C3,也就是tinkerboard2 40PIN排针的11脚
这两个脚也可以选择其他GPIO,只要将引脚配置复用为GPIO即可
此外,触摸芯片还需要I2C,板上的DSI接口已经包含了一组I2C,是I2C8,因此不用接到排针上面,接线如下
然后要支持自动旋转,必须要接个加速度传感器,笔者这里选择的是ST的LSM6DSL,也可以选择其他的,然后只需要接I2C,不用接中断,板上的40PIN排针只有一组I2C,接上即可
触摸芯片调试
触摸和旋转都涉及源码修改,要下载完整的SDK,SDK可以从深圳风火轮的论坛下载到,比从GIT上直接拉取速度快,地址是Tinker Board 2 & 2S Android11源码下载 - TinkerBoard 2/2s (RK3399) - tinkerboard华硕中国 - Tinker Board
7寸屏幕的触摸芯片为GT911,这是汇顶科技的触摸芯片,支持7-8寸屏,最多5点触摸。内核自带其驱动,路径为drivers/input/touchscreen/gt9xx。内核config要将CONFIG_TOUCHSCREEN_GT9XX设置为Y
然后设备树需要将gt911加入i2c8下,如下
&i2c8 {
goodix_ts@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>; //也可以填0x14
touch-gpio = <&gpio2 RK_PC3 GPIO_ACTIVE_LOW>; //中断IO
reset-gpio = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>; //复位IO
max-x = <1024>; //x方向解析度
max-y = <600>; //y方向解析度
tp-size = <911>; //与源码中选择的配置相关
status = "okay";
};
};
通过配置GT911上电时中断脚和复位脚电平时序,可以切换其I2C地址为0x5d和0x14的其中之一,这一设计是为了解决I2C冲突,这里可以任选一个
touch-gpio是中断脚,reset-gpio是复位脚,配置和硬件接线一致
max-x和max-y分别是x方向和y方向最大值,按屏的分辨率填写即可
tp-size对应的是源码中触摸配置文件的选择,这里填911
源码中有几个点需要修改一下。在gt9xx目录中找到gt9xx.c,
这里将gtp_change_x2y设置为false,不交换x和y的坐标上报值
然后找到gt9xx_cfg.h,将配置文件换掉,配置文件可以从 深圳风火轮 的网盘中获取,文件名为GT911_Config_20220510_094105.cfg
这里简单提一下原理,在GT911中,寄存器地址从0x8047开始,到0x8100,总共186个字节,为GT911的配置文件,datasheet中部分寄存器的功能说明如下
完整版本的可以直接查阅GT911 datasheet。这些寄存器的值与外屏,触摸芯片的贴合,接线等强相关,一般屏厂会提供这些信息,然后将这些值放到一个cfg文件中。下面可以大致看下其源码
在gt9xx_cfg.h中,将GT911_Config_20220510_094105.cfg中186个字节赋值给数组gtp_dat_gt11
然后在gt9xx.c中,将这个gtp_dat_gt11中的内容memcpy到名为config的数组中,然后在初始化的时候,会将名为config的数组内容写入到0x8047开头的寄存器中。这就是配置文件的原理
将这些地方修改之后,编译内核,烧录到板上,然后开机启动信息中,可以看到
说明GT911已经注册为一个INPUT设备。
在Linux下,鼠标,键盘,触摸这些都是INPUT设备,Android上层会监听所有的INPUT设备上报事件,如果有坐标上报事件,则会进行响应
在Android中,打开设置-系统-开发者选项 ( 如果找不到开发者选项,可以打开设置-关于平板电脑,然后多次点击版本号,即可进入开发者模式,开发者选项就会出现 ) 中的指针位置,就能显示出当前触摸的点,通过这种方式,可以确认触摸的驱动是否正常工作,上报的点位是否准确。
到这里,触摸的调试就完成了。
画面自动旋转功能调试
Android里面的自动旋转功能,本质就是靠加速度传感器,识别出当前设备的朝向,然后自动旋转画面。
RK已经实现了一套传感器的框架,具体的开发指南可以参考SDK里面的文档(RKDocs/common/Sensors)。
RK SDK里面已经带了部分加速度传感器的驱动,路径为kernel/drivers/input/sensors/accel,如果要新增,可以直接参考这里面的添加。
比如笔者这里添加的LSM6DSL,为ST的加速度传感器,而SDK里面自带的LSM330,同样为ST的加速度传感器,一般来说,同一个厂商的IC,数据读取方式是相似的,最多是寄存器不一样,直接参考其修改即可
目前RK的传感器框架,就是要实现这个名为struct sensor_operate的结构体,然后在probe函数中通过sensor_register_device将其注册。在这个结构体中
struct sensor_operate lsm6dsx_acc_ops = {
//名称
.name = "lsm6dsx_acc",
//类型,加速度传感器指定为SENSOR_TYPE_ACCEL
.type = SENSOR_TYPE_ACCEL,
//这个值要在内核目录下include/linux/sensor-dev.h中定义
.id_i2c = ACCEL_ID_LSM6DSX,
//从id_reg寄存器中取得的值必须等于id_data
.id_reg = ST_LSM6DSX_REG_WHO_AM_I,
.id_data = LSM6DSL_DEVICE_ID,
//这两个默认的
.precision = 16,
.range = {-32768, 32768},
//用不到中断,保持默认
.trig = IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
//使能函数和初始化函数
.active = lsm6dsx_acc_active,
.init = lsm6dsx_acc_init,
//应用层会定时调用这个API,这个API中要包含input设备上报的功能
.report = lsm6dsx_acc_report_value,
};
注意这个report函数,它上报的值要和Android系统里面指定的X Y Z方向一致,需要将传感器里面读取到的原始值进行换算
编写完驱动之后,编译内核,然后将boot.img烧录到板上,注意到这个打印信息
说明已经识别到设备,且已经注册成功了,如果没有这些信息,需要排查下id_reg和id_data是否配置正确。
然后可以尝试打开Android的自动旋转屏幕功能,如果传感器配置正确,此时画面会随着设备的朝向自动旋转。如果旋转方向不对,就需要排查传感器的值和Android系统指定的X Y Z方向的换算是否正确。
到这里,自动旋转屏幕的功能就调试完成。
总结
本文在上一篇tinkerboard2对接7寸1024*600分辨率的DSI屏幕的基础上,介绍了触摸和自动旋转两个和显示相关性较大的功能,调试的方法对于其他的触摸芯片和其他型号的加速度传感器同样适用。
得益于RK的SDK上面一些成熟的框架,tinkerboard2在视频输出这块,一些客制化的功能开发起来要比树莓派容易很多。