目录

1  触摸屏硬件连接

2  触摸屏检测原理

3  触摸屏接口模式

4  触摸屏驱动编程流程图​

5  触摸屏驱动程序

6 触摸屏驱动程序测试


1  触摸屏硬件连接

2440开发板使用的是4线触摸屏,该4线连接在2440的AIN4~AIN7引脚上
YM: (Y Minus)触摸屏的Y坐标的负线
YP : (Y Power)触摸屏的Y坐标的正线
XM: (Y Minus)触摸屏的Y坐标的负线
XP : (Y Power)触摸屏的Y坐标的正线

2  触摸屏检测原理

测X坐标方向时:XP接3.3V , XM接0V, YP与ADC检测引脚相连,当按压时就可以检测到YP电压,根据该电压可计算x坐标。
测Y坐标方向时:   YP接3.3V , YM接0V, XP与ADC检测引脚相连,当按压时就可以检测到XP电压,根据该电压可计算x坐标。

3  触摸屏接口模式

  • 分离的 X/Y 方向转换模式

触摸屏控制器可以工作在两个转换模式之一。方向转换模式如下方法操作。X 方向模式写 X 方向转换数据到
    ADCDAT0,故触摸屏接口产生中断源给中断控制器。Y 方向模式写 Y 方向转换数据到 ADCDAT1,故触摸屏接口产
    生中断源给中断控制器。

  • 自动(顺序)X/Y 方向转换模式

自动(顺序)X/Y 方向转换模式操作如下。触摸屏控制器顺序变换触摸 X 方向和 Y 方向。在自动方向转变模式中触摸
    控制器在写入 X 测量数值到 ADCDAT0 和写入 Y 测量数值到 ADCDAT1 后,触摸屏接口产生中断源给中断控制器。

  • 等待中断模式

当笔尖落下时触摸屏控制器产生中断(INT_TC)信号。等待中断模式设置值为 rADCTSC=0xd3; // XP_PU,XP_Dis,
XM_Dis,YP_Dis,YM_En触摸屏控制器产生中断信号(INT_TC)后,必须清除等待中断模式。(XY_PST 设置到无操作模式)

4  触摸屏驱动编程流程图

5  触摸屏驱动程序

ts_drv.c文件

#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 <asm/mach/map.h>#include <mach/regs-gpio.h>//包含了GPIO相关宏
#include <plat/adc.h>
#include <plat/regs-adc.h>
#include <plat/ts.h>struct touch_regs{unsigned long adccon;unsigned long adctsc;unsigned long adcdly;unsigned long adcdat0;unsigned long adcdat1;unsigned long adcupdn;
};static struct input_dev *touch_dev;
static volatile struct touch_regs* ts_regs;
static struct timer_list touch_timer;/*进入等待中断模式:
*等待触摸笔按下中断,开始手动测量X坐标,电压从YM端点进行检测
*/
static void enter_wait_down_mode(void)
{//检测笔尖抬起中断|YM输出使能|YP输出禁止|XP输出禁止|手动测量X方向ts_regs->adctsc = S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | S3C2410_ADCTSC_XY_PST(3);
}/*进入等待中断模式:
*等待触摸笔松开中断,开始手动测量X坐标,电压从YM端点进行检测
*/
static void enter_wait_up_mode(void)
{//检测笔尖抬起中断|YM输出使能|YP输出禁止|XP输出禁止|手动测量X方向ts_regs->adctsc = S3C2443_ADCTSC_UD_SEN | S3C2410_ADCTSC_YM_SEN |S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | S3C2410_ADCTSC_XY_PST(3);
}/*进入自动测量xy模式
*自动转换xy模式:x,y都转换完成后才产生ADC中断
*分离xy转换模式:x转换完成产生一次中断,y转换完成产生一次中断
*/
static void enter_measure_xy_mode(void)
{//XP上拉禁止 | 自动顺序x方向和Y方向测量ts_regs->adctsc = S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_AUTO_PST;
}static void start_adc(void)
{//时能ADC转换启动,且此位在启动后自动清0ts_regs->adccon |= S3C2410_ADCCON_ENABLE_START;
}static int s3c_filter_ts(int x[], int y[])
{
#define ERR_LIMIT 10int avr_x, avr_y;int det_x, det_y;avr_x = (x[0] + x[1])/2;avr_y = (y[0] + y[1])/2;det_x = (x[2] > avr_x) ? (x[2] - avr_x) : (avr_x - x[2]);det_y = (y[2] > avr_y) ? (y[2] - avr_y) : (avr_y - y[2]);if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))return 0;avr_x = (x[1] + x[2])/2;avr_y = (y[1] + y[2])/2;det_x = (x[3] > avr_x) ? (x[3] - avr_x) : (avr_x - x[3]);det_y = (y[3] > avr_y) ? (y[3] - avr_y) : (avr_y - y[3]);if ((det_x > ERR_LIMIT) || (det_y > ERR_LIMIT))return 0;return 1;
}static void touch_timer_function(unsigned long data)
{if(ts_regs->adcdat0 & S3C2410_ADCDAT1_UPDOWN )//触摸笔抬起{input_report_abs(touch_dev, ABS_PRESSURE, 0);input_report_key(touch_dev, BTN_TOUCH, 0);input_sync(touch_dev);enter_wait_down_mode();}else  //触摸笔按下{//测量xy坐标enter_measure_xy_mode();start_adc();}
}/*触摸笔按下,松开中断处理函数*/
static irqreturn_t touch_irq_handler(int irq, void *dev_id)
{if(ts_regs->adcdat0 & S3C2410_ADCDAT1_UPDOWN  )//触摸比抬起{enter_wait_down_mode();}else//触摸比按下{enter_measure_xy_mode();start_adc();}return IRQ_HANDLED;
}static irqreturn_t adc_irq_handler(int irq, void *dev_id)
{static int cnt = 0;int adcdat0,adcdat1;static int x[4],y[4];/*优化2: 如果ADC完成时,发现触摸笔已经松开, 则丢弃本次结果*/adcdat0 = ts_regs->adcdat0;adcdat1 = ts_regs->adcdat1;if(ts_regs->adcdat0 & S3C2410_ADCDAT1_UPDOWN)//触摸笔抬起{//Stylus up statecnt = 0;input_report_abs(touch_dev, ABS_PRESSURE, 0);input_report_key(touch_dev, BTN_TOUCH, 0);input_sync(touch_dev);enter_wait_down_mode();}else//触摸笔按下{/*优化3:多次测量,求平均值*/x[cnt] = ts_regs->adcdat0 & 0x3ff;y[cnt] = ts_regs->adcdat1 & 0x3ff;++cnt;if(cnt >= 4){/*优化4:软件过滤*/if(s3c_filter_ts(x,y)){//printk(" x=%d, y=%d \n",  (x[0]+x[1]+x[2]+x[3])/4, (y[0]+y[1]+y[2]+y[3])/4);input_report_abs(touch_dev, ABS_X, (x[0]+x[1]+x[2]+x[3])/4);input_report_abs(touch_dev, ABS_Y, (y[0]+y[1]+y[2]+y[3])/4);input_report_abs(touch_dev, ABS_PRESSURE, 1);input_report_key(touch_dev, BTN_TOUCH, 1);input_sync(touch_dev);}cnt = 0;//为了能够处理滑动事件,enter_wait_up_mode();mod_timer(&touch_timer, jiffies + HZ/100);}else{enter_measure_xy_mode();start_adc();}}return IRQ_HANDLED;
}static int touch_init(void)
{struct clk*  clk;int ret;//1.分配一个input_device结构体touch_dev = input_allocate_device();//2.设置//2.1 事件类型: 设置evbitset_bit(EV_KEY, touch_dev->evbit);//按键事件set_bit(EV_ABS, touch_dev->evbit);//绝对位移事件//2.2 具体事件set_bit(BTN_TOUCH ,touch_dev->keybit);input_set_abs_params(touch_dev, ABS_X, 0, 0x3FF, 0, 0);input_set_abs_params(touch_dev, ABS_Y, 0, 0x3FF, 0, 0);input_set_abs_params(touch_dev, ABS_PRESSURE, 0, 1, 0, 0);//3.注册ret = input_register_device(touch_dev);if(ret < 0){printk("failed to register input device\n");ret = -EIO;return ret;}//4.硬件相关//4.1 使能时钟CLKCONclk = clk_get(NULL, "adc");clk_enable(clk);//4.2 设置相关寄存器ts_regs = ioremap(S3C24XX_PA_ADC, sizeof(struct touch_regs));/*bit[14]:PRSCEN = 1 //预分频使能*bit[13:6]:PRSCVL =49 //预分频系数, ADCCLK=PCLK/(49+1) = 1MHz*bit[0]: ENABLE_START = 0 //A/D conversion starts by enable*/ts_regs->adccon = S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(49);ret = request_irq(IRQ_TC, touch_irq_handler, IRQF_SAMPLE_RANDOM, "touch_pen", NULL);//注册一个触摸中断if (ret) {printk("request IRQ_TC error\n");return ret;}ret = request_irq(IRQ_ADC, adc_irq_handler, IRQF_SAMPLE_RANDOM, "adc", NULL);if (ret) {printk("request IRQ_TC error\n");return ret;}/*优化1:设置ADCDLY为最大值*/ts_regs->adcdly = 0xFFFF;/*优化5:使用定时器处理长按滑动*/init_timer(&touch_timer);touch_timer.function = touch_timer_function;add_timer(&touch_timer);enter_wait_down_mode(); return 0;
}static void touch_exit(void)
{free_irq(IRQ_TC, NULL);free_irq(IRQ_ADC, NULL);input_unregister_device(touch_dev);input_free_device(touch_dev);iounmap(ts_regs);del_timer(&touch_timer);
//  clk_disable(clk);
}module_init(touch_init);
module_exit(touch_exit);
MODULE_LICENSE("GPL");

makefile文件

KERN_DIR = /home/ningjw/linux-3.4.2all:make -C $(KERN_DIR) M=`pwd` modules clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.orderobj-m   += ts_drv.o

6 触摸屏驱动程序测试

  • 去掉自带的触摸屏驱动程序,重新make uImage,并烧录uImage
    -> Device Drivers                                                                      
       -> Input device support              
         -> Touchscreens
            ->Samsung S3C2410/generic touchscreen input driver

如果不去掉触摸屏会报如下错误:
request IRQ_TC error
insmod: can't insert 'ts_drv.ko': Device or resource busy

  • 测试方式1:执行hexdump /dev/input/event0 命令,然后点击触摸屏可以看到有如下类似输出,则驱动正常
0000000 0235 0000 4877 0008 0003 0000 026a 0000
0000010 0235 0000 4889 0008 0003 0001 0201 0000
0000020 0235 0000 488d 0008 0003 0018 0001 0000
0000030 0235 0000 4892 0008 0001 014a 0001 0000       
  • 测试方式2:执行/usr/local/tslib/bin 下的ts_test文件(需要移植tslib),点击触摸屏,有如下输出

    /usr/local/tslib/bin # ./ts_test
    1067.438427:     43    165      1
    1067.455615:     44    165      1
    1067.485053:     44    166      0
    1068.963966:    176    142      1 

linux3.4.2 触摸屏驱动相关推荐

  1. Linux3.4.2的触摸屏驱动分析与编写

    开发环境: 开发板:JZ2440V3 CPU:samsunS3C2440 内核:Linux3.4.2 编译工具:arm-linux-gcc 4.3.2 LCD:4.3存液晶屏AT043TN24 参考文 ...

  2. FL2440移植LINUX-3.4.2 -- 按键驱动和触摸屏驱动移植

    (一)先移植按键输入子系统驱动: 拿过去编译,改错,然后insmod: (二)触摸屏驱动拿过去编译,改错,然后insmod: 触摸屏驱动的使用: 编译: tar xzf tslib-1.4.tar.g ...

  3. 全志A64触摸屏驱动调试

    一.前言 linux的触摸屏驱动一般要经历一下几个步骤(以4412为例):1.移植驱动到linux源码"driver/input/touchscreen/"目录下,在Kconfig ...

  4. Linux下IIC子系统和触摸屏驱动

    Linux下IIC子系统和触摸屏驱动 1.IIC简介   I2C( Inter-Integrated Circuit)总线是由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备. ...

  5. linux下GT911触摸屏驱动优化记录

    linux下GT911触摸屏驱动优化记录 背景 由于最近要做linux内核启动速度优化,所以就对着驱动一点一点优化,加上QT应用程序的初始化,总共的启动时间要做到4S以内.目前先调试GT911驱动程序 ...

  6. WINCE6.0+S3C6410的触摸屏驱动

    ********************************LoongEmbedded******************************** 作者:LoongEmbedded(kandi ...

  7. linux 触摸屏驱动编写

    早在诺基亚手机还比较流行的时候,那时候触摸屏用的还不多.但是随着触摸屏手机.即智能手机的流行,触摸屏基本成了手机的标配.所以,今天可以看看触摸屏驱动在linux上是如何进行的. 1.驱动目录 driv ...

  8. linux内核关闭触摸屏校准,linux内核usb触摸屏驱动bug调试- selected device is not a touchscreen I understand...

    近期给客户调试一块数控板,今天客户带过来一个屏,并且有一个usb的触摸屏芯片接在屏上.屏很快就弄好正常显示. 触摸屏在内核下找到usb 触摸屏驱动,内核启动后这个usb转的触摸屏也正常找到,注册为ev ...

  9. linux rs232触摸屏驱动程序,Linux下的触摸屏驱动

    一.触摸屏理论概述 对于触摸屏驱动,我们主要需要掌握触摸屏驱动代码和应用层测试代码.下面讲的是基于Mini2440的触摸屏驱动,现在的驱动我们都将设备和驱动分离,挂在平台设备总线上,让设备和驱动去匹配 ...

最新文章

  1. 每天一个linux命令(21):find命令之xargs
  2. fitEllipse函数
  3. AI之HCI:人机交互Human-Computer Interaction的简介、发展历史、案例应用之详细攻略
  4. 随笔② Java中的关键字 --- final关键字
  5. php多进程mysql更新不了_php MYSQL 数据更新修改不了
  6. android 生成推广图片保存_flutter 如何生成图片并保存到手机相册?
  7. UltraGrid的Row,通过BindingSource,给ComboBox修改,修改后,内容无法即时反馈给UltraGrid的bug...
  8. sql server数据库实现保留指定位数小数的函数
  9. 装饰器python的通俗理解_2道极好的Python算法题 | 带你透彻理解装饰器的妙用
  10. html单选框换行,html – 如何防止单选按钮及其标签之间的换行符,同时仍然允许标签本身中的换行符?...
  11. 还原python源码_python 的混淆后的代码可以还原么
  12. C++ 日志框架总结
  13. Navicat Premium 12.0.29 / 12.1.5.0注册机激活
  14. 直播系统源码开发经验分享
  15. 如何获取京东Cookie
  16. There are unfinished transactions remaining解决办法
  17. Unity shader护盾特效
  18. 视频怎么转为GIF,如何制作GIF
  19. 【生产优化】基于matlab遗传算法求解帐篷工序问题【含Matlab源码 2145期】
  20. 2021中大厂php+go面试题(2)

热门文章

  1. 数学建模方法——SPSS主成分分析法
  2. WiFi 2.4GHz和5GHz的差别
  3. 使用N2N搭建虚拟局域网进行游戏联机(服务端及客户端)
  4. 解决 rubygems.org 无法访问的问题!
  5. html asp:textbox,ASP.NET中 TextBox 文本输入框控件的使用方法
  6. 20 个快速高效学习 Java 编程在线资源
  7. 数据库技术与应用 学习笔记1
  8. 华为od一面 / 二面复盘(可内推)
  9. 普元 EOS定时任务实现原理
  10. 改变一生的经济学规律