Linux下的触摸屏驱动
作者:网络转载 发布时间:[ 2013/1/10 10:03:12 ] 推荐标签:
好了,一旦释放了锁,那么我们触摸屏事件的一个生命周期才真正算分析结束了,不过在此还有一个问题没有解决,是当我们触摸屏按键被释放后,其实也会产生一个按键中断,执行触摸中断程序,不过在这个程序中起初是为了获得一个信号量,由于信号量是等待锁,所以,程序一直在试图获取这个信号量,当我们的信号量在上面这个touch_timer_fire中被释放后,我们会再次获取这个信号量,继续跟踪这个触摸中断函数stylus_updown
static irqreturn_t stylus_updown(int irq, void *dev_id)
{
unsigned long data0;
unsigned long data1;
int updown;
if (down_trylock(&ADC_LOCK) == 0) { //再次获取锁
OwnADC = 1;
data0 = ioread32(base_addr+S3C2410_ADCDAT0);
data1 = ioread32(base_addr+S3C2410_ADCDAT1);
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
if (updown) { //因为是释放操作,所以updowm=0
touch_timer_fire(0);
} else {
OwnADC = 0;
up(&ADC_LOCK); //释放锁
}
}
return IRQ_HANDLED;
}
好了,这样我们真正结束了一次触摸时间的周期。
总结下触摸屏控制的整个运行过程:
Step1:软件开启INT_ADC和INT_TS中断,设置ADCCON以确定AD转换需要的时钟频率,设置ADCDLY以确定从得到命令到开始转换坐标的延时时长,设置ADCTSC使得触摸屏处于等待触笔按下状态
Step2:当触笔按下,产生INT_TC中断,执行stylus_updown,stylus_updown首先判断中断产生的原因是不是触笔按下,是的话调用定时函数touch_timer_fire,在touch_timer_fire中设置ADCTSC使得触摸屏准备进行自动X/Y轴转换状态,然后设置ADCCON启动坐标转换,结束stylus_updown。
Step3:触摸屏在延迟指定时间后开始转换X/Y坐标,并将转换的结果保存到ADCDAT0和ADADAT1中,完成后发出INT_ADC中断,表示转换完成。
Step4:进入INT_ADC中断处理程序stylus_action,获取X/Y轴坐标,然后进行四次坐标转换以求平均值,后设置ADCTSC使得触摸屏处于等待触笔释放状态,同时当下一个节拍到来时,调用touch_timer_fire向input子系统报告坐标。
Step5:当触笔释放,还会产生INT_TC中断,进入其中断处理程序,得到触笔释放的消息,后设置ADCTSC使得触摸屏处于下一次等待触笔按下状态。
三、触摸屏驱动测试
由于mini2440的触摸屏驱动是基于input子系统的,而input子系统给用户层提供的是input_event结构体,我们主要是在应用层接收这个结构体,然后对其类型进行分类,取出我们需要的数值。
struct input_event { struct timeval time;
unsigned short type; //支持的类型,如EV_ABS
unsigned short code; //支持的具体事件,如坐标事件的ABS_X
unsigned int value; //值
};
测试触摸屏驱动的应用层代码如下
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/fcntl.h>
int main(int argc, char *argv[])
{
int fd = -1;
int num;
size_t rb;
int version;
char name[20];
struct input_event ev;
int i=0;
if ((fd = open("/dev/input/event0", O_RDONLY)) < 0) //打开设备
{
perror("open error");
exit(1);
}
while(1)
{
rb = read(fd, &ev, sizeof(struct input_event)); //读取设备
if (rb < (int)sizeof(struct input_event)) //读取错误
{
perror("read error");
exit(1);
}
if (EV_ABS==ev.type) //读取按键内容
{
printf("event=%s,value=%d
",ev.code==ABS_X?"ABS_X":ev.code==ABS_Y?"ABS_Y":ev.code==ABS_PRESSURE?"ABS_PRESSURE":"UNKNOWEN",ev.value);
}else{
printf("not ev_abs
");
}
}
close(fd);
return 0;
}
编译测试程序test.c
arm-linux-gcc test.c –o test
超级终端:
./test
测试结果:(触笔按下触摸屏)
event=ABS_X, value=505
event=ABS_Y, value=334
event=ABS_PRESSURE, value=1
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11