Getting touch (indev) to work with LVGL


Not able to get a touch feedback while using LVGL

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

Nrf5340 MCU, Custom board, RM69090 Display controller (QSPI), 320%360 AMOLED display. Zephyr RTOS with Nordic NCS (SDK) with built-in gcc tools)
NCS version: 1.5.1
LVGL version: ## v7.6.1 (06.10.2020)
Zephyr RTOS version: 2.4.99

What LVGL version are you using?

LVGL version: ## v7.6.1 (06.10.2020)

What do you want to achieve?

Just want to see touch getting detected

What have you tried so far?

The touch driver works I can detect touch (finger down, up, move etc.), get x,y coordinates outside of LVGL. when I integrate with LVGL, display works fine, my touch driver detects a touch but LVGL doesn’t.

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

/*You code here*/
void btn_event_cb(lv_obj_t *btn, lv_event_t event) {
  if (event == LV_EVENT_CLICKED) {

void set_button(void) {
  lv_obj_t *btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button to the current screen*/
  //lv_obj_set_pos(btn, 10, 10);                            /*Set its position*/
  lv_obj_set_size(btn, 150, 100);         /*Set its size*/
  lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/
  lv_obj_align(btn, NULL, LV_ALIGN_CENTER, 0, 60);

  lv_obj_t *label = lv_label_create(btn, NULL); /*Add a label to the button*/
  lv_label_set_text(label, "Next");             /*Set the labels text*/

/*Return true is the touchpad is pressed*/
static bool kbpro_lvgl_touchpad_is_pressed(void) {
    return kbpro_touch_ztw622_event_status();

/*Get the x and y coordinates if the touchpad is pressed*/
static void kbpro_lvgl_touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) {
    (*x) = kbpro_touch_ztw622_get_x_coord();
    (*y) = kbpro_touch_ztw622_get_y_coord();

/* Will be called by the LVGL library to read the touchpad */
static bool kbpro_lvgl_touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;

    /*Save the pressed coordinates and the state*/
    if(kbpro_lvgl_touchpad_is_pressed()) {
        kbpro_lvgl_touchpad_get_xy(&last_x, &last_y);
        data->state = LV_INDEV_STATE_PR;
    } else {
        data->state = LV_INDEV_STATE_REL;

    /*Set the last pressed coordinates*/
    data->point.x = last_x;
    data->point.y = last_y;

    /*Return `false` because we are not buffering and no more data to read*/
    return false;

  initialize lvgl input device driver (touch in our case)
lv_indev_t * indev_touchpad;
lv_indev_drv_t indev_drv;

void kbpro_lvgl_indev_init(void) {
/*Initialize your touchpad if you have*/

  /*Register a touchpad input device*/
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = kbpro_lvgl_touchpad_read;
  indev_touchpad = lv_indev_drv_register(&indev_drv);
  if (!indev_touchpad) {
    printk("\n kbpro_lvgl_indev_init FAIL");

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

I managed to move forward… It looks like lv_task_handler() needs to be called periodically and i now do that - calling it anytime my underlying touch detects a a press or release. and now I see indev_drv.read_cb getting called every time there is a press or release… and I also see button call back detecting a click (though i would like it to be a bit more reliable… but that I will worry a bit later)…

Here’s what I do not understand… every time after button call back executes, lv_refr_task runs and somehow tries to draw the button again but messes up the rendering…

  1. why is lv_refr_task is running after button call back ? I have verified that this does happen every time and only after button call back executes. I looked at the documentation but couldn’t understand how is this supposed to work. I also looked at examples of buttons.
  2. from Zephyr RTOS and application design point of view, how often lv_task_handler should be called ? is it ok to call it only when underlying touch driver detects an event ?

I have attached two images… first one shows the messed up screen after button call back happens followed by execution of lv_refr_task

second image shows how it originally looks and expected to look like even after button call back is executed

Any response/feedback/comments will be greatly appreciated

update: the issue happens ONLY IF the button is aligned to center (LV_ALIGN_CENTER, LV_ALIGN_IN_TOP_MID, LV_ALIGN_IN_BOTTOM_MID)… but if I align the button to Top left, top right, bottom right etc. or even top mid, button seems to be fine and there are no issues…

I also tried by having just a single button and none of the other objects… issues is exactly the same.

what am I missing ? any feedback will be greatly appreciated.

please let me know if there is any additional information needed … any help would be greatly appreciated