lvgl / lv_port_linux

LVGL configured to work with a standard Linux framebuffer
MIT License
208 stars 140 forks source link

evdev_read callback denies non-zero ABS_MT_TRACKING_ID in touchscreen. #40

Closed SoMuchDay closed 8 months ago

SoMuchDay commented 8 months ago

Sorry for my english first because english is not my first language :( I'm new in embedded part, and also new in LVGL. Not that old in programming, actually. I've tried to write simple sample code that rotates image with screen touch, but it doesn't work after first touch. Plus, it doesn't work at all if I touch screen before app starts. So I assumed it my code's problem, and uploaded to my board demo app already exists - but it also have same symptom. I tried to debug as insert printf() at many points, and I found these lines in evdev.c. (152 - 157)

            else if(in.code == ABS_MT_TRACKING_ID) {
                                if(in.value == -1)
                                    evdev_button = LV_INDEV_STATE_REL;
                                else if(in.value == 0)
                                    evdev_button = LV_INDEV_STATE_PR;
            }

So I searched linux documents about that flag, and found this section. Multi-touch Protocol, 3.2. Protocol Usage.

For type B devices, the kernel driver should associate a slot with each identified contact, and use that slot to propagate changes for the contact. Creation, replacement and destruction of contacts is achieved by modifying the ABS_MT_TRACKING_ID of the associated slot. A non-negative tracking id is interpreted as a contact, and the value -1 denotes an unused slot. A tracking id not previously present is considered new, and a tracking id no longer present is considered removed. Since only changes are propagated, the full state of each initiated contact has to reside in the receiving end. Upon receiving an MT event, one simply updates the appropriate attribute of the current slot.

Some devices identify and/or track more contacts than they can report to the driver. A driver for such a device should associate one type B slot with each contact that is reported by the hardware. Whenever the identity of the contact associated with a slot changes, the driver should invalidate that slot by changing its ABS_MT_TRACKING_ID. If the hardware signals that it is tracking more contacts than it is currently reporting, the driver should use a BTNTOOLTAP event to inform userspace of the total number of contacts being tracked by the hardware at that moment. The driver should do this by explicitly sending the corresponding BTNTOOLTAP event and setting use_count to false when calling input_mt_report_pointer_emulation(). The driver should only advertise as many slots as the hardware can report. Userspace can detect that a driver can report more total contacts than slots by noting that the largest supported BTNTOOL*TAP event is larger than the total number of type B slots reported in the absinfo for the ABS_MT_SLOT axis.

and it also says type A devices has been deprecated at section 3.1:

Note MT protocol type A is obsolete, all kernel drivers have been converted to use type B.

So I understand it as ABS_MT_TRACKING_ID should increase for identify each touch events - at least to multi-touch device - so I tried to evtest. and this is result. It seems too long but I didn't cut because If upper section of device helps:

No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      gpio_keys_polled
/dev/input/event1:      ssd253x
Select the device event number [0-1]: 1
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: "ssd253x"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 330 (BTN_TOUCH)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value      0
      Min        0
      Max      799
    Event code 1 (ABS_Y)
      Value      0
      Min        0
      Max      479
    Event code 47 (ABS_MT_SLOT)
      Value      0
      Min        0
      Max        9
    Event code 53 (ABS_MT_POSITION_X)
      Value      0
      Min        0
      Max      799
    Event code 54 (ABS_MT_POSITION_Y)
      Value      0
      Min        0
      Max      479
    Event code 57 (ABS_MT_TRACKING_ID)
      Value      0
      Min        0
      Max    65535
    Event code 58 (ABS_MT_PRESSURE)
      Value      0
      Min        0
      Max       16
Properties:
  Property type 1 (INPUT_PROP_DIRECT)
Testing ... (interrupt to exit)
Event: time 1697531620.958962, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 9
Event: time 1697531620.958962, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 398
Event: time 1697531620.958962, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 209
Event: time 1697531620.958962, -------------- EV_SYN ------------
Event: time 1697531620.975913, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 11
Event: time 1697531620.975913, -------------- EV_SYN ------------
Event: time 1697531620.985108, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 397
Event: time 1697531620.985108, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 208
Event: time 1697531620.985108, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 9
Event: time 1697531620.985108, -------------- EV_SYN ------------
Event: time 1697531621.002052, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 207
Event: time 1697531621.002052, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 5
Event: time 1697531621.002052, -------------- EV_SYN ------------
Event: time 1697531621.011285, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 394
Event: time 1697531621.011285, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 205
Event: time 1697531621.011285, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 1
Event: time 1697531621.011285, -------------- EV_SYN ------------
Event: time 1697531621.024135, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1
Event: time 1697531621.024135, -------------- EV_SYN ------------
Event: time 1697531621.874388, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 10
Event: time 1697531621.874388, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 413
Event: time 1697531621.874388, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 213
Event: time 1697531621.874388, -------------- EV_SYN ------------
Event: time 1697531621.891331, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 214
Event: time 1697531621.891331, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 11
Event: time 1697531621.891331, -------------- EV_SYN ------------
Event: time 1697531621.908274, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 9
Event: time 1697531621.908274, -------------- EV_SYN ------------
Event: time 1697531621.942142, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 213
Event: time 1697531621.942142, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 5
Event: time 1697531621.942142, -------------- EV_SYN ------------
Event: time 1697531621.959085, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 211
Event: time 1697531621.959085, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 1
Event: time 1697531621.959085, -------------- EV_SYN ------------
Event: time 1697531621.965738, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1
Event: time 1697531621.965738, -------------- EV_SYN ------------
Event: time 1697531632.638183, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 11
Event: time 1697531632.638183, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 436
Event: time 1697531632.638183, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 185

Most of ABS_MT_TRACKING_ID seems to have non-zero value - so I changed evdev.c to following lines:

            else if(in.code == ABS_MT_TRACKING_ID) {
                                printf("in.code is ABS_MT_TRACKING_ID: %d\n", in.value);
                                if(in.value == -1)
                                    evdev_button = LV_INDEV_STATE_REL;
---                                else if(in.value == 0)
+++                                else                               
                                    evdev_button = LV_INDEV_STATE_PR;
            }

Because I thought all of non-negative value of ABS_MT_TRACKING_ID means touchscreen has pressed. And then I tested my app and demo app again - It works fine.

I think it could be merge to origin because it will be no harm, but I'll be appreciated to tell me if I missed something or wrong.

SoMuchDay commented 8 months ago

Oh and It was lv_drivers issue :p sorry for my bad

SoMuchDay commented 8 months ago

Nevermind. It was device's malfunction :( ABS_MT_TRACKING_ID has to be clear when touch releases but strangely it doesn't. sorry to bother you

kisvegabor commented 8 months ago

Happy to hear that it was resolved :slightly_smiling_face: