Background turns off

Solved: The problem was related to sending data to LTDC framebuffer address. Every time I send data to the buffer, the previous data on the buffer is deleted. Therefore, only newly written data was transferred to the screen. I define a 480 * 272 buffer to the frame buffer address and point its address. The tft_flush function just fills this buffer. Therefore, old data written to the buffer is not deleted.


I wanted to run the demo application in the lv_examples library. After loading the first screen, the background disappears immediately. Only the cursor is blinking.

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


What do you experience?

If there is no refresh on the screen, there is no problem.

What do you expect?

Why the background disappears? Also what should the buffer size be? I am using internal ram.

Code to reproduce

void tft_init(void)
    static lv_disp_buf_t disp_buf;
    static lv_color_t buf_1[LV_HOR_RES_MAX * 272];
    HAL_LTDC_SetAddress(&hltdc, (uint32_t)&buf_1, 0);
    lv_disp_buf_init(&disp_buf, buf_1, NULL, LV_HOR_RES_MAX * 272);   /*Initialize the display buffer*/

    * Register the display in LittlevGL

    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 = tft_flush;

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

    /*Finally register the driver*/
    disp = lv_disp_drv_register(&disp_drv);

static void tft_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
    /*Return if the area is out the screen*/
    if(area->x2 < 0) return;
    if(area->y2 < 0) return;
    if(area->x1 > 480 - 1) return;
    if(area->y1 > 272 - 1) return;

    int16_t width_x = (area->x2-area->x1)+1;
    int16_t width_y = (area->y2-area->y1)+1;

    HAL_LTDC_SetWindowPosition(&hltdc, area->x1, area->y1, 0);
    HAL_LTDC_SetWindowSize(&hltdc, width_x, width_y, 0);

    for(uint32_t i = 0; i <= width_x*width_y; i++) {
		*(__IO uint16_t*)(hltdc.LayerCfg[0].FBStartAdress+(i*2)) = color_p->full;

Screenshot and/or video

I think your flush function is implemented incorrectly. Take a look at our framebuffer driver or our STM32F746 example project for a reference. In particular you shouldn’t need to be changing the window position or size for the STM32 LTDC, and I think you are not compensating for the area offset provided by LVGL when you write to the framebuffer.