1.多点电容触摸简介

        ATK-7016 这款屏幕其实是由 TFT LCD+触摸屏组合起来的。底下是 LCD 面板,上面是触摸面板,将两个封装到一起就成了带有触摸屏的 LCD 屏幕。电容触摸屏也是需要一个驱动 IC的,驱动 IC 一般会提供一个 I2C 接口给主控制器,主控制器可以通过 I2C 接口来读取驱动 IC里面的触摸坐标数据。ATK-7016、ATK-7084 这两款屏幕使用的触摸控制 IC 是 FT5426,ATK- 4342 使用的驱动 IC 是 GT9147。这三个电容屏触摸 IC 都是 I2C 接口的,使用方法基本一样。
        FT5426 这款驱动 IC 采用 15*28 的驱动结构,也就是 15 个感应通道,28 个驱动通道,最
多支持 5 点电容触摸。ATK-7016 的电容触摸屏部分有 4 个 IO 用于连接主控制器:SCL、SDA、
RST 和 INT,SCL 和 SDA 是 I2C 引脚,RST 是复位引脚,INT 是中断引脚。一般通过 INT 引
脚来通知主控制器有触摸点按下,然后在 INT 中断服务函数中读取触摸数据。也可以不使用中
断功能,采用轮询的方式不断查询是否有触摸点按下,和所有的 I2C 器件一样,FT5426 也是通过读写寄存器来完成初始化和触摸坐标数据读取的,本节主要内容就是读写FT5426 的寄存器。FT5426 的 I2C 设备地址为 0X38,FT5426 的寄存器有很多,只用到了其中的一部分,如表所示:

2.多点触摸(MT)协议详解

        老版本的 linux 内核是不支持多点电容触摸的(Multi-touch,简称 MT),MT 协议是后面加入的,因此如果使用 2.x 版本 linux 内核的话可能找不到 MT 协议。MT 协议被分为两种类型,Type A 和 TypeB,这两种类型的区别如下:
TypeA:适用于触摸点不能被区分或者追踪,此类型的设备上报原始数据(此类型在实际使
用中非常少!)。
Type B:适用于有硬件追踪并能区分触摸点的触摸设备,此类型设备通过 slot 更新某一个
触摸点的信息,FT5426 就属于此类型,一般的多点电容触摸屏 IC 都有此能力。
        触摸点的信息通过一系列的 ABS_MT 事件(有的资料也叫消息)上报给 linux 内核,只有
ABS_MT 事件是用于多点触摸的,ABS_MT 事件定义在文件 include/uapi/linux/input.h 中,相关
事件如下所示:
852 #define ABS_MT_SLOT 0x2f /* MT slot being modified */
853 #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
854 #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
855 #define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
856 #define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
857 #define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
858 #define ABS_MT_POSITION_X 0x35 /* Center X touch position */
859 #define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */
860 #define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
861 #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
862 #define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
863 #define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
864 #define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
865 #define ABS_MT_TOOL_X 0x3c /* Center X tool position */
866 #define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
        在 上 面 这 些 众 多 的ABS_MT 事 件 中 , 我 们 最 常 用 的 就 是 ABS_MT_SLOT 、
ABS_MT_POSITION_X 、ABS_MT_POSITION_Y 和 ABS_MT_TRACKING_ID 。其中
ABS_MT_POSITION_X 和 ABS_MT_POSITION_Y 用 来 上报 触 摸点 的 (X,Y) 坐 标 信息 ,
ABS_MT_SLOT 用 来 上 报 触 摸 点 ID ,对于 Type B 类 型 的 设 备 , 需 要 用 到 ABS_MT_TRACKING_ID 事件来区分触摸点。
        对于 TypeA 类型的设备,通过 input_mt_sync()函数来隔离不同的触摸点数据信息,此函数
原型如下所示:
void input_mt_sync(struct input_dev *dev)
        此函数只要一个参数,类型为 input_dev,用于指定具体的 input_dev 设备。input_mt_sync()
函数会触发 SYN_MT_REPORT 事件,此事件会通知接收者获取当前触摸数据,并且准备接收
下一个触摸点数据。
        对于 Type B 类型的设备,上报触摸点信息的时候需要通过 input_mt_slot()函数区分是哪一
个触摸点,input_mt_slot()函数原型如下所示:     

void input_mt_slot(struct input_dev *dev, int slot)
        此函数有两个参数,第一个参数是 input_dev 设备,第二个参数 slot 用于指定当前上报的是
哪个触摸点信息。input_mt_slot()函数会触发 ABS_MT_SLOT 事件,此事件会告诉接收者当前
正在更新的是哪个触摸点(slot)的数据。
        不管是哪个类型的设备,最终都要调用 input_sync()函数来标识多点触摸信息传输完成,告
诉接收者处理之前累计的所有消息,并且准备好下一次接收。Type B 和 Type A 相比最大的区
别就是 Type B 可以区分出触摸点, 因此可以减少发送到用户空间的数据。Type B 使用 slot 协
议区分具体的触摸点,slot 需要用到 ABS_MT_TRACKING_ID 消息,这个 ID 需要硬件提供,
或者通过原始数据计算出来。对于 TypeA 设备,内核驱动需要一次性将触摸屏上所有的触摸点
信息全部上报,每个触摸点的信息在本次上报事件流中的顺序不重要,因为事件的过滤和手指
(触摸点)跟踪是在内核空间处理的。
        Type B 设备驱动需要给每个识别出来的触摸点分配一个 slot,后面使用这个 slot 来上报触
摸点信息。可以通过 slot 的 ABS_MT_TRACKING_ID 来新增、替换或删除触摸点。一个非负数
的 ID 表示一个有效的触摸点,-1 这个 ID 表示未使用 slot。一个以前不存在的 ID 表示这是一个
新加的触摸点,一个 ID 如果再也不存在了就表示删除了。
        有些设备识别或追踪的触摸点信息要比他上报的多,这些设备驱动应该给硬件上报的每个
触摸点分配一个 Type B 的 slot。一旦检测到某一个 slot 关联的触摸点 ID 发生了变化,驱动就
应该改变这个 slot 的 ABS_MT_TRACKING_ID,使这个 slot 失效。如果硬件设备追踪到了比他
正在上报的还要多的触摸点,那么驱动程序应该发送 BTN_TOOL_*TAP 消息,并且调用
input_mt_report_pointer_emulation()函数,将此函数的第二个参数 use_count 设置为 false。

2.1Type A 触摸点信息上报时序

1 ABS_MT_POSITION_X x[0]
2 ABS_MT_POSITION_Y y[0]
3 SYN_MT_REPORT
4 ABS_MT_POSITION_X x[1]
5 ABS_MT_POSITION_Y y[1]
6 SYN_MT_REPORT
7 SYN_REPORT

对于 Type A 类型的设备,发送触摸点信息的时序如下所示,这里以 2 个触摸点为例:

        第 1 行,通过 ABS_MT_POSITION_X 事件上报第一个触摸点的 X 坐标数据,通过
input_report_abs 函数实现,下面同理。
        第 2 行,通过 ABS_MT_POSITION_Y 事件上报第一个触摸点的 Y 坐标数据。
        第 3 行,上报 SYN_MT_REPORT 事件,通过调用 input_mt_sync 函数来实现。
        第 4 行,通过 ABS_MT_POSITION_X 事件上报第二个触摸点的 X 坐标数据。
        第 5 行,通过 ABS_MT_POSITION_Y 事件上报第二个触摸点的 Y 坐标数据。
        第 6 行,上报 SYN_MT_REPORT 事件,通过调用 input_mt_sync 函数来实现。
        第 7 行,上报 SYN_REPORT 事件,通过调用 input_sync 函数实现。
        我们在编写 TypeA 类型的多点触摸驱动的时候就需要按照示例代码中的时序上报坐标信息。Linux 内核里面也有 Type A 类型的多点触摸驱动,找到 st2332.c 这个驱动文件,路径为 drivers/input/touchscreen/st1232.c,找到 st1232_ts_irq_handler 函数,此函数里面就是上报触摸点坐标信息的。
103 static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
104 {
......
111 ret = st1232_ts_read_data(ts);
112 if (ret < 0)
113 goto end;
114
115 /* multi touch protocol */
116 for (i = 0; i < MAX_FINGERS; i++) {
117 if (!finger[i].is_valid)
118 continue;
119
120 input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t);
121 input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x);
122 input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y);
123 input_mt_sync(input_dev);
124 count++;
125 }
......
140
141 /* SYN_REPORT */
142 input_sync(input_dev);
143
144 end:
145 return IRQ_HANDLED;
146 }
        第 111 行,获取所有触摸点信息。
        第 116~125 行,按照 Type A 类型轮流上报所有的触摸点坐标信息,第 121 和 122 行分别上
报触摸点的(X,Y)轴坐标,也就是 ABS_MT_POSITION_X 和 ABS_MT_POSITION_Y 事件。每上报完一个触摸点坐标,都要在第 123 行调用 input_mt_sync 函数上报一个 SYN_MT_REPORT
信息。
        第 142 行,每上报完一轮触摸点信息就调用一次 input_sync 函数,也就是发送一个
SYN_REPORT 事件

2.2 Type B 触摸点信息上报时序

        对于 Type B 类型的设备,发送触摸点信息的时序如下所示,这里以 2 个触摸点为例:
1 ABS_MT_SLOT 0
2 ABS_MT_TRACKING_ID 45
3 ABS_MT_POSITION_X x[0]
4 ABS_MT_POSITION_Y y[0]
5 ABS_MT_SLOT 1
6 ABS_MT_TRACKING_ID 46
7 ABS_MT_POSITION_X x[1]
8 ABS_MT_POSITION_Y y[1] 9 SYN_REPORT
        第 1 行,上报 ABS_MT_SLOT 事件,也就是触摸点对应的 SLOT。每次上报一个触摸点坐
标之前要先使用input_mt_slot函数上报当前触摸点SLOT,触摸点的SLOT其实就是触摸点ID,
需要由触摸 IC 提供。
        第 2 行,根据 Type B 的要求,每个 SLOT 必须关联一个 ABS_MT_TRACKING_ID,通过
修改 SLOT 关联的 ABS_MT_TRACKING_ID 来完成对触摸点的添加、替换或删除。具体用到
的函数就是 input_mt_report_slot_state,如果是添加一个新的触摸点,那么此函数的第三个参数
active 要设置为 true,linux 内核会自动分配一个 ABS_MT_TRACKING_ID 值,不需要用户去指
定具体的 ABS_MT_TRACKING_ID 值。
        第 3 行,上报触摸点 0 的 X 轴坐标,使用函数 input_report_abs 来完成。
        第 4 行,上报触摸点 0 的 Y 轴坐标,使用函数 input_report_abs 来完成。
        第 5~8 行,和第 1~4 行类似,只是换成了上报触摸点 0 的(X,Y)坐标信息
        第 9 行,当所有的触摸点坐标都上传完毕以后就得发送 SYN_REPORT 事件,使用 input_sync 函数来完成。 当一个触摸点移除以后,同样需要通过 SLOT 关联的 ABS_MT_TRACKING_ID 来处理,时序如下所示:
1 ABS_MT_TRACKING_ID -1
2 SYN_REPORT
        第 1 行,当一个触摸点(SLOT)移除以后,需要通过 ABS_MT_TRACKING_ID 事件发送一
个-1 给内核。方法很简单,同样使用 input_mt_report_slot_state 函数来完成,只需要将此函数的
第三个参数 active 设置为 false 即可,不需要用户手动去设置-1。
        第 2 行,当所有的触摸点坐标都上传完毕以后就得发送 SYN_REPORT 事件。当要编写 Type B 类型的多点触摸驱动的时候就需要按照示例代码中的时序上报坐标信息。Linux 内核里面有大量的 Type B 类型的多点触摸驱动程序,我们可以参考这些现成的驱动程序来编写自己的驱动代码。这里就以 ili210x 这个触摸驱动 IC 为例,看看是 Type B 类型是如何上报触摸点坐标信息的。找到 ili210x.c 这 个 驱 动 文 件 , 路 径 为 drivers/input/touchscreen/ili210x.c,找到 ili210x_report_events 函数,此函数就是用于上报 ili210x触摸坐标信息的,函数内容如下所示:

78 static void ili210x_report_events(struct input_dev *input,
79 const struct touchdata *touchdata)
80 {
81 int i;
82 bool touch;
83 unsigned int x, y;
84 const struct finger *finger;
85
86 for (i = 0; i < MAX_TOUCHES; i++) {
87 input_mt_slot(input, i);
88
89 finger = &touchdata->finger[i];
90
91 touch = touchdata->status & (1 << i);
92 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
93 if (touch) {
94 x = finger->x_low | (finger->x_high << 8);
95 y = finger->y_low | (finger->y_high << 8);
96
97 input_report_abs(input, ABS_MT_POSITION_X, x);
98 input_report_abs(input, ABS_MT_POSITION_Y, y);
99 }
100 }
101
102 input_mt_report_pointer_emulation(input, false);
103 input_sync(input);
104 }
        第 86~100 行,使用 for 循环实现上报所有的触摸点坐标,第 87 行调用 input_mt_slot 函数
上 报 ABS_MT_SLOT 事件。第 92 行 调 用 input_mt_report_slot_state 函数上报 ABS_MT_TRACKING_ID 事件,也就是给 SLOT 关联一个 ABS_MT_TRACKING_ID。第 97 和
98 行使用 input_report_abs 函数上报触摸点对应的(X,Y)坐标值。
         第 103 行,使用 input_sync 函数上报 SYN_REPORT 事件.

2.3 MT 其他事件的使用

        在示例代码中给出了 Linux 所支持的所有 ABS_MT 事件,大家可以根据实际需求
将这些 事 件 组 成 各 种 事 件 组 合 。 最 简 单 的 组 合 就 是 ABS_MT_POSITION_X 和
ABS_MT_POSITION_Y,可以通过在这两个事件上报触摸点,如果设备支持的话,还可以使用
ABS_MT_TOUCH_MAJOR 和 ABS_MT_WIDTH_MAJOR 这两个消息上报触摸面积信息,关于
其他 ABS_MT 事件的具体含义大家可以查看 Linux 内核中的 multi-touch-protocol.txt 文档,这
里我们重点补充一下 ABS_MT_TOOL_TYPE 事件。
        ABS_MT_TOOL_TYPE 事件用于上报触摸工具类型,很多内核驱动都不能区分出触摸设备
类型,是手指还是触摸笔?这种情况下,这个事件可以忽略掉。目前的协议支持
MT_TOOL_FINGER(手指)、MT_TOOL_PEN(笔)和 MT_TOOL_PALM(手掌)这三种触摸设备类
型 , 于 Type B 类 型 , 此 事 件 由 input 子系统内核处理。如果驱动程序需要上报
ABS_MT_TOOL_TYPE 事件,那么可以使用 input_mt_report_slot_state 函数来完成此工作。
关于 Linux 系统下的多点触摸(MT)协议就讲解到这里,简单总结一下,MT 协议隶属于 linux
的 input 子系统,驱动通过大量的 ABS_MT 事件向 linux 内核上报多点触摸坐标数据。根据触
摸 IC 的不同,分为 TypeA 和 Type B 两种类型,不同的类型其上报时序不同,目前使用最多的
是 Type B 类型。接下来我们就根据前面学习过的 MT 协议来编写一个多点电容触摸驱动程序。

3. 硬件原理分析

触摸屏是和 RGB LCD 屏幕做在一起的,所以触摸屏也在 RGB LCD 接口上,都是连接在 I.MX6U-ALPHA 开发板底板上,原理图如图:
从图可以看出,触摸屏连接着I.MX6U的I2C2,INT引脚连接着I.MX6U的GPIO1_IO9,RST 引脚连接着 I.MX6U 的 SNVS_TAMPER9。在本章实验中使用中断方式读取触摸点个数和触摸点坐标数据,并且将其显示在 LCD 上。

Linux 多点电容触摸屏实验(1)相关推荐

  1. 【正点原子Linux连载】第六十四章 Linux 多点电容触摸屏实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  2. Linux 多点电容触摸屏实验

    1.电容触摸屏驱动框架 1.1 MT协议讲解 ①.电容触摸屏是 IIC 接口的,需要触摸 IC,以正点原子的 ATK7016 为例,其所使用的触摸屏控制 IC 为 FT5426,因此所谓的电容触摸驱动 ...

  3. 正点原子Linux阿尔法开发板4.3 寸多点电容触摸屏测试问题和gt9xx系列linux驱动移植

    正点原子Linux阿尔法开发板4.3 寸多点电容触摸屏测试问题和gt9xx系列linux驱动移植 正点原子官方CSDN 4.3 寸多点电容触摸屏测试问题 正点原子gt9xx系列linux驱动移植 1. ...

  4. 驱动程序开发:多点电容触摸屏

    驱动程序开发:多点电容触摸屏 一.编写驱动前的知识准备 1.CST340触摸屏芯片寄存器 2.CST340触摸屏的硬件原理图 3.电容触摸屏驱动是由几种linux驱动框架组成的 4.linux多点电容 ...

  5. STM32MP157驱动开发——多点电容触摸屏驱动

    STM32MP157驱动开发--多点电容触摸屏驱动 一.简介 二.电容触摸屏驱动框架简介 多点触摸(MT)协议详解 三.驱动开发 1.添加 FT5426 设备节点 2.FT5426 节点配置 3.驱动 ...

  6. 嵌入式Linux开发12——触摸屏实验

    背景知识   关于电容屏的物理原理我们就不去研究了,毕竟我们不是开发电容屏的,而是电容屏的使用者,我们只需要关注如何使用电容屏,如何得到其多点触摸坐标值即可.   我们以触摸控制IC FT5426为例 ...

  7. i.MX6ULL终结者Linux 电容触摸屏实验硬件原理图

    在本实验中使用迅为的7寸屏为例,使用的是FT5426触摸芯片. 图 1 从原理图中得知,7寸屏使用I2C2,触摸屏复位引脚为SNVS_TAMPER9,中断引脚为GPIO_9.

  8. 正点原子Linux阿尔法开发板4.3 寸多点电容触摸屏测试问题

    正点原子给的技术文档如上图,我按照文档上的步骤配置设备树更改驱动发现触摸没有反应,我以为是我的问题,后来发现我的显示屏驱动**IC不是GT9147.**** 附上链接 **https://downlo ...

  9. Linux驱动开发学习笔记-电容触摸屏驱动

    <电容触摸屏驱动框架> 电容触摸屏驱动其实是以下几种 linux 驱动框架的组合: ① IIC 设备驱动,因为电容触摸 IC 基本都是 IIC 接口的,因此大框架就是 IIC 设备驱动. ...

  10. STM32——触摸屏实验-电容型触摸屏-M4

    一.触摸屏 触摸屏(touch screen)又称为"触控屏"."触控面板",是一种可接收触头等输入讯号的感应装置.作为一种新型的电脑输入设备,可以用来取代传统 ...

最新文章

  1. Oracle 11g 新特性 -- Transparent Data Encryption (透明数据加密TDE) 增强 说明
  2. java面向对象中的抽象,类与对象
  3. 汉字与区位码(2) - 分析
  4. 【RBM】代码学习--DeepLearningToolBox
  5. 简单又实用的MRP手机平台下软件及游戏破解方法
  6. sai在别的图层复制图片后粘贴到新的图层中怎么调整图片尺寸?
  7. 计算机软件的著作权和专利权法律保护资料
  8. android地图定位到海洋,如何利用卫星导航技术进行高精度海洋测绘定位
  9. Ubuntu14.04搭建LXR本地服务器阅读Linux内核代码
  10. 51单片机使用12M晶振串口乱码问题
  11. 广告联盟的几大防作弊技术
  12. 随意发表见解易成无效表达
  13. android rootfs 编译,android rootfs
  14. linux安装vim plug,VIM 插件管理工具 vim-plug 简明教程
  15. 原创 | 连面拼多多、美团、头条、快手后给大家划下重点
  16. 阿里P8大佬的860页分布式微服务笔记,改变你对架构的认知
  17. java hh24miss_时间日期转换工具类,获取当前时间YYYYMMDD24HHMISS、YYYYMMDDHHMISS
  18. Windows常用DOS(cmd)目录命令
  19. OSMO ACTION 电池管家 黄灯什么意思
  20. 编译必装-DXSDK_Mar09安装详细教程

热门文章

  1. 2016服务器系统配置网站,Server 2016服务器操作系统中配置NIC组合
  2. linux上命令调用smplayer,Linux播放器——RedHat下MPlayer和SMPlayer的安装
  3. java 打砖块算法_打砖块java代码详细
  4. Android广告图片轮播控件
  5. 17.分段函数、绝对值函数以及幂指函数求导
  6. 武威市教师职称计算机考试,关于高级教师职称评定述职报告(精选5篇)
  7. ERDAS遥感影像处理-专题图制作
  8. CPU使用率查看方法
  9. 不要时刻忘记保持微笑
  10. matlab 超分辨率,matlab超分辨率