This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

am335x 触摸屏无法触发抬起中断

Other Parts Discussed in Thread: AM3358

各位你们好:

我用的是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

  • 在驱动中断处理函数出入口加些打印看看

    是不是上次中断没有退出?

  • 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

  • 好像找到原因了,在probe中发现,触摸屏的PEN_UP,PEN_DOWN中断均未使能。

    很难理解,为什么触摸屏驱动中会不使能按下和抬起中断?谁能帮忙解释下驱动为什么这么设计?

  • 印象里Linux的输入设备有很多触发方式,TS的驱动用的好像不是PEN_UP/DOWN的触发方式。

  • 周工:

          那触发方式是什么?在触摸驱动中,在收到中断后,根据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";
    };
    };

  • 我看到的驱动,是只有TSCADC_IRQENB_PENUP这个事件,而没有PENDOWN。

  • 周工:

         你看的版本是哪个?我用的是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);

  • 我看了下差不多的版本,在中断里是有对IRQENB_PENUP这个事件的处理。

  • 是的,触摸屏的中断函数里有对PENUP做处理,但现在的问题是当PENUP的时候,触摸屏的中断函数收不到中断,也就无法处理PENUP

  • 应该是ADC的驱动里的登记的中断源被触发才能到中断函数里,然后再对PENUP事件进行处理。

  • 是的,理论上是这样子,但是实际使用过程中发现IRQSTATUS_RAW寄存器的pen_up_event[9]这一位置1不会触发中断。

    所以我想知道中断源被触发,然后调用触摸屏驱动的中断函数,这个执行过程的代码在哪里,我想调试下,在PEN_UP的情况下,会不会产生中断

  • ti_am335_tsc.c probe函数中有,

    /*! Update Pen Down IRQ */
    irq_pendown = ts_dev->irq;
    err = request_irq(irq_pendown, ***, IRQF_SHARED, pdev->dev.driver->name, ts_dev);

    所以是只有pen down产生才会进入中断处理程序吗,那如何让 pen up 事件也能产生触发中断进到中断函数中呢?

    是需要再重新 request_irq(irq_penup, ***, IRQF_SHARED, pdev->dev.driver->name, ts_dev); 吗?

    也就是说TI提供的ti_am335_tsc.c 本身就不支持处理pen up事件是吗?