Description
With master branch LVGL 9.1.1, SHA ID ac576a2bf4e00c7278fcbd3e704d997536eac508
I am testing lv_display_set_rotation
with Raspberry Pi and Linux fb
and found an issue and also managed to find a workaround with indev/evdev
. This only seems to be a problem once lv_display_set_rotation
is called, In my case to be 180 degrees, but I am guessing a problem will occur with any rotation other than 0 degrees.
Please see the code and explanations below.
What MCU/Processor/Board and compiler are you using?
Raspberry Pi 5 with official 7" touch screen running Raspberry Pi OS 64 - Bookworm.
What do you want to achieve?
To have the issue resolved without the need for a workaround.
Code to reproduce
#define POINT_CORRECTION 1
#define CALIBRATION_SET 1
static lv_indev_read_cb_t _indev_read_cb;
static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data)
{
_indev_read_cb(indev, data);
#if POINT_CORRECTION
data->point.x -= 800;
data->point.y -= 480;
#endif
static lv_point_t point_prev = {.x = -1, .y = -1};
if(data->state == LV_INDEV_STATE_PRESSED) {
if(memcmp(&point_prev, &data->point, sizeof(point_prev))) {
point_prev = data->point;
char buf[64];
sprintf(buf, "x=%3u;y=%3u", data->point.x, data->point.y);
const char * fn = __FILE__;
const char * slash = strrchr(fn, '/');
fn = slash ? slash + 1 : fn;
printf("%5s: %15s %4d, %20s, %s\n", "Dbg", fn, __LINE__, "Click", buf);
}
} else {
point_prev.x = -1;
point_prev.y = -1;
}
}
int main(void)
{
lv_init();
lv_display_t * disp = lv_linux_fbdev_create();
lv_linux_fbdev_set_file(disp, "/dev/fb0");
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_180);
lv_indev_t * indev = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event1");
#if CALIBRATION_SET
lv_evdev_set_calibration(indev, 0, 0, 799, 479);
#endif
_indev_read_cb = lv_indev_get_read_cb(indev);
lv_indev_set_read_cb(indev, _evdev_read);
lv_demo_widgets();
for(uint32_t ms;;) {
ms = lv_timer_handler();
usleep(ms*1000);
}
return 0;
}
Dump when running In each case below and touching the display in the center,
With POINT_CORRECTION = 0
and CALIBRATION_SET = 0
[Warn] (2064886.584, +0) indev_pointer_proc: Y is -1 which is smaller than zero lv_indev.c:654
[Warn] (2064886.617, +33) indev_pointer_proc: X is -1 which is smaller than zero lv_indev.c:648
[Warn] (2064886.617, +0) indev_pointer_proc: Y is -1 which is smaller than zero lv_indev.c:654
Dbg: main.c 172, Click, x=800;y=480
[Warn] (2064886.650, +33) indev_pointer_proc: X is -1 which is smaller than zero lv_indev.c:648
[Warn] (2064886.650, +0) indev_pointer_proc: Y is -1 which is smaller than zero lv_indev.c:654
[Warn] (2064886.683, +33) indev_pointer_proc: X is -1 which is smaller than zero lv_indev.c:648
With POINT_CORRECTION = 1
and CALIBRATION_SET = 0
Dbg: main.c 172, Click, x= 0;y= 0
With POINT_CORRECTION = 1
and CALIBRATION_SET = 1
Dbg: main.c 172, Click, x=449;y=257
Dbg: main.c 172, Click, x=449;y=256
Dbg: main.c 172, Click, x=448;y=253
So correcting the point by subtracting the displays horizontal and vertical resolutions from the point coords solves the problem but only if lv_evdev_set_calibration
has also been called as above. Ideally this will be solved without the need for a workaround.
I hope this helps and look forward to a solution.