Linux嵌入式 驱动开发(多点电容触摸屏)
1.Linux下电容触摸屏驱动框架简介
多点触摸(MT)协议详解
电容触摸屏由以下几种Linux驱动框架组成的:
IIC设备驱动:以为电容触摸IC基本都是I2C接口,因此大框架式IIC设备驱动
中断驱动框架:通过中断引脚向Linux内核上报触摸信息
input子系统:屏幕的按下和抬起都是属于Linux的input子系统
这三个之前都学过了,所以最需要注意的就是input子系统下的多点电容触摸协议(MT协议)
MT协议分为A B 版本,
type A适用于触摸点不能被区分或者追踪,基本不用
type B适用于硬件追踪并能区分触摸点的触摸设备,此类型设备通过slot更新某一个触摸点信息,以下是type B执行的伪代码
//0.最开始需要先初始化MT的输入slots,input_mt_init_slots ABS_MT_SLOT 0 //1.上报ABS_MT_SLOT事件,此事件会告诉接收者当前正在更新的是哪个触摸点(slot),用input_mt_slot函数完成 ABS_MT_TRACKING_ID 45 //2.上报ABS_MT_TRACKING_ID事件,也就是给触摸点关联一个ID,用input_mt_report_slot_state函数完成 ABS_MT_POSITION_X x[0] //3.上报触摸点0的X轴坐标,用input_report_abs完成 ABS_MT_POSITION_Y y[0] ABS_MT_SLOT 1 //同触摸点0 ABS_MT_TRACKING_ID 46 ABS_MT_POSITION_X x[1] ABS_MT_POSITION_Y y[1] SYN_REPORT //4.当所有触摸点坐标都上传完毕以后就得发送SYN_REPORT事件,使用input_sync函数来完成 //如果追踪到的触摸点数量多于当前上报的数量,驱动程序使用 BTN_TOOL_TAP 事件来通 知用户空间当前追踪到的触摸点总数量,然后调用 input_mt_report_pointer_emulation 函数将 use_count 参数设置为 false。否则的话将 use_count 参数设置为 true,表示当前的触摸点数量
2.多点电容触摸驱动框架
1.I2C驱动框架
包括设备树匹配表,i2c驱动结构体,驱动出口入口函数
2.初始化触摸IC,中断,input子系统
初始化操作都是在probe里面完成的(初始化I2C,申请中断,input设备申请和初始化,初始化input和MT,注册input_dev)
3.上报坐标信息
(一会编写时详解)
3.实验程序编写
1.修改设备树
(这个真是个坑!!!!!!),先讲一下需要修改的东西,然后再讲一下需要注意的坑:
触摸芯片一共用到了4个IO,
一个复位IO,(这个在iomuxc下面)
一个中断IO, (这个在iomuxc_snvs下面)
I2C2的SCL和SDA (这个官方自己写过了)
然后再I2C2节点下面添加触摸芯片子节点,其中信息包括(属性,寄存器器件地址,所使用电气属性,中断IO对应的GPIO组,中断所使用的GPIO组的具体引脚,复位所对应的GPIO)
坑:
1.触摸芯片!!!需要注意自己的芯片的类型,因为看的文档是之前写的,所以已经更换了新款芯片,要根据新的触摸芯片设置寄存器的值。
2.注意检查复用问题。就是我们使用的引脚其它引脚不能再使用了,其中包括两点,一个是电气信息的复用,另一个就是有没有设备复用GPIO接口。
2.编写驱动
1.触摸芯片设备(设备节点,中断和复位IO,中断号,私有数据,input结构体,I2C设备结构体)
2.复位触摸芯片(设置触摸芯片的复位 IO 为高电平,防止芯片复位)
3.读取多个寄存器的值,写入多个寄存器的值,写一个寄存器的值(鉴于都是上节I2C的东西,这里不多说了)
4.触摸芯片中断服务函数
1.创建一个rdbuf[29]
这里先详细解释一下为何是29,首先触摸芯片这个寄存器是从0x02开始,0x02不存有数据,然后每六个寄存器属于一个坐 标,其中包含了x,y数据,以及触摸方式(手指或者笔等),但是这六个寄存器里面,只有前四个是有用的,后面两个作为保 存,所以:
我们一共最多支持五点触摸,前四个点的寄存器+加上最后一个点的前四个寄存器+最开始的0x02 = 4 * 6 + 4 + 1 = 29
2.读取多个寄存器的值
3.for循环这些值
{
获取触摸类型
获取x,y
获取信息表示是哪个触摸点
input_mt_slot(multidata->input, id);//上报当前正在使用哪个接触点
input_mt_report_slot_state(multidata->input, MT_TOOL_FINGER,down);//为它分配一个ID
input_report_abs(multidata->input, ABS_MT_POSITION_X, x);//上报xy
input_report_abs(multidata->input, ABS_MT_POSITION_Y, y);
input_mt_report_pointer_emulation(multidata->input, true);//上面协议详解有
input_sync(multidata->input);//上报SYN_REPORT事件
}
5.中断初始化(申请中断gpio,申请中断)
PS:如果我们申请的函数前面增加了devm的话,那么申请到的资源在使用结束后会由系统自动释放
同时这里增加了中断线程化得概念:中断线程化以后中断将作为内核线程运行,而且也可以被赋予不同的优先级,任务的优先级可能比中断线程的优先级高,这样做的目的就是保证高优先级的任务能被优先处理
6.probe
1.获取设备树中得中断和复位引脚
2.复位触摸芯片
3.初始化中断
4.初始化复位芯片
5.input设备注册
7.remove(input设备注销)
8.设备树匹配表,i2c驱动结构体,驱动出口入口函数
4.测试
这个玩意不用写测试程序,加载驱动后会出现新的设备
hexdump /dev/input/event2执行后,触摸屏幕后就会有信息显示
5.tslib
一个开源软件,用来测试屏幕有没有问题,电容屏不用测,电阻屏需要测
#Linux##C/C++##C++工程师##嵌入式工程师##嵌入式#