Porting lvgl 6.1 to LPCXpresso5408

Important: posts that do not use this template will be ignored or closed.

Before posting

  • Get familiar with Markdown to format and structure your post
  • Be sure to update lvgl from the latest version from the master branch.
  • Read the

Delete this section if you read and applied the mentioned points.

Description

Using the dev board mentioned below and using the MCUXpresso SDK builder, you can get ready to go lvgl examples. But they use version 5.3. I want to use the latest and greatest. So I am trying to update to project to the new release of lvgl of 6.1.

So I just keep the LCD driver code and RTOS code the same and bring in the new lvgl. And using the porting guide, I initialize the disp and input device. Call the proper flush_cp, etc.

But it did not end up being so easy. I followed the porting guide and I think I got everything in there.

The Problem

Using the demo.c demo and using two frame buffers the size of the screen with 2bytes per pixel, the 2nd frame buffer does not seem to be getting updated.

During the first flush_cb, it seems to display fine like the image below:


Notice the small black line in the upper left corner though.

During the next flush_cb, the LCD controller is updated to use the 2nd frame buffer and I get this:

And it just alternates between the two at a rate that can easily be seen. Maybe 500mS each.

Here is a gif of what happens on startup


Here is a gif of what happens if you click on something.

Everything seems to be glitchy and a lot of touch object don’t seem to work.

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

Dev Board = LPCXpresso54608
MCU = LPC54608
IDE = MCUXpresso
TFT = RK043FN02H-CT

This MCU has an LCD controller and has the 272x480 color LCD with capacitive touchscreen.

What do you want to achieve?

Bring in the latest lvgl release 6.1 into the project and get the demo.c to work.

What have you tried so far?

  1. Initialize the display to use only one buffer instead of two
  2. Break point at flush_cb shows that 2nd frame buffer is not being updated. It has some data which shows up in the upper left corner of the screen, but the rest of 0. It does however seem to update one you start touching the tabs to move to another tab in the demo.
  3. Went through the porting guide to see if I missed anything
  4. Tried the keyboard tutorial and it did similar things.

Code to reproduce

static void DEMO_FlushDisplay(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{

    LCDC_SetPanelAddr(LCD, kLCDC_UpperPanel, (uint32_t)color_p);

    s_framePending = true;

    if (xSemaphoreTake(s_frameSema, portMAX_DELAY) != pdTRUE)
    {
        PRINTF("Wait semaphore error: s_frameSema\r\n");
        assert(0);
    }

    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}
static void AppTask(void *param)
{
    lv_init();

    lv_port_disp_init();
    lv_port_indev_init();
    demo_create();

    for (;;)
    {
        lv_tick_inc(5);
        lv_task_handler();
        vTaskDelay(5);
    }
}
void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    DEMO_InitLcd();

    /*Create a display buffer*/
    lv_port_pre_init();
    static lv_disp_buf_t disp_buf1;
    lv_disp_buf_init(&disp_buf1, (void *)DEMO_BUFFER0_ADDR, (void *)DEMO_BUFFER1_ADDR, LCD_WIDTH*LCD_HEIGHT*LCD_FB_BYTE_PER_PIXEL);

    /*-----------------------------------
     * Register the display in LittlevGL
     *----------------------------------*/

    /*Create a display*/
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);            /*Basic initialization*/
    disp_drv.buffer = &disp_buf1;
    disp_drv.flush_cb = DEMO_FlushDisplay;    /*Used when `LV_VDB_SIZE != 0` in lv_conf.h (buffered drawing)*/
    lv_disp_drv_register(&disp_drv);


}
void lv_port_indev_init(void)
{


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

    /*Initialize your touchpad */
    DEMO_InitTouch();

    /*Register a touchpad input device*/
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb  = DEMO_ReadTouch;
    volatile static lv_indev_t * my_indev = NULL;
    my_indev = lv_indev_drv_register(&indev_drv);
}

Attached are source files
files.zip (11.7 KB)

Screenshot and/or video

See above for images and gifs. Also I have attached a zip file full of source files. I would attached the whole MCUXpresso project, but the file is too large.

Side note

This dev board SDK also comes with emWIN from SEGGER. It is super slow and unresponsive. Good job little vgl.

This probably isn’t going to fix the problem, but lv_disp_buf_init wants the buffer size in terms of the number of lv_color_t entries (usually # of pixels), not the number of bytes. So I think LCD_WIDTH*LCD_HEIGHT is the right size to use there.

It definitely looks like the second framebuffer is not being updated properly. I think the FlushDisplay function implementation is wrong. I’m not sure whether you wrote that or not.

LCDC_SetPanelAddr(LCD, kLCDC_UpperPanel, (uint32_t)color_p);

I’m suspecting that only in the case where the whole display is updated will color_p actually point to the beginning of your buffer, but I never use true double buffering mode so I can’t really comment much on it with any degree of trustworthiness. :wink:

1 Like

Thank you for your reply.

You were absolutely right. Changing to just “LCD_WIDTH*LCD_HEIGHT” made everything work. I never expected that passing in a buffer size larger than the display would be an issue. I just assumed it would use only what it needed.