android下触摸屏驱动实现
android下触摸屏驱动实现
最近学习了电容触摸屏的驱动及其上层工作原理,拿出来和大家分享!转]Android触摸屏校准程序的实现一,校准的触摸算法如下:触摸屏校准通用方法。
(XL, YL是显示屏坐标,XT, YT是触摸屏坐标,)XL = XT*A+YT*B+CYL = XT*D+YT*E+F由于具体计算是希望是整数运算,所以实际中保存的ABCDEF为整数,而增加一个参数Div XL = (XT*A+YT*B+C) / DivYL = (YT*D+YT*E+F) / DivTSLIB把以上的7个参数ABCDEF Div 保存在pointercal 文件中。
不校准的数据:A=1, B=0, C=0, D=0, E=1, F=0, Div=1A B C D E F Div-411 37818 -3636780 -51325 39 47065584 65536二,Android 事件处理机制android 事件的传入是从EventHub开始的,EventHub是事件的抽象结构,维护着系统设备的运行情况(设备文件放在/dev/input里),设备类型包括Keyboard、TouchScreen、TraceBall。
它在系统启动的时候会通过open_device方法将系统提供的输入设备都增加到这个抽象结构中,并维护一个所有输入设备的文件描述符,如果输入设备是键盘的话还会读取/system/usr/keylayout/目录下对应键盘设备的映射文件(修改./development/emulator/keymaps /qwerty.kl来改变键值的映射关系),另外getEvent方法是对EventHub中的设备文件描述符使用poll操作等侍驱动层事件的发生,如果发生的事件是键盘事件,则调用Map函数按照映射文件转换成相应的键值并将扫描码和键码返回给KeyInputQueue.frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp根据事件的类型以及事件值进行判断处理,从而确定这个事件对应的设备状态是否发生了改变并相应的改变对这个设备的描述结构InputDevice。
基于Android4.X平台的触摸屏技术方案探讨
( 2 ) 电容式 触控优 点是 触控顺滑、 支持多点触摸 、 敏感度 更 高、 定位 更准确、响应速 度更快、 显示更清晰、 透 光率较高、 整 体功耗更低 , 高硬度的接触面, 无需按压, 使用寿命较 长。 故常用
n d r o i d 框架层源自A c T i v i t y M a n a g e r 传 递给A c t i v i t y 中的系 于高端市场 。 电容式触 控 的缺 点是精度不足 , 不支持手写笔操 A 统方 法 , 然后执 行相应 的系 统方 法更 新V i e w 类 ,消息传 递 至 控, 且有漂移存在、 面板的成本相对较高、 实现 大尺寸应 用较 困
2 常用 的触 摸屏 分 类
是触屏, A n d r o i d 考虑触摸 的主要是响应效果 , 着重优化用户触
A n d r o i d 对 3种硬件设备的用户事件消息响应: 触摸响 ( 1 ) 电阻式 触摸屏俗 称 “ 软 屏” , 它依靠 感知压力来 定位 的 摸响应 。 O N T o u e h ) 、 按键响应( o n K e y ) 和轨迹球 ( T r a c k b a l 1 ) 。 原理 , 使用指 甲、 手写笔等 尖锐、 绝缘物 体可 以进行操控 , 塑料 应(
触屏 的动作取代传统的键 盘与鼠标输入 , 并借助液 晶来 显示画 和处理 的工作, 实现人机 交互 。 人机交 互实质 上就是人与屏幕 面, 它在构建物 联终端 , 实现人机交互的最流行 的传感技术。 相应位 置上 的视 图控件 的交互。 A n d r o i d 系统的触摸屏几乎 全
讨TA n d r o i d平 台的触 摸技 术 实现 机制 , 最 后讲 述 用A n d r o i d 4 . X打造 新一代 平台的触摸 屏。 适应 未来物 联 网时代的应用要 求。 关键 词: 触 摸 屏; 触摸 响应 ; 多屏互动
4_Focaltech Android平台Driver介绍_v1.0
编译驱动
编译驱动主要是修改相关的makefile和Kconfig两个文件,其中Kconfig是配置文件。 • 在makefile中加入以下代码:
#obj-$(CONFIG_TOUCHSCREEN_FT5X0X) += ft5x06.o
#ft5x06-objs += ft5x06_ts.o ft5x06_ex_fun.o focaltech_ctl.o • 在Kconfig文件加入以下代码:
Android应用层APK的使用
●
应用层的APK主要有两个工具FT_Test_Platform.apk和FTS_Upgrade.apk 分别有两个版本,一个i2c读写版本,一个是ft_rw_iic_drv版本。两个版本 在应用上没有任何区别,只是中间层的.so不一样而已。 如果是i2c读写的,需要正确的设置i2c index,如果不是的,可以不用设置。 针对不同的芯片类型需要设置一下,如6x06需要设置成FTS-18Bytes协议 的,其它的用Standard IIC。同时要选择相应的IC Type。 相应的设置都正确后,就可以在整机上查看 rawdata、diffdata、 upgrade和读写寄存器等。
input_report_abs(input_dev, ABS_MT_TRACKING_ID,id);
●
B协议中用input_mt_slot(input_dev, id)。 A协议中报事件用
input_report_abs(input_dev, ABS_MT_PRESSURE, event); event>0表示有触摸, event=0表示无触摸。
Android 2.x与4.x在Input上的区别
●
B协议中报事件用 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, btouch); btouch 为true表示有触摸,btouch为false表示无触摸。 A协议中每报一个点的信息都需要调用 input_mt_sync(input_dev), 最后还需要再调用input_sync(input_dev),B协议中只需要最后调 用input_sync(input_dev)即可。 主要的区别就在这里。
安卓操作系统添加多点触摸设备支持特性内核配置步骤V2.0
研发部受控文件图号:ZAN1604-2标题:安卓操作系统添加多点触摸设备支持特性内核配置步骤部门:研发部版本:V2.0日期:2016年3月2日修改安卓源码目录Android\x.x\kernel\drivers\hid中的hid-ids.h头文件,添加如下定义:如图1所示:Fig 1 hid-ids.h 文件截图#define USB_VENDOR_ID_ZAAG_VID_V3V50xAAEC #define USB_DEVICE_ID_ZAAG_PID_V3V50xB0D0#define USB_VENDOR_ID_ZAAG_VID_V60xAAEC #define USB_DEVICE_ID_ZAAG_PID_V60x0820 #define USB_VENDOR_ID_ZAAG_HID_VID_V6 0xAAEC #define USB_DEVICE_ID_ZAAG_HID_PID_V60x0922 #define USB_VENDOR_ID_ZAAG_HID_VID_V7 0x202E #define USB_DEVICE_ID_ZAAG_HID_PID_V70x0006修改上述目录下的hid-multitouch.c中的mt_devices[]数组,如图2所示:Fig 2 hid-multitouch.c文件截图检查上述目录下的hid-core.c中的hid_have_special_driver[]数组,如图3所示:Fig 3 hid-core.c文件截图确认该数组中包括如图4中红框内所示的两个成员变量,如果没有,请添加完整:Fig 4 数组成员变量截图修改make menuconfig中的选项,把多点触摸驱动编译进内核:make menuconifgDevice DriversHID DevicesSpecial HID driversHID Multitouch panels如图5所示: Fig 5 make menuconfig 修改截图罗益峰研发部受控文件版本控制表。
触摸屏驱动原理
触摸屏驱动原理
触摸屏驱动原理基于电容变化的测量原理。
触摸屏是由一层导电膜覆盖在玻璃或塑料表面上形成的,平常不产生电流。
当手指或其他物体触摸到屏幕上时,触摸屏会感应到电流的变化。
触摸屏驱动器通过相应的算法来检测这些电流变化,并将其转化为对触摸点位置的坐标数据。
常见的触摸屏驱动技术有四种:电容式、电阻式、表面声波和红外线。
1. 电容式触摸屏驱动原理:
电容式触摸屏采用两层导电板构成电容,在不触摸屏幕时,电容平衡。
当手指触摸到屏幕上时,由于人体电容的存在,导致电容发生变化。
触摸屏驱动器会检测到变化的电容值,并通过测量和计算来确定触摸点位置。
2. 电阻式触摸屏驱动原理:
电阻式触摸屏由两层导电薄膜构成,中间夹有绝缘层。
当触摸屏被触摸时,导电薄膜会接触到一起,形成电阻的变化。
触摸屏驱动器通过测量电阻的变化来确定触摸点位置。
3. 表面声波触摸屏驱动原理:
表面声波触摸屏利用超声波传感器将声波传输到触摸屏表面。
当有物体触摸到触摸屏时,声波会被打断并反射回传感器。
触摸屏驱动器通过测量声波传输和反射时间的差异来确定触摸点位置。
4. 红外线触摸屏驱动原理:
红外线触摸屏在触摸屏表面周围设置红外线发射器和接收器,形成网状的红外线检测区域。
当有物体触碰到触摸屏时,会阻挡红外线的传输。
触摸屏驱动器会通过检测到的红外线被阻挡的位置来确定触摸点位置。
不同类型的触摸屏驱动原理各有优缺点,适用于不同场景和需求。
但无论采用哪种触摸屏驱动技术,其基本原理都是通过检测电容、电阻、声波或红外线的变化来确定触摸点位置。
基于DragonBoard 410c开发板的触摸屏驱动编写
基于DragonBoard 410c开发板的触摸屏驱动编写前言:让大家初步了解对高通MSM8916平台的输入子系统的实现,给大家提供Dragon Board 410c平台开发输入系统设备的思路。
(如:按键设备、触摸屏、轨迹球等)在高通MSM8916平台中,具有触摸屏、轨迹球和简单按键功能,这些功能是由Android 系统内中的驱动程序实现的,并且需要用户空间的内容来协助实现。
一、触摸屏驱动编写高通MSM8916平台的触摸屏驱动程序的实现文件是drivers/input/touchscreen/synapTIcs_i2c_rmi4.c,此文件的核心是函数synapTIcs_ts_probe(),在该函数中需要进行触摸屏工作模式的初始化,对作为输出设备的触摸屏驱动在Linux平台下的设备名注册,同事初始化触摸时间触发时引起的中断操作。
此函数的实现代码如下:staTIc int synapTIcs_rmi4_probe(struct i2c_client *client,const struct i2c_device_id *dev_id){int retval = 0;unsigned char ii;unsigned char attr_count;struct synaptics_rmi4_f1a_handle *f1a;struct synaptics_rmi4_fn *fhandler;struct synaptics_rmi4_fn *next_fhandler;struct synaptics_rmi4_data *rmi4_data;struct synaptics_rmi4_device_info *rmi;struct synaptics_rmi4_platform_data *platform_data =client-dev.platform_data;struct dentry *temp;if (!i2c_check_functionality(client-adapter,I2C_FUNC_SMBUS_BYTE_DATA)){dev_err(client-dev,%s: SMBus byte data not supported\n,__func__);return -EIO;}if (client-dev.of_node) {platform_data = devm_kzalloc(client-dev,sizeof(*platform_data),GFP_KERNEL);if (!platform_data) {dev_err(client-dev, Failed to allocate memory\n);return -ENOMEM;}retval = synaptics_rmi4_parse_dt(client-dev, platform_data);if (retval)return retval;} else {platform_data = client-dev.platform_data;}if (!platform_data) {dev_err(client-dev,%s: No platform data found\n,__func__);return -EINV AL;}rmi4_data = kzalloc(sizeof(*rmi4_data) * 2, GFP_KERNEL);if (!rmi4_data) {dev_err(client-dev,%s: Failed to alloc mem for rmi4_data\n,__func__);return -ENOMEM;}rmi = (rmi4_data-rmi4_mod_info);rmi4_data-input_dev = input_allocate_device();//创建设备if (rmi4_data-input_dev == NULL) {dev_err(client-dev,%s: Failed to allocate input。
MTK6515 软件驱动配置教程
MTK6515 android打版软件配置∙ 1 一、配置GPIO∙ 2 二、配置emmc3 三、配置LCMo 3.1 1、增加LCM驱动文件o 3.2 2、配置驱动文件o 3.3 3、配置背光4 四、配置touch panelo 4.1 1、通过dct配置gipo及其对应的别名o 4.2 2、配置mediatek/config/bbk15_td_ics/ProjectConfig.mko 4.3 3、增加tp 驱动目录及驱动文件o 4.4 4、配置刚刚添加的驱动文件o 4.5 5、配置pmic供电∙ 5 五、注意事项6 六、附录o 6.1 1、i2C配置的两种方法o 6.2 2、将触屏配置成点触模式一、配置GPIO通过工具:mediatek/source/dct/DrvGen.exe配置并替换dws文件:mediatek/custom/bbk75_emmc_gb2/kernel/dct/dct/codegen.dws∙配置GPIO的主要目的是使系统在uboot,甚至preloader阶段时保持BB管脚的状态;在kernel启动阶段加载驱动模块时,不少驱动是会重新设置其用的gpio功能的,所以这一阶段并不要求非常严格,然而同时也必须要保证gpio所配置的初始状态不会影响到系统的启动,如死机、复位等等。
二、配置emmc1、在下面文件的MTK6575标签栏添加对应的flash芯片型号信息:mediatek/build/tools/emigen/MT6575/MemoryDeviceList_MT6575.xls2、从以下文件获取flash芯片对应的序号(从第1列为0,开始数,如到第L列则为11):mediatek/build/tools/ptgen/emmc_region.xls3、mediatek/custom/bbk15_td_ics/preloader/inc/custom_MemoryDevice.h#define BOARD_ID LENOVO75#define CS_PART_NUMBER[0] KMSJS000KM_B308将上面的宏更改为MemoryDeviceList_MT6575.xls中对应的内容4、mediatek/config/bbk15_td_ics/ProjectConfig.mk将EMMC_CHIP更改为第2步获取的数值,如EMMC_CHIP = 11。
Android多点触摸的实现——1.6patch(一)
Android多点触摸的实现——1.6patch(一)第一章摘要在Linux内核支持的基础上,Android在其 2.0源码中加入多点触摸功能。
由此触摸屏在Android的frameworks被完全分为2种实现途径:单点触摸屏的单点方式,多点触摸屏的单点和多点方式。
第二章软件位在Linux的input.h中,多点触摸功能依赖于以下几个主要的软件位:………………………..#define SYN_REPORT 0#define SYN_CONFIG 1#define SYN_MT_REPORT 2………………………...#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ …………………………在Android中对应的软件位定义在RawInputEvent.java中:…………………..public class RawInputEvent {……………….public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;………………..public static final int ABS_MT_TOUCH_MAJOR = 0x30;public static final int ABS_MT_TOUCH_MINOR = 0x31;public static final int ABS_MT_WIDTH_MAJOR = 0x32;public static final int ABS_MT_WIDTH_MINOR = 0x33;public static final int ABS_MT_ORIENTATION = 0x34;public static final int ABS_MT_POSITION_X = 0x35;public static final int ABS_MT_POSITION_Y = 0x36;public static final int ABS_MT_TOOL_TYPE = 0x37;public static final int ABS_MT_BLOB_ID = 0x38;………………….public static final int SYN_REPORT = 0;public static final int SYN_CONFIG = 1;public static final int SYN_MT_REPORT = 2;………………..在Android中,多点触摸的实现方法在具体的代码实现中和单点是完全区分开的。
ft5x06触摸屏驱动实现分析
触摸屏驱动触摸屏三种状态•active•monitor•hibernate 我们主要是需要通过serial interface建立与其的通讯接口,如write reg 、read reg等接口。
通过芯片使用手册提供给我们的寄存器信息,对芯片进行信息读取或配置。
i2c-core•总线驱动方法•i2c_smbus_write_block_data•i2c_smbus_read_i2c_block_data •i2c_smbus_read_byte•i2c_smbus_write_byte•设备注册、注销方法•i2c_register_driver•i2c_del_driver设备注册static struct i2c_board_info touchscreen_ft5x06_info[] = { {I2C_BOARD_INFO("ft5x0x_ts", 0x38),.platform_data = &touchscreen_ft5x06_pdata,.irq = MSM_GPIO_TO_INT(FT5X06_INT), }};static struct i2c_registry msm8x60_i2c_devices[] __initdata = { ..#ifdef CONFIG_TOUCHSCREEN_EDT_FT5X06{I2C_SURF | I2C_FFA | I2C_FLUID,MSM_GSBI3_QUP_I2C_BUS_ID,touchscreen_ft5x06_info,ARRAY_SIZE(touchscreen_ft5x06_info),},#endif}•msm8x60_init --》register_i2c_devices--》i2c_register_board_info•int __init i2c_register_board_info(int busnum,struct i2c_board_info const *info, unsigned len)•注册前面的数组中的设备驱动注册•module_init(ft5x0x_ts_init);编译过程中,宏定义module_init(ft5x0x_ts_init) 将把我们的模块驱动初始化函数指针添加到.initcall6.init 中。
s3c2440触摸屏驱动(针对android版)
s3c2440触摸屏驱动(针对android版)s3c2440 触摸屏驱动(针对android版)和原来的触摸屏驱动区别不是很⼤,增加了report函数来将事件发送到应⽤层。
驱动结构:很简单的字符设备+平台设备驱动,总的结构来说,主要四个部分构成:proberemoveresumesuspend⼯作机制则是注册设备,然后发⽣ts按下事件后产⽣ts中断以及adc中断,获得按下坐标。
没有读写函数,重点就是在两个中断处理函数上。
1,平台设备架构部分分析:probe函数:流程:ts基址的重映射->获得并启动时钟->ADCCON、ADCDLY、ADCTSC的初始化->初始化input设备完善ts结构体->建⽴ts_filter_chain->申请中断->注册input设备(2.6.27后为event0不再是ts0)。
static int __init s3c2410ts_probe(struct platform_device *pdev){int rc;struct s3c2410_ts_mach_info *info;struct input_dev *input_dev;int ret = 0;dev_info(&pdev->dev,"Starting\n");info =(struct s3c2410_ts_mach_info*)pdev->dev.platform_data;//获得平台设备数据if(!info){dev_err(&pdev->dev,"Hm... too bad: no platform data forts\n");return-EINVAL;}#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUGprintk(DEBUG_LVL "Entering s3c2410ts_init\n");#endifadc_clock = clk_get(NULL,"adc");if(!adc_clock){dev_err(&pdev->dev,"failed to get adc clock source\n");return-ENOENT;}clk_enable(adc_clock);#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUGprintk(DEBUG_LVL "got and enabled clock\n");#endifbase_addr = ioremap(S3C2410_PA_ADC,0x20);//将PA_ADC寄存器重映射到内存上if(base_addr ==NULL){dev_err(&pdev->dev,"Failed to remap register block\n"); ret =-ENOMEM;goto bail0;}/* If we acutally are a S3C2410: Configure GPIOs */if(!strcmp(pdev->name,"s3c2410-ts"))s3c2410_ts_connect();//初始化相关gpio⼝if((info->presc & 0xff)> 0)writel(S3C2410_ADCCON_PRSCEN |S3C2410_ADCCON_PRSCVL(info->presc&0xFF),base_addr + S3C2410_ADCCON);elsewritel(0, base_addr+S3C2410_ADCCON);/* Initialise registers */if((info->delay & 0xffff)> 0)writel(info->delay & 0xffff, base_addr + S3C2410_ADCDLY);writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC);/* Initialise input stuff */memset(&ts, 0,sizeof(struct s3c2410ts));input_dev = input_allocate_device();if(!input_dev){dev_err(&pdev->dev,"Unable to allocate the input device\n");ret =-ENOMEM;}//初始化input设备ts.dev = input_dev;ts.dev->evbit[0]= BIT_MASK(EV_SYN)| BIT_MASK(EV_KEY)|BIT_MASK(EV_ABS);ts.dev->keybit[BIT_WORD(BTN_TOUCH)]= BIT_MASK(BTN_TOUCH);input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0);input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0);input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0);ts.dev->name = s3c2410ts_name;ts.dev->id.bustype = BUS_RS232;ts.dev->id.vendor = 0xDEAD;ts.dev->id.product = 0xBEEF;ts.dev->id.version = S3C2410TSVERSION;ts.state = TS_STATE_STANDBY;//设置ts状态为就绪ts.event_fifo = kfifo_alloc(TS_EVENT_FIFO_SIZE, GFP_KERNEL, NULL);//为event队列申请内存空间if(IS_ERR(ts.event_fifo)){ret =-EIO;goto bail2;}/* create the filter chain set up for the 2 coordinates we produce */ts.chain = ts_filter_chain_create(pdev, info->filter_config, 2);//针对android的,建⽴filter_chainif(IS_ERR(ts.chain))goto bail2;ts_filter_chain_clear(ts.chain);/* Get irqs */if(request_irq(IRQ_ADC, stylus_action, IRQF_SAMPLE_RANDOM,"s3c2410_action", ts.dev)){dev_err(&pdev->dev,"Could not allocate ts IRQ_ADC !\n"); iounmap(base_addr);goto bail3;}if(request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM, "s3c2410_action", ts.dev)){dev_err(&pdev->dev,"Could not allocate ts IRQ_TC !\n"); free_irq(IRQ_ADC, ts.dev);iounmap(base_addr);ret =-EIO;goto bail4;}dev_info(&pdev->dev,"Successfully loaded\n");/* All went ok, so register to the input system */rc = input_register_device(ts.dev);if(rc){ret =-EIO;goto bail5;}return 0;bail5:free_irq(IRQ_TC, ts.dev);free_irq(IRQ_ADC, ts.dev);clk_disable(adc_clock);iounmap(base_addr);disable_irq(IRQ_TC);bail4:disable_irq(IRQ_ADC);bail3:ts_filter_chain_destroy(ts.chain);kfifo_free(ts.event_fifo);bail2:input_unregister_device(ts.dev);bail1:iounmap(base_addr);bail0:return ret;}remove:就是probe的逆运算,static int s3c2410ts_remove(struct platform_device *pdev) {disable_irq(IRQ_ADC);disable_irq(IRQ_TC);free_irq(IRQ_TC,ts.dev);free_irq(IRQ_ADC,ts.dev);if(adc_clock){clk_disable(adc_clock);clk_put(adc_clock);adc_clock =NULL;}input_unregister_device(ts.dev);iounmap(base_addr);ts_filter_chain_destroy(ts.chain);kfifo_free(ts.event_fifo);return 0;}resume与suspend函数可有可⽆,完成触摸屏的激活和挂起,2,中断处理分析:三种模式转换过程:等待down中断模式->x,y连续坐标转换模式->等待up中断模式->等待down中断模式->..两个中断的发⽣:触摸屏按下,发⽣ts中断,开始ad转换,ad转换结束,发⽣adc中断。
史上最详细的触摸屏驱动分析
/*触摸屏驱动程序及分析*/#include <linux/errno.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/init.h>#include <linux/serio.h>#include <linux/delay.h>#include <linux/platform_device.h>#include <linux/clk.h>#include <asm/io.h>#include <asm/irq.h>#include <plat/regs-adc.h>#include <mach/regs-gpio.h>/* For ts.dev.id.version */#define S3C2410TSVERSION 0x0101#define WAIT4INT(x) (((x)<<8) | \S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \S3C2410_ADCTSC_XY_PST(3))#define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))static char *s3c2410ts_name = "s3c2410 TouchScreen";static struct input_dev *dev;static long xp;static long yp;static int count;extern struct semaphore ADC_LOCK;static int OwnADC = 0;static void __iomem *base_addr;/*把GPG12~15 设置为保留模式*/static inline void s3c2410_ts_connect(void){s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);}/*求坐标的平均值,报告坐标,当还是按下状态时,再次调用ADC转换,如果抬起则让触摸屏设置为等待中断模式*/static void touch_timer_fire(unsigned long data){unsigned long data0;unsigned long data1;int updown;/*用于读取ADCDA T数据*/data0 = ioread32(base_addr+S3C2410_ADCDA T0);data1 = ioread32(base_addr+S3C2410_ADCDA T1);/*判断是按下还是送开*/updown = (!(data0 & S3C2410_ADCDA T0_UPDOWN)) && (!(data1 & S3C2410_ADCDA T0_UPDOWN));/*如果按下*/if (updown) {if (count != 0) {/*转换四次后进行事件汇报*/long tmp;tmp = xp;xp = yp;yp = tmp;/* 求平均值*/xp >>= 2;yp >>= 2;/* 报告x、y的绝对坐标值*/input_report_abs(dev, ABS_X, xp);input_report_abs(dev, ABS_Y, yp);/* 报告按键事件,键值为1(代表触摸屏对应的按键被按下) */input_report_key(dev, BTN_TOUCH, 1);/* 报告触摸屏的状态,1表明触摸屏被按下*/input_report_abs(dev, ABS_PRESSURE, 1);/* 同步*/input_sync(dev);}xp = 0;yp = 0;count = 0;/*自动X/Y轴坐标转换模式的设置,自动地进行X轴和Y轴的转换操作,随后产生相应的INT_ADC中断通知转换完毕*/iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);/*如果还没有启动ADC或者ADC转换四次完毕后则启动ADC*/iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);} else {count = 0;/* 如果触摸笔是弹起状态,则提出报告,并让触摸屏处于等待触摸的阶段*//* 报告按键事件,键值为0(代表触摸屏对应的按键被释放) */input_report_key(dev, BTN_TOUCH, 0);/* 报告触摸屏的状态,0表明触摸屏未被按下*/input_report_abs(dev, ABS_PRESSURE, 0);/*同步*/input_sync(dev);/* 设置触摸屏为等待中断模式,等待触摸笔按下*/iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);if (OwnADC) {OwnADC = 0;up(&ADC_LOCK);}}}static struct timer_list touch_timer =TIMER_INITIALIZER(touch_timer_fire, 0, 0);/*当触摸按下时,产生INT_TC中断,会进入到stylus_updown中断处理函数当有中断产生时,会使OwnADC=1,然后读取数据,并判断是抬起还是按下,按下则调用touch_timer_fire()函数,抬起则释放锁,并使OwnADC=0*/static irqreturn_t stylus_updown(int irq, void *dev_id){unsigned long data0;unsigned long data1;int updown;/*注意在触摸屏驱动模块中,这个ADC_LOCK的作用是保证任何时候都只有一个驱动程序使用ADC的中断线,因为在mini2440的adc模块中也会使用到ADC,这样只有拥有了这个锁,才能进入到启动ADC代码部分,注意尽管LDD3中说过信号量因为休眠不适合使用在ISR中,但down_trylock是一个例外,它不会休眠*/if (down_trylock(&ADC_LOCK) == 0) {OwnADC = 1;//获取ADC转换的数据data0 = ioread32(base_addr+S3C2410_ADCDA T0);data1 = ioread32(base_addr+S3C2410_ADCDA T1);updown = (!(data0 & S3C2410_ADCDA T0_UPDOWN)) && (!(data1 & S3C2410_ADCDA T0_UPDOWN));/*判断目前触摸笔的状态updown = 1 触摸笔按下;updown = 0 触摸笔弹起;*/if (updown) {//当触摸笔按下时touch_timer_fire(0); /*这是一个定时器函数,当然在这里只是作为普通函数调用,用来启动ADC*/} else {//当笔弹起时,释放锁OwnADC = 0;up(&ADC_LOCK);}}return IRQ_HANDLED;}/*INT_ADC 中断处理函数读取四次AD转换的值,然后求和,超过四次后执行touch_time_fire()函数*/static irqreturn_t stylus_action(int irq, void *dev_id){unsigned long data0;unsigned long data1;if (OwnADC) {data0 = ioread32(base_addr+S3C2410_ADCDA T0);data1 = ioread32(base_addr+S3C2410_ADCDA T1);xp += data0 & S3C2410_ADCDA T0_XPDA TA_MASK;yp += data1 & S3C2410_ADCDA T1_YPDA TA_MASK;count++;if (count < (1<<2)) { /*如果小于四次重新启动ADC转换*/iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);iowrite32(ioread32(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_ENABLE_STAR T, base_addr+S3C2410_ADCCON);} else {/*如果超过四次,启动1个时间滴答的定时器,停止ADC,然后调用定时器处理函数touch_timer_fire进行数据上报*/mod_timer(&touch_timer, jiffies+1);iowrite32(WAIT4INT(1), base_addr+S3C2410_ADCTSC);}}return IRQ_HANDLED;}static struct clk *adc_clock;/*初始化主要做的工作为:1、获取ADC时钟并使时钟使能2、申请IO虚拟地址3、设置ADCCON,ADCDLY,ACDTSC4、申请input设备5、设置input事件类型,事件值,X,Y坐标的最大最小值6、中断申请7、注册input设备*/static int __init s3c2410ts_init(void){struct input_dev *input_dev; //定义input结构体指针/*获取时钟,触摸屏是挂载在APB BUS上的外围设备,需要时钟控制,见数据手册第7章*/adc_clock = clk_get(NULL, "adc");if (!adc_clock) {//如果时钟获取失败时printk(KERN_ERR "failed to get adc clock source\n");return -ENOENT;}//时钟使能clk_enable(adc_clock);/*I/O内存不要直接进行访问的,最好对其进行映射*/base_addr=ioremap(S3C2410_PA_ADC,0x20);if (base_addr == NULL) {printk(KERN_ERR "Failed to remap register block\n");return -ENOMEM;}/* Configure GPIOs 把YPON,YMON,XPON,XMOND都设置成11,保留模式*/s3c2410_ts_connect();/*使能预分频和设置分频系数S3C2410_ADCCON_PRSCEN:使AD转换使能,是ADCCON的第14位PRSCENS3C2410_ADCCON_PRSCVL(0xFF):预分频系数,取值为0~255:,AD时钟=PCLK/(PRSCVL+1),且必须小于1/5的PCKL*/iowrite32(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF),base_addr+S3C2410_ADCCON);/*设置ADC延时,在等待中断模式下表示产生INT_TC的间隔时间,ADC转换周期等待定时器*/iowrite32(0xffff, base_addr+S3C2410_ADCDLY);/*ADCTSC = 0xd3 ,将触摸屏置为等待中断模式,等待触摸屏被按下产生INT_TC中断*/iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);/* 以下配置2.6内核划分出来的输入设备*//* 分配一个input输入设备*/input_dev = input_allocate_device();if (!input_dev) {//分配input输入设备不成功时printk(KERN_ERR "Unable to allocate the input device !!\n");return -ENOMEM;}dev = input_dev;/*evbit字段用来定义该输入设备可以支持的(产生和响应)的事件的类型,触摸屏设置为支持同步(EN_SYN)、按键(EN_KEY)、绝对坐标(EV_ABS)事件*/dev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);/* 设置所支持的按键(键值),触摸屏可以看成只有一个按键的设备*/dev->keybit[BITS_TO_LONGS(BTN_TOUCH)] = BIT(BTN_TOUCH);/* 设置绝对坐标x的最小最大值(0-0x3FF) */input_set_abs_params(dev, ABS_X, 0, 0x3FF, 0, 0);/* 设置绝对坐标y的最小最大值(0-0x3FF) */input_set_abs_params(dev, ABS_Y, 0, 0x3FF, 0, 0);input_set_abs_params(dev, ABS_PRESSURE, 0, 1, 0, 0);dev->name = s3c2410ts_name;dev->id.bustype = BUS_RS232;dev->id.vendor = 0xDEAD;dev->id.product = 0xBEEF;dev->id.version = S3C2410TSVERSION;/*INT_TC, INT_ADC中断注册,问题:两种中断的产生时机?哪种中断会先产生?答案:INT_TC会先产生,并不断的产生*//* Get irqs *///中断处理函数if (request_irq(IRQ_ADC, stylus_action, IRQF_SHARED|IRQF_SAMPLE_RANDOM, "s3c2410_action", dev)) {printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n");iounmap(base_addr);return -EIO;}if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,"s3c2410_action", dev)) {printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n");iounmap(base_addr);return -EIO;}printk(KERN_INFO "%s successfully loaded\n", s3c2410ts_name);/* All went ok, so register to the input system *//*注册输入设备*/input_register_device(dev);return 0;}/*主要完成:1、中断的释放2、注销input设备3、释放虚拟内存*/static void __exit s3c2410ts_exit(void){disable_irq(IRQ_ADC);disable_irq(IRQ_TC);free_irq(IRQ_TC,dev);free_irq(IRQ_ADC,dev);if (adc_clock) {clk_disable(adc_clock);clk_put(adc_clock);adc_clock = NULL;}input_unregister_device(dev);iounmap(base_addr);}module_init(s3c2410ts_init);module_exit(s3c2410ts_exit);MODULE_LICENSE("GPL");。
android触摸屏驱动加载
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
Console: switching to colour frame buffer device 80x30
eth0: dm9000 at c4812000,c4814000 IRQ 207 MAC: 08:00:3e:26:0a:5b
Linux video capture interface: v2.00
Uniform Multi-Platform E-IDE driver
ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
E/mountd ( 778): could not read initial mass storage state
D/AndroidRuntime( 781):
D/AndroidRuntime( 781): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
触摸屏驱动加载
内核信息表示触摸屏驱动已经加载:
Starting kernel ...
Uncompressing Linux...........................................................................................................
实验5 触摸屏驱动的移植
一、实验目的
掌握 Linux 下触摸屏驱动程序的原理; 掌握 Linux 下触摸屏应用程序的编写方法。
二、实验环境
硬件:TQ2440 核心子板、PC 机; 软件:Windows 2000/NT/XP、Fedora10、其他嵌入式软件包。
三、完成实验所需时间:约90分钟 四、实验内容
#include <asm/arch/idle.h> #include <asm/arch/fb.h> #include <asm/arch/ts.h>
#include <asm/plat-s3c24xx/s3c2410.h> #include <asm/plat-s3c24xx/s3c2440.h> #include <asm/plat-s3c24xx/clock.h>
}; static void __init smdk2440_map_io(void) {
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); }
+= elo.o
obj-$(CONFIG_TOUCHSCREEN_FUJITSU)
+= fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_MTOUCH)
+= mtouch.o
obj-$(CONFIG_TOUCHSCREEN_MK712)
基于Android的触摸屏驱动开发
寓
基于 An d r o i d昀触摸屏驱 动开 发
国光 电器股 份 有 限公 司 欧 阳小星
[ 摘 要] 本文分析 了A n d r o 试操作 系统 的输入子 系统 结构 , 开发 出了基于 I 2 C ̄ An d r o i dI n p u t f i - 系统的触摸屏驱动程序 , 实现 了 多点 触控数据 的上报 , 较低功耗 的电源管理及虚拟按键使驱 动成 功应用于平板 电脑 , 性能稳定。 [ 关键i  ̄ q ] A n d r o i d I n p u t 触摸 屏 电源管理 虚 拟按键
用 户 应 用
An d oLeabharlann r dA H … … 一 一
_ 、 !
●I n p u t c o r e : 负责管理输 入设备 , 如驱动程 序的文 件注册 , 在驱动 层与E v e n t H a n d l e r 层之 间起承 上启下的作用 , 传递事 件消息 , 输人事件 经 过驱 动一 输入 核一事 件处理一 用户 空间一应 用程序 的路线 完成整 个 事件 的响应 。  ̄E v e n t Ha n d l e r : 负责输入设 备的事件注册 及管理 , 将i n p u t _ d e v 与 i n p u th a n d l e r 关联 在一起 , 同时将事件上报给用户空间 。 ●An d r o i d 硬件抽象层 E v e n t Hu b: E v e n t Hu b是本地框架 l i b u i 的一部 分, 是A n d r o i d 系统 中所有事 件的处理 中心 , 负责驱动程 序的控制及 给 服务管理 的j a v a 框架提供 消息 。 ●输入服 务管理的 J a v a 框架 : 在j a v a 框架层具有 I n p u t M a n a g e r 等类 处理 由抽象层 E v e n t H u b 传 递上来的消息 , 将 获取到的 R a w I n p u t E v e n t 转 换值或 K e y E v e n t 值提供给应用层。 ●J a v a 应用 层 : 在 应用 程 序 中通过 重新 实 现 A n d r o i d . v i e w类 中的 o n T o u c h E v e n t 等 函数来 响应 触摸 屏 的运动 事件 , 或 通过 重新 实现 o n — K e y D o w n 等 函数 响应虚拟按键 的按键 事件。 I n p u t 驱动 程序是 L i n u x 标 准的输 入设 备字符 驱动程 序 , 包 括事件 设备、 游戏杆 和 鼠标 3 种驱 动 , 其 主设 备号为 1 3 , 事件设 备为 6 4 ~ 9 5 , 游 戏杆 为0~3 1 , 鼠标为 3 3~6 3 。其中 , 事件 驱动( E v e n t ) 是l i n u x内核通 用 的驱 动程序 , 它支持 t o u c h s c r e e n 、 m o u s e / m i c e 、 k e y b o a r d 等 多种 输人设 备 。I n p u t 输入子 系统为设备驱 动及事件处理 提供 了标 准的接 口, 用户 只需设计 并实现设备驱动程序 即可 , 设备驱动 的实现过 程如下 : 1 ) 驱动模块初始化 一个 i n p u t 设备, 内核主要通过 i n p u t — d e v 结构体 分 配一个输入设 备 , 通过 s e t _ b i t 0 设 置设备支持 的事件 , 包括 同步 、 按 键、 键 盘触摸和绝对坐标等事件 ; 2 ) 在p r o b e 初 始化 函 数 中使用 i n p u t r e g i s t e r _ _ d e v i c e 0 函数 注册 i n — p u t _ d e v 到i n p u t 输入子系统 , 使其成 为结构 化的输 入设备 ; 3 ) 注册 中断 及事件上 报处理 , 由于输入设 备的事件 发生时 间不规 律, 驱 动程 序通 常 采用 中断 的方 式 响应 事件 , 将 数据 信息 封装 成 - n — p u t _ e v e n t 结构上报 给相 关接 口文件/ d e v / i n p u t / E v e n t X 。 3 . 基于 An d r o i d的触摸屏驱动 实现 触摸屏 是一种被广泛应用 于手 持终端设备 、 医疗设 备 、 工业控制等 嵌人 式设备 的输 入材料 , 它具有 响应 速度快 , 易操作性 等优点 , 目前使 用最 广的触摸屏 有电容式 和 电阻式 两种类 型 , 相关工作 原理请参 考文 献[ 4 ] [ 5 ] 。其 中电容式 由于具有 多触点功能 , 可 以同时支持用 户单手指 、 多个 手指或多 只手 、 多个 人同时操作 屏幕 , 操 作更加方 便 , 在行业 中的
触摸屏驱动编写
1、i2c_add_driver将驱动注册到总线上。
2、调用probe函数分配touch_dev结构,ts_init_touch初始化触摸屏设备。
初始化在gpio_request分配io口,初始化workINIT_WORK(&touch_dev->work, zinitix_touch_work),初始化input_dev 并注册inputrequest_irq申请中断对于input初始化:input_mt_init_slots(ts->input_dev, ts->max_touch_num);b类触摸事件需要set_bit(EV_SYN, touch_dev->input_dev->evbit);设置事件响应set_bit(EV_KEY, touch_dev->input_dev->evbit);设置按键响应set_bit(BTN_TOUCH, touch_dev->input_dev->keybit);一次触摸结束响应(后面调用input_report_key(touch_dev->input_dev, BTN_TOUCH, 0);每次报点都要调用。
0表示触摸结束)set_bit(EV_ABS, touch_dev->input_dev->evbit);绝对值事件响应触摸屏调试注意事项:1 、io口配置引脚定义。
(引脚序号是否跟主板一样)2、input初始化,事件设置,参数设置3、多点触摸协议有a类,b类之分。
A类在每次报点后加input_mt_sync(touch_dev->input_dev);B类需要在probe中input_mt_init_slots(ts->input_dev,ts->max_touch_num);再在每次报点前input_mt_slot(ts->input_dev, index);触摸屏驱动编写参考:1、打印信息参考:#ifdef DEBUG#define DBG(fmt ...) printk(KERNINFO fmt)#else#define DBT(fmt ...)#endif#ifdef DEBUGERR#define DEBUGERR(fmt ...) printk(KERNERR fmt) #else##define DEBUGERR(fmt ...)#endif2、互换参考:#ifdef SWAP_XY#define swap_xy(x,y) do{typeof(x) z=x; x=y;y=z;}while(0);#endifX, y 置换注意:input_device中也要置换Input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, X_MAX, 0, 0)Input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, Y_MAX, 0, 0)3、io初始化参考:IO初始化不正确将无法产生中断,#define TOUCH_RST_PIN RK29_PIN6_PC3#define TOUCH_INT_PIN RK29_PIN0_PA2Int ft5306_init_io(void){//用io前首先要申请io,其次注意io设置的延时。
触摸屏驱动软件使用教程
触摸屏驱动软件使用教程第一章:介绍触摸屏驱动软件的作用和分类触摸屏驱动软件是指用于控制和管理触摸屏设备的软件,它能够将触摸屏的触摸信号转化为计算机可识别的输入信号。
根据不同的触摸屏技术,触摸屏驱动软件也分为电容式触摸屏驱动软件、电阻式触摸屏驱动软件、表面声波触摸屏驱动软件等。
第二章:安装触摸屏驱动软件前的准备工作在安装触摸屏驱动软件之前,我们需要确定自己所使用的触摸屏型号和操作系统。
可通过查看触摸屏设备上的标签或查阅相关文档来获取这些信息。
另外,确保计算机已连接触摸屏设备,并且能够正常工作。
第三章:电容式触摸屏驱动软件的安装与配置对于电容式触摸屏,我们需要首先下载适用于该触摸屏型号和操作系统的驱动软件。
下载完成后,双击运行安装程序,按照提示完成安装。
安装完成后,我们需要进入设备管理器,找到触摸屏驱动,确保它已启用并处于正常工作状态。
接着,我们进入控制面板,点击触摸屏选项进行软件配置,根据需要进行灵敏度调整和其他参数设置。
第四章:电阻式触摸屏驱动软件的安装与配置对于电阻式触摸屏,大多数情况下,操作系统已经自带相应的驱动软件,并且会自动识别和安装。
如果没有自动安装驱动,我们可以根据触摸屏型号去官方网站下载对应的驱动程序。
下载完成后,运行安装程序,按照提示完成安装。
安装完成后,我们同样需要进入设备管理器确认驱动已启用并正常工作。
要配置电阻式触摸屏驱动软件,可以在控制面板或者驱动软件提供的设置界面中进行灵敏度调整和其他参数配置。
第五章:表面声波触摸屏驱动软件的安装与配置表面声波触摸屏是一种利用声波传播和反射的技术来获得触摸信息的触摸屏。
安装和配置表面声波触摸屏驱动软件与电容式触摸屏驱动软件类似,首先下载适用于该触摸屏型号和操作系统的驱动软件,运行安装程序完成安装。
再次确认驱动已启用并正常工作后,进入控制面板或者驱动软件提供的设置界面进行相关参数的配置。
第六章:常见问题解决办法6.1 驱动安装失败:可以重新下载驱动软件,并按照安装说明进行操作。
手机制造行业中的屏幕驱动技术原理及应用
手机制造行业中的屏幕驱动技术原理及应用近年来,随着智能手机的普及与技术的不断提升,手机制造行业中屏幕驱动技术也得到了快速发展。
屏幕驱动技术是指将图像信号转化为电信号,并通过驱动电路控制液晶屏幕的亮暗变化,从而实现手机屏幕上显示各种图像、文字和视频等功能。
在手机制造行业中,主要有两种屏幕驱动技术:TFT-LCD(薄膜晶体管液晶显示器)和AMOLED(主动矩阵有机发光二极管)。
下面将分别介绍这两种技术的原理及应用。
TFT-LCD技术是目前手机市场上最为常见的屏幕驱动技术之一。
这种技术采用了薄膜晶体管作为电子开关,液晶屏中的每一个像素点都有一个对应的薄膜晶体管控制其亮度和颜色。
当输入信号进入显示器后,经过电路内的控制和放大处理,最终通过驱动电路将电信号传送到每个像素点的薄膜晶体管上,使其开启或关闭,从而控制像素点的亮暗变化。
TFT-LCD技术在手机制造行业中的应用非常广泛。
首先,TFT-LCD具有色彩鲜艳、显示稳定等优点,可以呈现出高清晰度的图像和视频。
其次,TFT-LCD具有快速响应时间、高刷新率等特点,使得手机屏幕能够在高速移动或切换图像时依然保持清晰流畅。
再者,TFT-LCD技术也具有较低的功耗,可以延长手机的续航时间。
因此,TFT-LCD技术已经成为目前手机市场上最主流的屏幕驱动技术。
除了TFT-LCD技术之外,AMOLED技术也在手机制造行业中得到了广泛应用。
AMOLED技术采用有机发光材料作为像素点的发光层,通过在像素点上加电产生电流驱动有机发光材料发光。
与TFT-LCD技术不同的是,AMOLED技术中每个像素点都可以独立发光,不需要背光源,因此屏幕更加薄和轻便。
AMOLED技术在手机制造行业中的应用越来越广泛。
首先,AMOLED屏幕具有无限对比度和快速响应时间等特点,能够呈现出极高的画质和色彩鲜艳的图像。
其次,AMOLED屏幕具有较低的功耗,使得手机在显示亮色图像时能够节约更多的电能。
此外,AMOLED屏幕还可以实现弯曲的设计,使得手机具有更高的灵活性和创新性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最近学习了电容触摸屏的驱动及其上层工作原理,拿出来和大家分享!转]Android触摸屏校准程序的实现一,校准的触摸算法如下:触摸屏校准通用方法。
(XL, YL是显示屏坐标,XT, YT是触摸屏坐标,)XL = XT*A+YT*B+CYL = XT*D+YT*E+F由于具体计算是希望是整数运算,所以实际中保存的ABCDEF为整数,而增加一个参数Div XL = (XT*A+YT*B+C) / DivYL = (YT*D+YT*E+F) / DivTSLIB把以上的7个参数ABCDEF Div 保存在pointercal 文件中。
不校准的数据:A=1, B=0, C=0, D=0, E=1, F=0, Div=1A B C D E F Div-411 37818 -3636780 -51325 39 47065584 65536二,Android 事件处理机制android 事件的传入是从EventHub开始的,EventHub是事件的抽象结构,维护着系统设备的运行情况(设备文件放在/dev/input里),设备类型包括Keyboard、TouchScreen、TraceBall。
它在系统启动的时候会通过open_device方法将系统提供的输入设备都增加到这个抽象结构中,并维护一个所有输入设备的文件描述符,如果输入设备是键盘的话还会读取/system/usr/keylayout/目录下对应键盘设备的映射文件(修改./development/emulator/keymaps /qwerty.kl来改变键值的映射关系),另外getEvent方法是对EventHub中的设备文件描述符使用poll操作等侍驱动层事件的发生,如果发生的事件是键盘事件,则调用Map函数按照映射文件转换成相应的键值并将扫描码和键码返回给KeyInputQueue.frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp根据事件的类型以及事件值进行判断处理,从而确定这个事件对应的设备状态是否发生了改变并相应的改变对这个设备的描述结构InputDevice。
Windowmanager会创建一个线程(InputDispatcherThread),在这个线程里从事件队列中读取发生的事件(QueuedEvent ev = mQueue.getEvent()),并根据读取到事件类型的不同分成三类(KEYBOARD、TOUCHSCREEN、TRACKBALL),分别进行处理,例如键盘事件会调用dispatchKey((KeyEvent)ev.event, 0, 0)以将事件通过Binder发送给具有焦点的窗口应用程序,然后调用mQueue.recycleEvent(ev)继续等侍键盘事件的发生;如果是触摸屏事件则调用dispatchPointer(ev, (MotionEvent)ev.event, 0, 0),这里会根据事件的种类(UP、DOWN、MOVE、OUT_SIDE等)进行判断并处理,比如Cancel或将事件发送到具有权限的指定的窗口中去;移植方案Android本身并不带触摸屏校准。
Android获取到的数据就是驱动上报的原始数据。
方案一: 移植TSLIB,通过TSLIB产生pointercal 校准参数文件。
方案二: 从Android框架层获取OnTouch事件产生pointercal 校准参数文件方案一: 数据的校准在驱动中完成。
即把pointercal 的参数数据通过某种方式(sysfs)传递给驱动程序进行校准。
方案二: 驱动上报原始点,原始点在框架层拦截后进行校验处理。
TSLIB移植过程修改源码以适应android的文件结构。
设定Android.mk 编译选项,生成库即应用。
etc/ts.conf module_raw inputsrc/ts_config.c #define TS_CONF "/system/etc/ts.conf"src/ts_load_module.cchar *plugin_directory="/system/lib/ts/plugins/";tests/fbutils.cchar *defaultfbdevice = "/dev/graphics/fb0";COPY ts.conf 到/system/etc/ts.confinit.rc. mkdir /data/etc/pointercal通过ts_calibrate 产生pointercal 数据文件。
框架内获取参数文件制作APK 应用,仿效ts_calibrate采点并计算出各参数,产生pointercal框架内实现触摸屏校准在InputDevive.java 中拦截触摸屏原始数据进行pointercal参数校验后再分发驱动内实现触摸屏校准在init.rc 中添加event,在触摸屏加载后把pointercal参数输送给驱动。
结果-效果实现细节:扩展init - proper_serivce 系统支持的属性权限,对自定义的特殊系统属性进行权限开放。
使用自定义系统属性在init.rc 中on property 事件中处理pointercal的读写权限。
使用自定义系统属性触摸屏校准程序.apk 和InputDevice.java 中的输入事件的同步。
(在触摸屏校准期间inputDevice 在输入事件中不能采用算法。
校准程序完成有inputDevice重新启用校准算法)模拟器中至今无法进入device.absX/Y != null 的代码,需要了解以下inputDevice 被调用的步骤。
三,触摸屏的时间流程:驱动层:/** Touchscreen absolute values** These parameters are used to help the input layer discard out of* range readings and reduce jitter etc.** o min, max:- indicate the min and max values your touch screen returns* o fuzz:- use a higher number to reduce jitter** The default values correspond to Mainstone II in QVGA mode** Please read* Documentation/input/input-programming.txt for more details.*/static int abs_x[3] = {350, 3900, 5};module_param_array(abs_x, int, NULL, 0);MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz");static int abs_y[3] = {320, 3750, 40};module_param_array(abs_y, int, NULL, 0);MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz");static int abs_p[3] = {0, 150, 4};module_param_array(abs_p, int, NULL, 0);MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz");/** 对设备进行初始化设置*/set_bit(EV_ABS, wm->input_dev->evbit);set_bit(ABS_X, wm->input_dev->absbit);set_bit(ABS_Y, wm->input_dev->absbit);set_bit(ABS_PRESSURE, wm->input_dev->absbit);input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],abs_x[2], 0);input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],abs_y[2], 0);input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1], abs_p[2], 0);/** 事件发生时,提供原始点*/input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);/** 提供给驱动外查询input_dev 的接口* struct input_absinfo info;* ioctl(fd, EVIOCGABS(axis), &info)* src file: evDev.c*/if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {t = _IOC_NR(cmd) & ABS_MAX;abs.value = dev->abs[t];abs.minimum = dev->absmin[t];abs.maximum = dev->absmax[t];abs.fuzz = dev->absfuzz[t];abs.flat = dev->absflat[t];Android 底层驱动EventHub.cppstatic const char *device_path = "/dev/input";openPlatformInput(void)scan_dir(device_path);open_device(devname);fd = open(deviceName, O_RDWR);/** 对外接口,getEvent,* inotify 监控device_path目录,使用poll机制轮询inotify 和各个输入设备的可用状态。