Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touch event handling on NXP RT1064 EVK not working with LVGL 7.0.2, causes distortion of frame buffer #1600

Closed
nicholaskunes opened this issue Jun 20, 2020 · 4 comments

Comments

@nicholaskunes
Copy link

nicholaskunes commented Jun 20, 2020

What MCU/Processor/Board and compiler are you using?
NXP EVK RT1064
Using MCUExpresso IDE from NXP
I have a 480p x 272p LCD touchscreen attached to the board, I have ran other programs that involve touch on it (and previous version of LVGL) and the display works perfectly as expected.

What do you want to achieve?
Touch events to work as expected.

What have you tried so far?
Implemented touch event handling and a test button in LVGL 5.2 (works)
Implemented touch event handling and a test button in LVGL 7.0.2 (does not work as expected)

void lv_port_indev_init(void)
{
    lv_indev_drv_t indev_drv;

    /*------------------
     * Touchpad
     * -----------------*/

    /*Initialize your touchpad */
    DEMO_InitTouch();

    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = touchpad_read;
    indev_touchpad = lv_indev_drv_register(&indev_drv);
}

static void DEMO_InitTouch(void)
{
    status_t status;

    lpi2c_master_config_t masterConfig = {0};

    /*Clock setting for LPI2C*/
    CLOCK_SetMux(kCLOCK_Lpi2cMux, TOUCH_LPI2C_CLOCK_SOURCE_SELECT);
    CLOCK_SetDiv(kCLOCK_Lpi2cDiv, TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER);

    /*
     * masterConfig.debugEnable = false;
     * masterConfig.ignoreAck = false;
     * masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
     * masterConfig.baudRate_Hz = 100000U;
     * masterConfig.busIdleTimeout_ns = 0;
     * masterConfig.pinLowTimeout_ns = 0;
     * masterConfig.sdaGlitchFilterWidth_ns = 0;
     * masterConfig.sclGlitchFilterWidth_ns = 0;
     */
    LPI2C_MasterGetDefaultConfig(&masterConfig);

    /* Change the default baudrate configuration */
    masterConfig.baudRate_Hz = TOUCH_I2C_BAUDRATE;

    /* Initialize the LPI2C master peripheral */
    LPI2C_MasterInit(TOUCH_I2C, &masterConfig, TOUCH_I2C_CLOCK_FREQ);

    /* Initialize touch panel controller */
    status = FT5406_RT_Init(&touchHandle, TOUCH_I2C);
    if (status != kStatus_Success)
    {
        PRINTF("Touch panel init failed\n");
        assert(0);
    }
}

// TEST BUTTON CODE

lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL);     /*Add a button the current screen*/
lv_obj_set_pos(btn, 10, 10);                            /*Set its position*/
lv_obj_set_size(btn, 100, 50);                          /*Set its size*/
lv_obj_set_event_cb(btn, btn_event_cb);                 /*Assign a callback to the button*/

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

...

void btn_event_cb(lv_obj_t * btn, lv_event_t event)
{
    if(event == LV_EVENT_CLICKED) {
        printf("Clicked\n");
    }
}

Issue
When I click the button which does display perfectly, distortion occurs at the top of the screen.

Video of Issue
streamable.com/15cfz7

@nicholaskunes
Copy link
Author

nicholaskunes commented Jun 20, 2020

The contents of touchpad_read()

static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    touch_event_t touch_event;
    static int touch_x = 0;
    static int touch_y = 0;

    if (kStatus_Success == FT5406_RT_GetSingleTouch(&touchHandle, &touch_event, &touch_x, &touch_y))
    {
        data->state = LV_INDEV_STATE_PR;
    } else {
        data->state = LV_INDEV_STATE_REL;
    }

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

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

Yes, I am aware x/y are inverted, un-inverting it does not change the issue.

@embeddedt
Copy link
Member

So much code has been rewritten between 5.2 and 7.0 that I'm not surprised that the behavior has changed. My guess would be that there's something up withh your display driver. Can you show your disp_flush function and the area where you initialize and register your display buffer?

@nicholaskunes
Copy link
Author

nicholaskunes commented Jun 20, 2020

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    ELCDIF_SetNextBufferAddr(LCDIF, (uint32_t)color_p);

    s_framePending = true;

    if (xSemaphoreTake(s_frameSema, portMAX_DELAY) == pdTRUE)
    {
        lv_disp_flush_ready(disp_drv);
    }
    else
    {
        assert(0);
    }
}
void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    DEMO_InitLcd();

    lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

    /*Set up the functions to access to your display*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = 480;
    disp_drv.ver_res = 272;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.buffer = &disp_buf_2;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}
AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t s_frameBuffer[2][LCD_WIDTH * LCD_HEIGHT * LCD_FB_BYTE_PER_PIXEL], 64);

void lv_port_pre_init(void)
{
    /*
     * Pass in the frame buffer address to LittlevGL manually, the LV_VDB_ADR
     * and LV_VDB2_ADR should be defined to LV_VDB_ADR_INV in lv_conf.h
     */
    lv_disp_buf_init(&disp_buf_2, s_frameBuffer[0], s_frameBuffer[1], LCD_WIDTH * LCD_HEIGHT * LCD_FB_BYTE_PER_PIXEL);   /*Initialize the display buffer*/
}

@embeddedt
Copy link
Member

I think you'd only want to pass LCD_WIDTH * LCD_HEIGHT as the size; lv_disp_buf_init expects the size to be counted in lv_color_ts not bytes. You still need your array size to be multiplied though, since you declared it as a uint8_t.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants