Support for Python3

Note that, lv_indev_act() is valid only in events and signals when there are an active (being processed) indev. Instead, I suggest using lv_indev_next() to get the first indev:

p = lv.point_t()
lv.indev_get_point(lv.indev_next(null), p)
print("x=%d, y=%d" % (p.x, p.y))

Thanks for pointing this out.
Instead of null, you need to pass None.

1 Like

Uncommented as you suggested and recompiled. Here’s what I see while pressing down on the touchscreen:

xpt7603_read data: x = 57, y = 55, pressed = 1, state = 1
xpt7603_read data: x = 57, y = 55, pressed = 1, state = 1
xpt7603_read data: x = 58, y = 55, pressed = 1, state = 1
xpt7603_read data: x = 58, y = 55, pressed = 1, state = 1
xpt7603_read data: x = 59, y = 56, pressed = 1, state = 1
xpt7603_read data: x = 58, y = 55, pressed = 1, state = 1

And then when I let go:

xpt7603_read data: x = 58, y = 55, pressed = 0, state = 0
xpt7603_read data: x = 58, y = 55, pressed = 0, state = 0
xpt7603_read data: x = 58, y = 55, pressed = 0, state = 0

For reference, data->state is an enum:

enum { LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR };

So it looks like the driver is correctly reading the interrupt and touch input.
But still no print statements from my button event callback. (My button is at 50,50)

Am I correctly setting up the button and event callback?


I tried to follow your suggestion to read the coordinates from the script, but ran into issues.

I added the following code to my infinite while loop:

        p = lv.point_t()
        lv.indev_get_point(lv.indev_next(None), p)
        print("x=%d, y=%d" % (p.x, p.y))

But when I run the script, I get an error:

  File "fbtouchtest.py", line 64, in <module>
AttributeError: 'module' object has no attribute 'indev_next'

That should be lv.indev_get_next, instead of indev_next.
Give it a try.

One problem I noticed in your code:

According to the docs, the read callback function should return false when there is no more data to read.
However, your read callback is returning valid.

I also find it confusing that the read function should return false when it succeeds.
@kisvegabor - how about changing this for future releases? I’ve already seen number of people fall in this.

Wasn’t this problem already corrected here?

Changed it to use lv.indev_get_next(None) but then it gives me an error:

  File "fbtouchtest.py", line 64, in <module>
SyntaxError: Can't convert NoneType to lv_indev_t!

If I try it with no arguments, lv.indev_get_next():

  File "fbtouchtest.py", line 64, in <module>
TypeError: function takes 1 positional arguments but 0 were given

Also tried creating a temporary variable tmp = lv.indev_t() and passing that to lv.indev_get_next but then I just get

x=-1, y=-1

Is there a way I can create an indev_t typed variable and set it to None?


That’s right, this was fixed. The Omega2 Dash uses the XPT7603

indev_get_next expects lv_indev_t type.
You can set it to NULL like this: lv.indev_t(None).
I agree it would be more intuitive to use None directly, I’ve added an issue to track this.

Right.
I didn’t notice any other problem with your code. The way you register the driver looks fine and the fact that your read function is called by lvgl shows that it was registered correctly.

So I suggest debugging this:

  • with lv.indev_get_point as discussed
  • with printings in lvgl code
  • with a a debugger, if that’s available.

@amirgon Thanks for your continued support on this!

I tried this out:

tmp = lv.indev_t(None)

print('starting loop')
while True:
        p = lv.point_t()
        lv.indev_get_point(lv.indev_get_next(tmp), p)
        print("x=%d, y=%d" % (p.x, p.y))

And I get this error:

Traceback (most recent call last):
  File "fbtouchtest.py", line 57, in <module>
SyntaxError: Can't convert NoneType to lv_indev_t!

Where line 57 is tmp = lv.indev_t(None)

Looks like indev_t also expects a lv_indev_t type. Seems like a chicken and egg type of thing?


Do you have any suggestions on where I should start looking with a debugger?

Sorry - the correct syntax is: tmp = lv.indev_t.cast(None)
That should work.

I’d probably start with the call site of your callback:

then single-step through and try to understand how the point coordinates and state are used (or why they are not).
Perhaps @embeddedt or @kisvegabor could give some tips what you should look at.

Awesome! That works!

I see this type of output:

xpt7603_read data: x = 80, y = 71, pressed = 1, state = 1
x=-1, y=-1
x=-1, y=-1
...
xpt7603_read data: x = 80, y = 71, pressed = 0, state = 0
x=-1, y=-1
...

Now we know the driver correctly reads the touch input coordinates but doesn’t pass it along.

Once I get a debugger up and running to check out the call site of indev driver read callback, I’ll report back.

Thanks for your help!

1 Like

I fixed that, now you can use lv.indev_get_next(None)

Closing the loop here! Fixed the issue with touch input!

The root cause was kind of silly. The xpt7603_read function did not have the two arguments expected by the read_cb function pointer in lv_indev_drv_t

So it would read the touch input coordinates from the device correctly. But because of the incorrect arguments the coordinates did not get propagated to the rest of the code.

The fix is here:

A silly issue but difficult to debug.

Note that I copied the structure of my xpt7603 driver from the existing xpt2046 implmentation. It has the same issue: https://github.com/lvgl/lv_binding_micropython/blob/master/driver/esp32/modxpt2046.c#L209

Thanks for the update!

The driver which is officially supported is xpt2046.py, where I believe the problem is not present.