Linux下的触摸屏驱动Word格式.docx
- 文档编号:22520891
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:18
- 大小:20.46KB
Linux下的触摸屏驱动Word格式.docx
《Linux下的触摸屏驱动Word格式.docx》由会员分享,可在线阅读,更多相关《Linux下的触摸屏驱动Word格式.docx(18页珍藏版)》请在冰豆网上搜索。
);
//获取时钟
if(!
adc_clock){
printk(KERN_ERR"
failedtogetadcclocksource\n"
return-ENOENT;
}
clk_enable(adc_clock);
//使能时钟
base_addr=ioremap(S3C2410_PA_ADC,0x20);
//物理地址转为虚拟地址
if(base_addr==NULL){
Failedtoremapregisterblock\n"
return-ENOMEM;
s3c2410_ts_connect();
//触摸屏端口配置
//使能预分频,分频系数为0xff
iowrite32(S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(0xFF),base_addr+S3C2410_ADCCON);
iowrite32(0xffff,
base_addr+S3C2410_ADCDLY);
//延时
//检查光标按下中断信号,等待中断
iowrite32(WAIT4INT(0),base_addr+S3C2410_ADCTSC);
input_dev=input_allocate_device();
//分配input设备
input_dev){
Unabletoallocatetheinputdevice!
!
\n"
dev=input_dev;
//支持按键事件、坐标事件
dev->
evbit[0]=BIT(EV_SYN)|BIT(EV_KEY)|BIT(EV_ABS);
keybit[BITS_TO_LONGS(BTN_TOUCH)]=BIT(BTN_TOUCH);
//对于X轴范围是0-ox3ff,数据误差是0,中心平滑位置是0
input_set_abs_params(dev,ABS_X,0,0x3FF,0,0);
input_set_abs_params(dev,ABS_Y,0,0x3FF,0,0);
input_set_abs_params(dev,ABS_PRESSURE,0,1,0,0);
name=s3c2410ts_name;
id.bustype=BUS_RS232;
id.vendor=0xDEAD;
id.product=0xBEEF;
id.version=S3C2410TSVERSION;
//申请AD转换中断
if(request_irq(IRQ_ADC,stylus_action,IRQF_SHARED|IRQF_SAMPLE_RANDOM,"
s3c2410_action"
dev)){
s3c2410_ts.c:
CouldnotallocatetsIRQ_ADC!
iounmap(base_addr);
return-EIO;
//申请触摸中断
if(request_irq(IRQ_TC,stylus_updown,IRQF_SAMPLE_RANDOM,
"
CouldnotallocatetsIRQ_TC!
printk(KERN_INFO"
%ssuccessfullyloaded\n"
s3c2410ts_name);
input_register_device(dev);
return0;
}
下面是这个模块加载函数中调用的一个配置端口函数
staticinlinevoids3c2410_ts_connect(void)
//将触摸屏用到的四个端口配置成触摸屏模式
s3c2410_gpio_cfgpin(S3C2410_GPG(12),S3C2410_GPG12_XMON);
s3c2410_gpio_cfgpin(S3C2410_GPG(13),S3C2410_GPG13_nXPON);
s3c2410_gpio_cfgpin(S3C2410_GPG(14),S3C2410_GPG14_YMON);
s3c2410_gpio_cfgpin(S3C2410_GPG(15),S3C2410_GPG15_nYPON);
我们来分析两种情况,第一种情况,如果没有按下触摸屏
驱动中定义了一个定时器
staticstructtimer_listtouch_timer=
TIMER_INITIALIZER(touch_timer_fire,0,0);
因为这个定时器的期限时间设置为0,这表示当驱动加载后就会执行一次定时函数touch_timer_fire
staticvoidtouch_timer_fire(unsignedlongdata)
unsignedlongdata0;
unsignedlongdata1;
intupdown;
data0=ioread32(base_addr+S3C2410_ADCDAT0);
//读取X坐标
data1=ioread32(base_addr+S3C2410_ADCDAT1);
//读取Y坐标
updown=(!
(data0&
S3C2410_ADCDAT0_UPDOWN))&
&
(!
(data1&
S3C2410_ADCDAT0_UPDOWN));
//触摸屏是否被按下,如果按下updowm=1
if(updown){
if(count!
=0){
longtmp;
tmp=xp;
xp=yp;
yp=tmp;
xp>
>
=2;
yp>
input_report_abs(dev,ABS_X,xp);
input_report_abs(dev,ABS_Y,yp);
input_report_key(dev,BTN_TOUCH,1);
input_report_abs(dev,ABS_PRESSURE,1);
input_sync(dev);
xp=0;
yp=0;
count=0;
iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE|AUTOPST,base_addr+S3C2410_ADCTSC);
iowrite32(ioread32(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_ENABLE_START,base_addr+S3C2410_ADCCON);
}else{//没有被按下
//初始化count为0,表示当前AD转换没发生
input_report_key(dev,BTN_TOUCH,0);
//向input子系统报告未按下
input_report_abs(dev,ABS_PRESSURE,0);
//等待按键中断
if(OwnADC){//OwnADC是获取一把锁标示,在此为0
OwnADC=0;
up(&
ADC_LOCK);
第二种情况,如果触摸屏被按下,首先触发触摸中断,执行stylus_updown函数
staticirqreturn_tstylus_updown(intirq,void*dev_id)
if(down_trylock(&
ADC_LOCK)==0){
//获取一把锁
OwnADC=1;
//表示获得锁
//读取X轴数据
//读取Y轴数据
//触摸屏是否被按下,按下updowm=1
touch_timer_fire(0);
//如果触摸屏被按下,执行touch_timer_fire
}else{
//去抖动操作,释放锁
returnIRQ_HANDLED;
下面我们第二次分析touch_timer_fire,而这次主要是因为触摸中断中调用了这个函数,假设当前触摸屏被按下后,坐标值还没进行AD转换
if(updown){
//触摸屏被按下
=0){//count是全局变量,统计AD转换次数,目前未AD转换
//虽然触摸屏被按下,但是未完成AD转换
//自动连续测量X和Y坐标
iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE|AUTOPST,base_addr+S3C2410_ADCTSC);
//AD转换开始且该位在开始后清零
}else{
if(OwnADC){
现在我们知道,如果触摸屏被按下,但是AD还没转换完毕,那么我们会开启AD转换,自动测量X和Y坐标,这样就会触发AD转换中断,执行AD转换的中断处理程序。
其实当我们的触摸屏被按下,当X和Y轴获取电压值,然后就会进行AD转换,执行AD转换的中断处理程序。
好了,我们该看看AD转换的中断代码了。
staticirqreturn_tstylus_action(intirq,void*dev_id)
if(OwnADC){//只有触摸屏被按下,相应了触摸中断该标志才为1
xp+=data0&
S3C2410_ADCDAT0_XPDATA_MASK;
//叠加X坐标
yp+=data1&
S3C2410_ADCDAT1_YPDATA_MASK;
//叠加Y坐标
count++;
//统计AD转换次数
if(count<
(1<
<
2)){//如果AD转换次数不足4次
iowrite32(ioread32(base_addr+S3C2410_ADCCON)|S3C2410_ADCCON_ENABLE_START,base_addr+S3C2410_ADCCON);
mod_timer(&
touch_timer,jiffies+1);
//四次AD转换后,修改定时时间
iowrite32(WAIT4INT
(1),base_addr+S3C2410_ADCTSC);
//等待释放
在这个AD转换的中断程序中,有一个全局变量count令人费解,count是什么作用呢?
我们做AD转换时,其实是对一个点进行了四次采样,然后把四次采样结果进行叠加然后取平均。
这样提高AD转换的精确度。
在上面这个AD转换的中断处理程序中,我们知道,当count不足4次时,会继续进行自动连续测量X和Y坐标并开启AD转换,只有当AD转换次数达到四次后,就会修改定时器的时间,使得下一个节拍到来时执行定时器处理程序,并且等待按键被释放。
当AD转换完毕,我们在下一个节拍到来后,会执行一次定时器程序touch_timer_fire
=0){//count是全局变量,统计AD转换次数,目前已经4次
//X和Y轴数据交换
//因为对同一个点采样四次,这里对X轴取平均
//因为对同一个点采样四次,这里对Y轴取平均
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 触摸屏 驱动