10. input子系统:触摸屏¶
在上节内容中,已经讲解到了如何使用input输入子系统读取按键值, 触摸屏也是属于input输入子系统的设备,关于input输入子系统 的内容请参考 input子系统:按键检测
10.1. 使能触摸屏相关设备树插件¶
野火imx6ull提供了很多的设备树插件,用于控制板子上外设的开启,默认状态下触摸屏相关插件是没有开启的, 因此我们先需要开启触摸屏相关的设备树插件。修改 /boot/uEnv.txt 文件内容, 使能触摸屏设备树相关插件内容以及i2c1设备树插件并重启开发板。
1 2 | dtoverlay=/usr/lib/linux-image-4.19.94-stm-r1/overlays/stm-fire-i2c1.dtbo
dtoverlay=/usr/lib/linux-image-4.19.94-stm-r1/overlays/stm-fire-touch-capacitive-goodix.dtbo
|
查看 /dev/input 以及 /dev/input/by-path 目录下的内容
1 2 3 4 5 6 7 8 9 10 | root@npi:~# ls -l /dev/input/
total 0
drwxr-xr-x 2 root root 80 Mar 5 05:47 by-path
crw-rw---- 1 root input 13, 64 Mar 5 05:47 event0
crw-rw---- 1 root input 13, 65 Mar 5 05:47 event1
root@npi:~# ls -l /dev/input/by-path/
total 0
lrwxrwxrwx 1 root root 9 Mar 5 05:47 platform-40012000.i2c-event -> ../event0
lrwxrwxrwx 1 root root 9 Mar 5 05:47 platform-gpio-keys-event -> ../event1
root@npi:~#
|
可知其中触摸屏设备对应的是 event0 ,不同板子情况可能不同。
10.2. 使用evtest测试屏幕¶
通过以下命令下载evtest工具
1 | sudo apt install evtest
|
在终端上执行evtest命令并选择触摸屏进行测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | root@npi:~# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0: Goodix Capacitive TouchScreen
/dev/input/event1: gpio-keys
Select the device event number [0-1]: 0
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x416 product 0x395 version 0x200
Input device name: "Goodix Capacitive TouchScreen"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 125 (KEY_LEFTMETA)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 167
Min 0
Max 799
Event code 1 (ABS_Y)
Value 264
Min 0
Max 479
Event code 47 (ABS_MT_SLOT)
Value 0
Min 0
Max 9
Event code 48 (ABS_MT_TOUCH_MAJOR)
Value 0
Min 0
Max 255
Event code 50 (ABS_MT_WIDTH_MAJOR)
Value 0
Min 0
Max 255
Event code 53 (ABS_MT_POSITION_X)
Value 0
Min 0
Max 799
Event code 54 (ABS_MT_POSITION_Y)
Value 0
Min 0
Max 479
Event code 57 (ABS_MT_TRACKING_ID)
Value 0
Min 0
Max 65535
Properties:
Property type 1 (INPUT_PROP_DIRECT)
Testing ... (interrupt to exit)
Event: time 1614924530.479210, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 56
Event: time 1614924530.479210, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 729
Event: time 1614924530.479210, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 392
Event: time 1614924530.479210, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 34
Event: time 1614924530.479210, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 34
Event: time 1614924530.479210, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1614924530.479210, type 3 (EV_ABS), code 0 (ABS_X), value 729
Event: time 1614924530.479210, type 3 (EV_ABS), code 1 (ABS_Y), value 392
Event: time 1614924530.479210, -------------- SYN_REPORT ------------
Event: time 1614924530.507254, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1
Event: time 1614924530.507254, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1614924530.507254, -------------- SYN_REPORT ------------
|
根据以上信息即可知道当触摸屏幕时有什么事件产生。
10.3. 编写应用程序¶
触摸屏检测相关的应用程序与按键检测的应用程序类似,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <linux/input-event-codes.h>
#include <unistd.h>
#define default_path "/dev/input/event0"
int main(int argc,char * argv[])
{
int fd;
int ret;
char * path;
struct input_event event;
int x,y;
if (argc == 2)
{
path = argv[1];
}
else
{
path = default_path;
}
//打开设备
fd = open(path,O_RDONLY);
if(fd < 0)
{
perror(path);
exit(-1);
}
while (1)
{
memset(&event, 0, sizeof(struct input_event));
//读取按键值
ret = read(fd,&event,sizeof(struct input_event));
if (ret == sizeof(struct input_event))
{
//触发事件类似判断
if(event.type == EV_ABS)
{
//X、Y轴坐标
if(event.code == ABS_X)
x = event.value;
else if(event.code == ABS_Y)
y = event.value;
}
//打印坐标
if(event.type == EV_SYN) //EV_SYN
{
printf("touch x = %d,y = %d\n", x, y);
}
}
}
close(fd);
return 0;
}
|
运行程序后,触摸屏幕后将不断打印坐标信息。
10.4. 触摸屏相关设备树插件¶
野火STM32MP157提供了很多的设备树插件源码,若想要修改触摸屏设备树插件, 用户只需要根据相关相对应的设备树插件修改即可。
其中触摸屏的设备树插件为 stm-fire-touch-capacitive-goodix-overlay.dts ,源码如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /dts-v1/;
/plugin/;
//#include "../stm32mp157c.dtsi"
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mfd/st,stpmic1.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
/{
fragment@0{
target=<&i2c1>;
__overlay__{
#address-cells = <1>;
#size-cells = <0>;
gtxx_tsc@5d {
compatible = "goodix,gt917s";
reg = <0x5d>;
status = "okay";
/*gpio*/
reset-gpios = <&gpioe 12 GPIO_ACTIVE_LOW>;
irq-gpios = <&gpioz 4 GPIO_ACTIVE_HIGH>;
/*interrupt*/
interrupt-parent = <&gpioz>;
interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
irq-flags = <2>; /*1:rising 2: falling*/
};
};
};
};
|
若想修改触摸屏控制芯片相关引脚,仅需要修改以上高亮部分代码即可。