触摸屏硬件以及驱动简介

1.电容式触摸板的工作原理
电容屏要实现多点触控,靠的就是增加互电容的电极,简单地说,就是将屏幕分块,在每一个区域里设置一组互电容模块都是独立工作,所以电容屏就可以独立检测到各区域的触控情况,进电容技术触摸面板CTP(Capacity Touch Panel)是利用人体的电流感应进行工作的。电容屏是一块四层复合玻璃屏,玻璃屏的内表面和夹层各涂一层ITO(纳米铟锡金属氧化物),最外层是只有0.0015mm厚的矽土玻璃保护层,夹层ITO涂层作工作面,四个角引出四个电极,内层ITO为屏层以保证工作环境。当用户触摸电容屏时,由于人体电场,用户手指和工作面形成一个耦合电容,因为工作面上接有高频信号,于是手指吸收走一个很小的电流,这个电流分别从屏的四个角上的电极中流出,且理论上流经四个电极的电流与手指头到四角的距离成比例,控制器通过对四个电流比例的精密计算,得出位置。可以达到99%的精确度,具备小于3ms的响应速度。
2.电容屏模组的组成
触摸屏:也就是我们手触摸操作的透明部分;
触摸IC:当电容屏触摸到时,要解析到触点的位置坐标,就是通过这颗芯片去计算处理的。
1、电容式触摸屏的类型主要有两种:
(1)、表面电容式: 表面电容式利用位于四个角落的传感器以及均匀分布整个表面的薄膜,有一个普通的ITO层和一个金属边框,当一根手 指触摸屏幕时,从板面上放出电荷,感应在触 屏 的四角完成,不需要复杂的ITO图案;
(2)、投射式电容: 采用一个或多个精心设计,被蚀烛的ITO,这些 ITO层通过蛀蚀形成多个水平和垂直电极,采用成行/列交错同时带有传感功能的独立芯片。现在平板电脑、手机、车载等多用投射式电容,所以我们后面分析表明投射式电容的构成。
投射电容的轴坐标式感应单元矩阵 :轴坐标式感应单元分立的行和列,以两个交叉的滑条实现 X轴滑条 Y轴滑条 检测每一 格感应单元的电容变化。(示意图中电容,实际为透明的)
2、电容触摸屏分辨率,通道数;
上图所示,X,Y轴的透明电极电容屏的精度、分辨率与X、Y轴的通道数有关,通道越多,分辨率越高。
4.内核中触摸屏的驱动
以下记录在调试过程遇到的与驱动有关的几个问题,本次分析以FT5436当前版本驱动为示例:
(1)中断速率过高,具体表现为与固件中设置的报点速率不相符;
经过分析发现是驱动中做了如下设置:
Focaltech_core.c:
err = request_threaded_irq(client->irq, NULL, fts_ts_interrupt,
pdata->irq_gpio_flags | IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
client->dev.driver->name, data);
pdata->irq_gpio = of_get_named_gpio_flags(np, “focaltech,irq-gpio”, 0, &pdata->irq_gpio_flags);

msm8917-pmi8937-qrd-sku5.dtsi:
focaltech,irq-gpio = <&tlmm 65 0x2008>;/active low level-sensitive/
按照上述代码的设置在low && falling均触发内核中断,所以中断触发次数成倍增长;
(2)内核CTP两种报点协议 A&B
<1>A & B协议简单介绍
如果从设备获取的当前数据与上一个数据相同,我们有必要再上报当前的数据吗?如果我们不管两次数据是否一致都上报,那就是A协议;如果我们不选择上报,那么既然需要比较,总需要把上次数据存起来,slot(位置,槽;两层含义:位置,容器)就是做的这个事情
,显然这个就是Slot(B)协议。
A协议:
不会使用SLOT,多指处理中,它的报点序列如下,没一个序列都以input_report_***函数实现:
通过getevent获取的一个点的上报event:
BTN_TOUCH DOWN
ABS_MT_TRACKING_ID 00000000 //这个ID是无效的;
ABS_MT_PRESSURE 0000003f
ABS_MT_TOUCH_MAJOR 00000006
ABS_MT_POSITION_X 00000147
ABS_MT_POSITION_Y 000001e7
SYN_MT_REPORT 00000000//系统以SYN_MT_REPORT为一个点的信息的结尾
SYN_REPORT 00000000 //以SYN_REPORT为一次事件的结尾;
在多指触摸的时候,android的中间件部分每收到一次SYN_MT_REPORT的形成一个点信息,收到一个点后并不会立即处理,而是一个时间完成之后才处理,SYN_REPORT就是这个事件结束的标志

B协议:
没有SYN_MT_REPORT,利用ABS_MT_TRACKING_ID来跟踪当前点属于那一条线。当前序列中某点的ID值,如果与前一次序列中某点的ID值相等,那么他们拘束于同一条线,应用层就不用再去计算这个点是哪条线上了;如果按下并一直按同一个点,那么input子系统就会做个处理来屏蔽你上下两次相同点,减少IO负担。协议B明显优越于协议A,但是协议B需要硬件支持,ID值并不是随便赋值的,而是硬件上跟踪了点的轨迹,比如按下一个点硬件就会跟踪这个点的ID,只要不抬起上报的点都会和这个ID相关。
通过getevent获取的一个点的上报event:
EV_ABS ABS_MT_TRACKING_ID 0000000a
EV_ABS ABS_MT_TOUCH_MAJOR 00000006
EV_ABS ABS_MT_PRESSURE 0000007f
EV_ABS ABS_MT_POSITION_X 000001e4
EV_ABS ABS_MT_POSITION_Y 00000327
EV_KEY BTN_TOUCH DOWN
EV_SYN SYN_REPORT 00000000 rate 0
EV_ABS ABS_MT_TRACKING_ID ffffffff
EV_KEY BTN_TOUCH UP
EV_SYN SYN_REPORT 00000000 rate 2
5.分析注册和上报数据的流程
注册 :
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(EV_ABS, input_dev->evbit);
__set_bit(BTN_TOUCH, input_dev->keybit);
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);

if FTS_MT_PROTOCOL_B_EN /和A相比多注册slot/

input_mt_init_slots(input_dev, pdata->max_touch_number, INPUT_MT_DIRECT);

else

input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 0x0f, 0, 0);

endif

input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->x_min, pdata->x_max, 0, 
0);
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min, pdata->y_max, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 0xFF, 0, 0);

if FTS_REPORT_PRESSURE_EN

input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);

endif

如果注册了ABS_MT_PRESSURE,上报时就要上报ABS_MT_PRESSURE。
上报:
Protocol A:
for (i = 0; i < event->touch_point; i++)
{
if (event->au8_touch_event[i] == FTS_TOUCH_DOWN || event->au8_touch_event[i] == FTS_TOUCH_CONTACT)
{
input_report_abs(data->input_dev,ABS_MT_TRACKING_ID,event->au8_finger_id[i]);

if FTS_REPORT_PRESSURE_EN

        input_report_abs(data->input_dev, ABS_MT_PRESSURE, event->pressure[i]);

endif

        input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->area[i]);
        input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->au16_x[i]);
        input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->au16_y[i]);
        input_mt_sync(data->input_dev);

}
input_sync(data->input_dev);
Protocol B:
for (i = 0; i < event->touch_point; i++)
{
if (event->au8_finger_id[i] >= data->pdata->max_touch_number)
{
}
break;
input_mt_slot(data->input_dev, event->au8_finger_id[i]);//根据id注册一个slot

    if (event->au8_touch_event[i] == FTS_TOUCH_DOWN || event->au8_touch_event[i] == FTS_TOUCH_CONTACT)
    {
      input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true);//分配ABS_MT_TRACKING_ID
        input_report_abs(data->input_dev, ABS_MT_PRESSURE, event->pressure[i]);
        input_report_abs(data->input_dev,ABS_MT_TOUCH_MAJOR, event->area[i]);
        input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->au16_x[i]);
        input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->au16_y[i]);
        touchs |= BIT(event->au8_finger_id[i]);
        data->touchs |= BIT(event->au8_finger_id[i]);
        input_sync(data->input_dev);

}
6.过调试程中遇到的问题总结
(1)硬测标准(机台测试)不达标
具体表现如:准确度、正斜向线性度、反斜向线性度、唤醒延迟、两指识别距离等,此类问题基本都需要FAE配合更改;
(2)主观测试之边缘划线不直,线不贴边等,此问题也需要FAE进行更改。
(3)在调试过程偶遇TP卡住,失效,经分析有以下几种情况:
<1>报点速率过高,经分析代码中引入了两种触发中断的方式,falling & low同时产生了作用,导致中断触发次数过高,由于TP中断触发方式为FALLING,固只保留falling触发即可;
<2>在芯片内即TP 控制器的固件做报点率限制,也可限制上报速率;
<3>插入USB充电时,TP容易失效 ,充电时对TP的数据有干扰,造成数据不稳定,需要在固件中对TP做屏蔽干扰;

你可能感兴趣的:(Android-TP)