各位你们好:
我用的是AM3358,ti-processor-sdk-linux-am335x-evm-03.02.00.05
在调试触摸屏的过程中发现了以下问题,请指教
在触摸屏使用过程中,大概5次点击屏幕,会出现一次最后一次采样结束,PENUP中断没有触发。
通过读取寄存器RAWSTATUS
发现PENUP的中断标志是被置1了,但是驱动中中断线程没有被调用到。
下面这个就是抬起中断未触发读出来的值。
Read at address 0x44E0D024 (0xb6f92024): 0x00000600
root@am335x-evm:~# devmem2 0x44e0d024 w[0x00000402]
/dev/mem opened.
Memory mapped at address 0xb6fb1000.
Read at address 0x44E0D024 (0xb6fb1024): 0x00000600
而正常抬起中断触发后,读出来的值
root@am335x-evm:~# devmem2 0x44e0d024
/dev/mem opened.
Memory mapped at address 0xb6fe8000.
Read at address 0x44E0D024 (0xb6fe8024): 0x00000400
Denny%20Yang99373:
在驱动中断处理函数出入口加些打印看看
是不是上次中断没有退出?
zizhen hu:
回复 Denny%20Yang99373:
hi denny:
中断是退出了的,因为下一次再去触点,中断的产生没有问题。
然后,如果手动在写寄存器0x603之类的,也会打印出中断信息。
从调试信息来看,感觉好像抬起的时候,没有触发FIFO就不会触发中断。请看下面的log。
这一个是没有触发抬起中断的Log.
[huzz]titsc_irq:irq_status=0x605[huzz]titsc_irq:IRQENB_HW_PEN[huzz]titsc_irq:IRQENB_PENUP[huzz]titsc_irq:IRQENB_FIFO0THRES[huzz]titsc_read_coordinates:xtemp=20,ytemp=16[huzz]titsc_irq:calc,x=2743,y=1622,z=176[huzz]titsc_irq:irq_status=0x402[huzz]titsc_irq:irq_status=0x404[huzz]titsc_irq:IRQENB_FIFO0THRES[huzz]titsc_read_coordinates:xtemp=22,ytemp=13[huzz]titsc_irq:calc,x=2747,y=1615,z=175[huzz]titsc_irq:irq_status=0x403[huzz]titsc_irq:IRQENB_HW_PEN[huzz]titsc_irq:irq_status=0x404[huzz]titsc_irq:IRQENB_FIFO0THRES[huzz]titsc_read_coordinates:xtemp=31,ytemp=24[huzz]titsc_irq:irq_status=0x403[huzz]titsc_irq:IRQENB_HW_PEN
这个是正常的log
[huzz]titsc_irq:irq_status=0x605[huzz]titsc_irq:IRQENB_HW_PEN[huzz]titsc_irq:IRQENB_PENUP[huzz]titsc_irq:IRQENB_FIFO0THRES[huzz]titsc_read_coordinates:xtemp=7,ytemp=12[huzz]titsc_irq:calc,x=1606,y=1088,z=224[huzz]titsc_irq:irq_status=0x402[huzz]titsc_irq:irq_status=0x404[huzz]titsc_irq:IRQENB_FIFO0THRES[huzz]titsc_read_coordinates:xtemp=9,ytemp=29[huzz]titsc_irq:irq_status=0x403[huzz]titsc_irq:IRQENB_HW_PEN[huzz]titsc_irq:irq_status=0x404[huzz]titsc_irq:IRQENB_FIFO0THRES[huzz]titsc_read_coordinates:xtemp=11,ytemp=12[huzz]titsc_irq:calc,x=1586,y=1046,z=231[huzz]titsc_irq:irq_status=0x403[huzz]titsc_irq:IRQENB_HW_PEN[huzz]titsc_irq:irq_status=0x404[huzz]titsc_irq:IRQENB_FIFO0THRES[huzz]titsc_read_coordinates:xtemp=9,ytemp=39[huzz]titsc_irq:irq_status=0x603[huzz]titsc_irq:IRQENB_HW_PEN[huzz]titsc_irq:IRQENB_PENUP
zizhen hu:
回复 Denny%20Yang99373:
好像找到原因了,在probe中发现,触摸屏的PEN_UP,PEN_DOWN中断均未使能。
很难理解,为什么触摸屏驱动中会不使能按下和抬起中断?谁能帮忙解释下驱动为什么这么设计?
Jian Zhou:
回复 zizhen hu:
印象里Linux的输入设备有很多触发方式,TS的驱动用的好像不是PEN_UP/DOWN的触发方式。
zizhen hu:
回复 Jian Zhou:
周工:
那触发方式是什么?在触摸驱动中,在收到中断后,根据IRQSTATUS_RAW的寄存器来来判断触摸状态并处理。现在碰到的问题是,当我触摸抬起的时候,根本进不了这个函数,也就无法进行后续处理。但是用devmem2读取这个寄存器,发现pen_up_event是被置1了的。这是am335x没有收到adc芯片的中断还是怎么回事?
static irqreturn_t titsc_irq(int irq, void *dev){ struct titsc *ts_dev = dev; struct input_dev *input_dev = ts_dev->input; unsigned int fsm, status, irqclr = 0; unsigned int x = 0, y = 0; unsigned int z1, z2, z;
status = titsc_readl(ts_dev, REG_RAWIRQSTATUS);// printk("[huzz]%s:irq_status=0x%x\n",__func__,status); if (status & IRQENB_HW_PEN) {// printk("[huzz]%s:IRQENB_HW_PEN\n",__func__); ts_dev->pen_down = true; irqclr |= IRQENB_HW_PEN; pm_stay_awake(ts_dev->mfd_tscadc->dev); }
if (status & IRQENB_PENUP) {// printk("[huzz]%s:IRQENB_PENUP\n",__func__); fsm = titsc_readl(ts_dev, REG_ADCFSM); if (fsm == ADCFSM_STEPID) { ts_dev->pen_down = false; input_report_key(input_dev, BTN_TOUCH, 0); input_report_abs(input_dev, ABS_PRESSURE, 0); input_sync(input_dev); pm_relax(ts_dev->mfd_tscadc->dev); } else { ts_dev->pen_down = true; } irqclr |= IRQENB_PENUP; }
if (status & IRQENB_EOS) irqclr |= IRQENB_EOS;
/* * ADC and touchscreen share the IRQ line. * FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only */ if (status & IRQENB_FIFO0THRES) {
下面是am33xx.dtsi中的内容,触摸中断号是16吗?linux内核的中断处理机制是怎么处理这个中断号的?触摸屏在什么情况下会产生这个中断?周工,请帮忙分析一下,谢谢。我在ti的文档中没有找到关于CPU对于中断是如何接收和处理的。谢谢。
tscadc: tscadc@44e0d000 { compatible = "ti,am3359-tscadc"; reg = <0x44e0d000 0x1000>; interrupt-parent = <&intc>; interrupts = <16>; ti,hwmods = "adc_tsc"; status = "disabled";
tsc { compatible = "ti,am3359-tsc"; }; am335x_adc: adc { #io-channel-cells = <1>; compatible = "ti,am3359-adc"; }; };
Jian Zhou:
回复 zizhen hu:
我看到的驱动,是只有TSCADC_IRQENB_PENUP这个事件,而没有PENDOWN。
zizhen hu:
回复 Jian Zhou:
周工:
你看的版本是哪个?我用的是ti-processor-sdk-linux-am335x-evm-03.02.00.05
触摸驱动文件:drivers/input/touchscreen/ti_am335x_tsc.c
其在probe中配置了FIFO的中断,但是没有配置PENUP,PENDOWN中断。
if (device_may_wakeup(tscadc_dev->dev)) { err = dev_pm_set_wake_irq(tscadc_dev->dev, ts_dev->irq); if (err) dev_err(&pdev->dev, "irq wake enable failed.\n"); }
titsc_writel(ts_dev, REG_IRQSTATUS, IRQENB_MASK); titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_EOS);
Jian Zhou:
回复 zizhen hu:
我看了下差不多的版本,在中断里是有对IRQENB_PENUP这个事件的处理。
zizhen hu:
回复 Jian Zhou:
是的,触摸屏的中断函数里有对PENUP做处理,但现在的问题是当PENUP的时候,触摸屏的中断函数收不到中断,也就无法处理PENUP
Jian Zhou:
回复 zizhen hu:
应该是ADC的驱动里的登记的中断源被触发才能到中断函数里,然后再对PENUP事件进行处理。