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. 编写应用程序

触摸屏检测相关的应用程序与按键检测的应用程序类似,如下所示

代码仓库/Source/input/touch_input.c
 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提供了很多的设备树插件源码,若想要修改触摸屏设备树插件, 用户只需要根据相关相对应的设备树插件修改即可。

野火设备树插件GitHub

其中触摸屏的设备树插件为 stm-fire-touch-capacitive-goodix-overlay.dts ,源码如下所示

ebf_linux_kernel/tree/ebf_4.19_star/arch/arm/boot/dts/overlays/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*/
             };
         };

     };

 };

若想修改触摸屏控制芯片相关引脚,仅需要修改以上高亮部分代码即可。