Linux下的触摸屏驱动
作者:网络转载 发布时间:[ 2013/1/10 10:03:12 ] 推荐标签:
在这个AD转换的中断程序中,有一个全局变量count令人费解,count是什么作用呢?我们做AD转换时,其实是对一个点进行了四次采样,然后把四次采样结果进行叠加然后取平均。这样提高AD转换的精确度。在上面这个AD转换的中断处理程序中,我们知道,当count不足4次时,会继续进行自动连续测量X和Y坐标并开启AD转换,只有当AD转换次数达到四次后,会修改定时器的时间,使得下一个节拍到来时执行定时器处理程序,并且等待按键被释放。当AD转换完毕,我们在下一个节拍到来后,会执行一次定时器程序touch_timer_fire
static void touch_timer_fire(unsigned long data)
{
unsigned long data0;
unsigned long data1;
int updown;
data0 = ioread32(base_addr+S3C2410_ADCDAT0);
data1 = ioread32(base_addr+S3C2410_ADCDAT1);
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
if (updown) { //触摸屏被按下
if (count != 0) { //count是全局变量,统计AD转换次数,目前已经4次
long tmp;
tmp = xp;
xp = yp;
yp = tmp; // X和Y轴数据交换
xp >>= 2; //因为对同一个点采样四次,这里对X轴取平均
yp >>= 2; //因为对同一个点采样四次,这里对Y轴取平均
input_report_abs(dev, ABS_X, xp); //报告X坐标
input_report_abs(dev, ABS_Y, yp); //报告Y坐标
input_report_key(dev, BTN_TOUCH, 1); //报告触摸事件
input_report_abs(dev, ABS_PRESSURE, 1);
input_sync(dev); //同步
}
xp = 0; //清零
yp = 0;
count = 0;
//自动连续测量X和Y坐标
iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
//AD转换开始且该位在开始后清零
iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
} else {
count = 0;
input_report_key(dev, BTN_TOUCH, 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);
}
}
}
这里首先解释下,为什么要对X和Y坐标值交换,因为我们的X35LCD屏是240*320的,为了满足用户“X轴长Y轴短”的习惯,在此进行X和Y坐标值交换,当然在此不交换,不会影响触摸屏驱动的运行。
我们这次分析这个定时器touch_timer_fire,终发现我们不但向input子系统报告了我们的坐标值,还对坐标变量和统计AD转换次数变量清零,后还打开了AD转换开关,既然这次触摸事件已经结束,那么这里怎么还打开AD转换开关呢?其实,如果你足够细心,你会发现,虽然AD开关打开了,然后会执行AD转换的中断处理程序,一旦进入AD转换,肯定也是转换四次,然后在下一个节拍到来时,执行定时程序,关键的是,此时我们的触摸屏按键已经释放了,在这一的背景下,我们再次跟踪定时函数touch_timer_fire
static void touch_timer_fire(unsigned long data)
{
unsigned long data0;
unsigned long data1;
int updown;
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) {
long tmp;
tmp = xp;
xp = yp;
yp = tmp;
xp >>= 2;
yp >>= 2;
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; //初始化count为0,表示当前AD转换没发生
input_report_key(dev, BTN_TOUCH, 0); //向input子系统报告未按下
input_report_abs(dev, ABS_PRESSURE, 0); //触摸屏是抬起状态
input_sync(dev);
iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC); //等待按键中断
if (OwnADC) { //OwnADC是获取一把锁标示,在此为1
OwnADC = 0; //该锁标志为0,表示释放该锁
up(&ADC_LOCK); //释放锁
}
}
}
相关推荐
更新发布
功能测试和接口测试的区别
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