Touch desynchronization on STMF407xx XPT2046 with LVGL 9.4.0

Guys, just want to share my first hands-on projects with lvgl 9.4.0 as learning progress. Pomo app with stm32f407xx - 2.4inch LCD and XPT2046 touch.
stm32f407xx pomodoro timer

pomo_demo

There is a issue that I’ve not understand and fixed. If you guys here have experiences on this can give me some instruction to debug. Thanks in advances.

Issue (See videos attached):

  • When I tap the first button, it reacts immediately (normal).
  • When I tap the second button, LVGL still triggers the first button’s event — even though the raw touch coordinates printed in the log correctly show the second button’s (different) position.
  • Only after I tap the second button a second time, it correctly activates the second one.

Debug Observation:
I have tried to debug the raw position when touching, the x,y coords see to be reported correctly on each touch

Reading function

void xpt2046_read(lv_indev_t * indev, lv_indev_data_t * data)
{
    static int16_t last_x = 0;
    static int16_t last_y = 0;
    static bool last_pressed = false;

    bool pressed = (LV_DRV_INDEV_IRQ_READ == 0);

    if (pressed) {
        LV_DRV_INDEV_SPI_CS(0);

        LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_X_READ);
        uint8_t buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0);
        int16_t x = buf << 8;
        buf = LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_Y_READ);
        x += buf;

        buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0);
        int16_t y = buf << 8;
        buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0);
        y += buf;

        LV_DRV_INDEV_SPI_CS(1);

        x >>= 3;
        y >>= 3;

        xpt2046_corr(&x, &y);
        xpt2046_avg(&x, &y);

        last_x = x;
        last_y = y;
    }

    data->point.x = last_x;
    data->point.y = last_y;
    data->state   = pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;

    /* Debug logs to verify */
    if (pressed && !last_pressed)
        LV_LOG_USER("[TOUCH] PRESSED (%d,%d)", last_x, last_y);
    else if (!pressed && last_pressed) {
      data->point.x = -1;
      data->point.y = -1;
      LV_LOG_USER("[TOUCH] RELEASED (%d,%d)", last_x, last_y);
    }


    last_pressed = pressed;
}

Cool!

The issue really seems like a problem with the driver but I can see anything obvious in your code.

The only this I’d change is removing

   data->point.x = -1;
   data->point.y = -1;

Actually the in v9 LVGL does few things internally to make the read_cb simpler. So you can just

if(pressed) {
  //set data->point.x and y
}

data->state   = pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; 

And that’s it. No static variables are needed. I hope it resolves it. :crossed_fingers: