Only nothing or horizontal lines displayed after porting

Description

After porting the display part of LVGL with the help of the guide:

  • cloned the latest (v8.1.0) LVGL release and structured related files into my project
  • completed lv_port_disp.c with calls to my display driver
  • modified lv_conf.h according to my screen
  • called lv_init() and lv_port_disp_init() before main loop
  • called lv_task_handler() in the main loop
  • called lv_tick_inc(1) every 1 ms and lv_timer_handler() every 5 ms using timer interrupts

I tried creating a simple button with LVGL. But the outcome was weird. I had only got blank or horizontal strips with the style of the border of the button.

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

STM32F407ZGT6 MCU
135x240 LCD with ST7789 driver. SPI connection.
STM32CubeIDE with gcc in C99

What do you want to achieve?

Simple widgets should be displayed normally.

What have you tried so far?

For testing around LVGL:

  • initialized basic buttons and sliders. Buttons with a specific parameter will result in stripes in the style of button border. Other buttons and bars result in blank display.
  • added code both after and before lv_task_handler(). It can be observed that this function did finish.

For testing around my display driver: directly called driver functions to render small boxes. Everything was fine.

Code to reproduce

lv_conf.h (modified parts):

#define LV_COLOR_DEPTH 16
#define LV_COLOR_16_SWAP 0
#define LV_DPI_DEF 30

lv_disp_port.c (modified parts):

#define MY_DISP_HOR_RES 240
#define MY_DISP_VER_RES 135
void lv_port_disp_init(void)
{
    disp_init();

    static lv_disp_draw_buf_t draw_buf_dsc_1;
    static lv_color_t buf_1[MY_DISP_HOR_RES * 10];
    lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);

    static lv_disp_drv_t disp_drv; 
    lv_disp_drv_init(&disp_drv);

    disp_drv.hor_res = MY_DISP_HOR_RES;
    disp_drv.ver_res = MY_DISP_VER_RES;

    disp_drv.flush_cb = disp_flush;

    disp_drv.draw_buf = &draw_buf_dsc_1;

    lv_disp_drv_register(&disp_drv);
}

static void disp_init(void)
{
	ST7789_Init();
}

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    ST7789_Fill((uint16_t)(area->x1), (uint16_t)(area->y1), (uint16_t)(area->x2), (uint16_t)(area->y2), color_p->full);

    lv_disp_flush_ready(disp_drv);
}

main.c (only int main() part):

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_TIM7_Init();
  MX_TIM6_Init();

  lv_init();
  lv_port_disp_init();

  //************CODE HERE. SEE BELOW************//

  while (1)
  {
	  ST7789_Fill(110, 20, 130, 40, 0x000F); // Directly calls my driver to draw a dark blue box in the upper middle for reference.
	  lv_task_handler();
  }
}

For the code at the place of the comment:

Button

lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_set_pos(btn, x, 70);
lv_obj_set_size(btn, 50, 20);

Only when x = 0 my display yields something:

For all other x there is only the dark blue box due to my driver call.

Bar

lv_obj_t * bar1 = lv_bar_create(lv_scr_act());
lv_obj_set_size(bar1, 200, 20);
lv_obj_center(bar1);
lv_bar_set_value(bar1, 70, LV_ANIM_OFF);

Only the dark blue box.

Any help is appreciated. Thanks!

Problem solved. The last parameter of disp_flush() is a lv_color_t *, a pointer to the color array. I mistakenly used the given parameters to “fill” an area with the color determined by the first element of the array. Just re-implement the flush as:

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    ST7789_DrawImage((uint16_t)(area->x1), (uint16_t)(area->y1), (uint16_t)(area->x2) - (uint16_t)(area->x1) + 1, (uint16_t)(area->y2) - (uint16_t)(area->y1) + 1, (uint16_t*)color_p);
    lv_disp_flush_ready(disp_drv);
}

(P.S. The display driver I used is this.)