以前调试触摸屏很快就搞定了,现在Linux内核下调试还挺繁琐。
遇到的问题:
初始化时,注册了tc中断与adc中断。首先进入tc中断, 在tc中断服务程序中,开启启动adc
注册中断
if((ret = request_irq(IRQ_ADC, irq_isr_2, IRQF_SHARED|IRQF_SAMPLE_RANDOM, "sharpzou-Adc", ts_devp)) != 0)
printk(KERN_ALERT"irq_adc REQUEST_IRQ Fail %d ! /n", ret);
if( (ret = request_irq(IRQ_TC, irq_isr, IRQF_SAMPLE_RANDOM | IRQF_SHARED, "sharpzou-TouchS ", ts_devp)) != 0)
{
printk(KERN_ALERT"REQUEST_IRQ Fail %d ! /n", ret);
}
设置pin脚, GPIO的复用功能
//set pin config
s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);
s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);
s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);
s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);
初始化设置,分频、 延时、 开启tc的等待中断模块
//set reg
iowrite32(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF), reg_base + S3C2410_ADCCON);
iowrite32(0xffff, reg_base + S3C2410_ADCDLY);
iowrite32(WAIT4INT(0), reg_base + S3C2410_ADCTSC); //0x0d3
TC中断程序
static irqreturn_t irq_isr(int irq, void *dev_id)
{
printk(KERN_ALERT"Touch screen ISR!---Ready for ADC INT/n");
irq_cnt++;
printk(KERN_ALERT"Now ADCTSC=%x, ADCCON=%x /n",ioread32(reg_base+S3C2410_ADCTSC), ioread32(reg_base + S3C2410_ADCCON));
设置adc为 x/y轴坐标自动转换模式与设置引脚电路
//disable XP pull-up, enable auto x/y convert
此处设置的ADCTSC为非等待中断模式
//iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE |AUTOPST , reg_base + S3C2410_ADCTSC);
iowrite32(ioread32(reg_base+S3C2410_ADCCON)|(0x1), reg_base + S3C2410_ADCCON); //ADCON
//clear interrupt flag
iowrite32((0x1<<9) , reg_irq_base + 0x18);
iowrite32((0x1<<31) , reg_irq_base + 0x0);
iowrite32((0x1<<31) , reg_irq_base + 0x10);
return 1;
}
ADC中断服务函数
static irqreturn_t irq_isr_2(int irq, void *dev_id)
{
unsigned long data0;
unsigned long data1;
int updown = 0;
// printk(KERN_ALERT"This is ADC ISR!/n");
// printk(KERN_ALERT"Now ADCTSC=%x, ADCCON=%x /n",ioread32(reg_base+S3C2410_ADCTSC), ioread32(reg_base + S3C2410_ADCCON));
为什么? 只在触摸屏在等待中断模式下才能使用ADCDAT0查询按键的状态
iowrite32(WAIT4INT(0), reg_base + S3C2410_ADCTSC); //0x0d3
读取寄存器,主要为了获得按键的状态与键值
data0 = ioread32(reg_base + S3C2410_ADCDAT0);
data1 = ioread32(reg_base + S3C2410_ADCDAT1);
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
printk(KERN_ALERT"data0=%x, data1=%x , updown = %d ,irq1_cnt = %d/n", data0, data1, updown,irq_cnt);
printk(KERN_ALERT"Now1 ADCTSC=%x, ADCCON=%x /n",ioread32(reg_base+S3C2410_ADCTSC), ioread32(reg_base + S3C2410_ADCCON));
if(updown)
{
如果按键未松手,读取键值,并开启ADC启动位(ADC启动位在启动后会自动清零)
// iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE |AUTOPST , reg_base + S3C2410_ADCTSC);
iowrite32(ioread32(reg_base+S3C2410_ADCCON)|(0x1), reg_base + S3C2410_ADCCON); //ADCON
}
else //wait for now touch
{
如果此时已经松手,则退出,等待下一次的tc中断
iowrite32(WAIT4INT(0), reg_base + S3C2410_ADCTSC); //0x0d3
}
printk(KERN_ALERT"Now3 ADCTSC=%x, ADCCON=%x /n",ioread32(reg_base+S3C2410_ADCTSC), ioread32(reg_base + S3C2410_ADCCON));
//clear interrupt flag
iowrite32((0x1<<10) , reg_irq_base + 0x18);
iowrite32((0x1<<31) , reg_irq_base + 0x0);
iowrite32((0x1<<31) , reg_irq_base + 0x10);
return 1;
}
关于寄存器的设置于状态值的读取比较繁琐。
需要注意的是 ADCDAT0/1 寄存器的最高位,即触摸屏的按下状态只有在等待中断模块下才有效,其它情况下都无效。
关于寄存器的设置最重要的就是上面寄存器的读取,其它关于adc的寄存器设置较简单。如果没有改变在等待中断情况下读取的话会造成误读,逻辑混乱。
由于判断键是否按下需要在等待中断模式下,所在在adc中断函数中判断键是否按下比较困难,但是读取键值是没有问题的,可以考虑按键是否按下放在其他地方判断,如引入定时器放入定时器函数,adc中断函数只进行读键值与判断进入的次数等。
这里的按下后坐标的读取采用的adc自身中断并已最大速度的循环触发,这种方式应该不是很可取的,应该另开定时器,定时循环获取坐标值,在TC中断函数开启定时器, 在定时器函数里面控制adc中断。(下一步添加定时器机制)
接下来该添加INPUT输入子系统,提供用户端的接口。