Task Handler started but never completes?

Description

lv_indev_read_task: indev read task started but never finishes.

What MCU/Processor/Board and compiler are you using?

Adafruit Feather M4 using the FeatherWing TFT with TS input.

What do you experience?

Happens frequently when using touch screen input to trigger buttons etc. The buttons get “stuck” inbetween states and essentially pause all task handling.

What do you expect?

Task handler should never pause and whatever infinite loops it iswaiting on needs to timeout, or I need to have a way to handle the timeout in the touch screen callback (maybe I already can? but not sure how to do so).

Code to reproduce

Nothing specific, any button I create since I started using LVGL has done this… also tabs in tabviews etc. It’s not widget specific, it’s related to the touch screen handling.

TS callback looks like this:

bool input_ts(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
    TouchPoint p;

    // save the state and save the pressed coordinate
    data->state = ts.touched() ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
    if (data->state == LV_INDEV_STATE_PR)
    {
        p = ts.getPoint();
        last_y = map(p.x, TS_MINX, TS_MAXX, 0, tft.height());
        last_x = map(p.y, TS_MINY, TS_MAXY, 0, tft.width());
    }

    // set the coordinates (if released use the last pressed coordinates)
    data->point.x = last_x;
    data->point.y = last_y;

    return !ts.bufferEmpty();
}

TRACE level logs look like this (you can see a normal task handler output with my own logging in the middle, then the failed task handling ending in an infinite loop of indev stop and start read):

TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_core/lv_indev.c129: _lv_indev_read_task: indev read task finished
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_core/lv_indev.c77: _lv_indev_read_task: indev read task started
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c153: _lv_indev_read: idnev read started
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c155: _lv_indev_read: idnev read finished
F: 0 0 <=> 1 0 0, 0 0 <=> 1 0 1, 1 0 <=> 2 0 0, 1 1 <=> 2 0 1, 2 1 <=> 1 1 1, FOUND
F: 0 0 <=> 1 0 0, 0 0 <=> 1 0 1, 1 0 <=> 2 0 0, 1 1 <=> 2 0 1, 2 1 <=> 1 1 1, FOUND
D: 2 1 <=> 1 1 1,
C: 0 0 <=> 1 1 1,
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_core/lv_indev.c129: _lv_indev_read_task: indev read task finished
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_core/lv_refr.c177: _lv_disp_refr_task: lv_refr_task: started
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_core/lv_refr.c310: _lv_disp_refr_task: lv_refr_task: ready
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_core/lv_indev.c77: _lv_indev_read_task: indev read task started
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c153: _lv_indev_read: idnev read started
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c155: _lv_indev_read: idnev read finished
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_core/lv_indev.c129: _lv_indev_read_task: indev read task finished
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_core/lv_indev.c77: _lv_indev_read_task: indev read task started
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c153: _lv_indev_read: idnev read started
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c155: _lv_indev_read: idnev read finished
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c153: _lv_indev_read: idnev read started
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c155: _lv_indev_read: idnev read finished
TRACE: File: .pio/libdeps/adafruit_feather_m4/lvgl/src/lv_hal/lv_hal_indev.c153: _lv_indev_read: idnev read started
... 
(TO INFINITY AND BEYOND!!!)

Screenshot and/or video

When “stuck”, buttons have a STATE that is inbetween PRESSED and RELEASED (I have other photos but can only upload one):

Given the code snippet, I’m 99% sure you want to always return false from input_ts. I don’t know if that will solve your problem but returning true almost always results in undesirable behavior.

@embeddedt Thanks for the quick response. Swapping my buffer check to always return false worked like a charm!

@kisvegabor Perhaps we should consider removing this feature from the core library. I’ve personally never used it, and confusion surrounding it seems to be a common cause of input-related issues.

Even having spent some time delving into the core code it would have taken me a while to realize the cause of the lock up.