可以看到当我们需要设置等待中断模式时只需要把adctsc寄存器设置为0xd3即可
2、s3c_ts_timer_function(定时器处理函数)
static void s3c_ts_timer_function(unsigned long data)
{
IF (s3c_ts_regs->adcdat0 & (1<<15)) /*判断是否按下,adcdat0第十五位如果是1为松开,是0为按下*/
{
/* 已经松开 */
/*上报事件*/
input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);
input_report_key(s3c_ts_dev, BTN_TOUCH, 0);
input_sync(s3c_ts_dev); /*上报完成*/
enter_wait_pen_down_mode(); /*等待按下*/
}
else
{
/* 测量X/Y坐标 */
enter_measure_xy_mode();
start_adc();
}
}
3、enter_measure_xy_mode()(坐标测量函数)
static void enter_measure_xy_mode(void)
{
s3c_ts_regs->adctsc = (1<<3)|(1<<2);
}
4、start_adc()(开始adc转换)
static void start_adc(void)
{
s3c_ts_regs->adccon |= (1<<0);
}
接下来是比较重头的两个中断处理函数了5、pen_down_up_irq()(当触摸屏按下时的中断处理函数)
当我们按下触摸屏进入到我们的中断处理函数 pen_down_up_irq()中后我们还需要判断是否仍旧是按下状态
static irqreturn_t pen_down_up_irq(int irq, void *dev_id)
{
if(s3c_ts_regs->adcdat0 & (1<<15)) /*判断是否按下,adcdat0第十五位如果是1为松开,是0为按下*/
{
// printk("pen up\n");
enter_wait_pen_down_mode(); /*等待按下处理函数*/
}
else
{
//printk("pen down\n");
//enter_wait_pen_up_mode();
enter_measure_xy_mode(); /*测量xy坐标函数*/
start_adc(); /*adc转换函数*/
}
return IRQ_HANDLED;
}
6、adc_irq()(AD转换完成后产生的ADC中断)
static irqreturn_t adc_irq(int irq, void *dev_id)
{
static int cnt = 0;
static int x[4], y[4];
int adcdat0, adcdat1;
/* 优化措施2: 如果ADC完成时, 发现触摸笔已经松开, 则丢弃此次结果 */
adcdat0 = s3c_ts_regs->adcdat0;
adcdat1 = s3c_ts_regs->adcdat1;
if (s3c_ts_regs->adcdat0 & (1<<15))
{
/* 已经松开 */
cnt = 0;
input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0);
input_report_key(s3c_ts_dev, BTN_TOUCH, 0);
input_sync(s3c_ts_dev);
enter_wait_pen_down_mode();
}
else
{
// printk("adc_irq cnt = %d, x = %d, y = %d\n", ++cnt, adcdat0 & 0x3ff, adcdat1 & 0x3ff);
/* 优化措施3: 多次测量求平均值 */
x[cnt] = adcdat0 & 0x3ff;
y[cnt] = 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(s3c_ts_dev, ABS_X, (x[0]+x[1]+x[2]+x[3])/4);
input_report_abs(s3c_ts_dev, ABS_Y, (y[0]+y[1]+y[2]+y[3])/4);
input_report_abs(s3c_ts_dev, ABS_PRESSURE, 1);
input_report_key(s3c_ts_dev, BTN_TOUCH, 1);
input_sync(s3c_ts_dev);
}
cnt = 0;
enter_wait_pen_up_mode();
/* 启动定时器处理长按/滑动的情况 */
mod_timer(&ts_timer, jiffies + HZ/100);
}
else
{
enter_measure_xy_mode();
start_adc();
}
}
return IRQ_HANDLED;
}
第三大部分:出口函数
出口函数的作用就是释放在入口函数中申请的各个内存空间而已
static void s3c_ts_exit(void){
free_irq(IRQ_TC, NULL);free_irq(IRQ_ADC, NULL);iounmap(s3c_ts_regs);input_unregister_device(s3c_ts_dev);input_free_device(s3c_ts_dev);del_timer(&ts_timer);}
到这里一个相对简单的触摸屏驱动程序就基本算是完成了,接下来需要做的就是利用tslib来对触摸屏驱动程序进行调试,这部分的内容如果放在这里讲就显得有点累赘了,朋友们可以去度娘上查查资料或者直接参照韦东山老师第二期视频的第16课的第三节“触摸屏驱动程序之使用TSLIB测试”这一节的内容
谢谢大家观看,希望各位多多提出本帖不足,热烈欢迎大家进帖讨论和分享学习经验。