Display not refreshing - guidance requested

Description

Hey all, looking for some guidance. I’m currently setting up LVGL on a STM32 Nucleo board, and have everything initializing correctly, but the screen is never refreshing. This applies to changing active labels, as well as animations for initially created labels (i.e. scrolling text). I am able to create labels successfully on initialization, but nothing is updated when running in the main loop. A couple things to note: I am using FreeRTOS (CMSIS RTOSv2), and have read the applicable documentation. As such, I am using a semaphore to control access to lv_timer_handler();. Additionally, I believe I have setup the driver correctly using DMA, as initialization displays everything correctly. Having read similar posts, I have also confirmed the usage of lv_tick_set_cb().

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

STM32 Nucleo-F446RE, coded and compiled using STM32 CubeIDE, ILI9341 display.

What do you want to achieve?

Refresh and update display with applicable changes.

What have you tried so far?

Walked through code with breakpoints, confirmed usage of lv_tick and lv_timer_handler(), confirmed display driver is functioning correctly (at least on initialization). I have tried messing with LV_USE_OS in lv_conf.h, and have only had success with using LV_OS_NONE and manual usage of tasks and semaphores through CMSIS-RTOSv2.

Code to reproduce

Initialization (all done before FreeRTOS task scheduler begins):

	//create display
	lv_display_t * disp = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES);

	//set flush callback
	lv_display_set_flush_cb(disp, disp_flush);

	//set log callback
	lv_log_register_print_cb(lv_log_print);

	//create and set buffers
	static lv_color_t buf_1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10];
	lv_display_set_buffers(disp, buf_1, NULL, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL);

	//register tick function
	lv_tick_set_cb(HAL_GetTick);
  //get active screen
  lv_obj_t *scr = lv_screen_active();

  //set background color
  lv_obj_set_style_bg_color(scr, lv_color_make(255, 0, 0), LV_PART_MAIN);

  //create label
  textLabel = lv_label_create(scr);
  lv_label_set_text(textLabel, "Hello World");
  lv_obj_set_style_text_color(scr, lv_color_white(), LV_PART_MAIN);
  lv_obj_align(textLabel, LV_ALIGN_CENTER, 0, 0);

  textLabel2 = lv_label_create(scr);
  lv_label_set_long_mode(textLabel2, LV_LABEL_LONG_SCROLL_CIRCULAR);
  lv_obj_set_width(textLabel2, 150);
  lv_label_set_text(textLabel2, "It is a circularly scrolling text. ");
  lv_obj_align(textLabel2, LV_ALIGN_CENTER, 0, 40);

Display driver:

static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    if(disp_flush_enabled)
    {
    	//get pixels in area
    	int32_t areaX = (area->x2 + 1) - area->x1;
    	int32_t areaY = (area->y2 + 1) - area->y1;
    	int32_t areaPixels = areaX * areaY;

    	//assign display driver
    	disp_driver = disp_drv;

    	//set SPI to 16 bit transfer
    	hspi2.Init.DataSize = SPI_DATASIZE_16BIT;
    	HAL_SPI_Init(&hspi2);

    	//transmit DMA
    	HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)color_p, areaPixels);

    	disp_disable_update();
    }
}

(lv_display_flush_ready(disp_driver); called in SPI transfer complete callback)

lv_timer usage (called in timer interrupt):

	  //check for semaphore
	  if (osSemaphoreAcquire(LVGLSemaphore, 0) == osOK)
	  {
		  //call handler
		  lv_timer_handler();

		  //release semaphore
		  osSemaphoreRelease(LVGLSemaphore);
	  }

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

Welcome,

where do you call lv_tick_inc()? Can you confirm whether or not your flush callback and corresponding lv_flush_ready() functions actually get called?

Upon first inspection I think the problem here is a lack of tick_inc().

Hi Tinus,

Thanks for the response, sorry for the late reply.

I currently setup the tick function through lv_tick_set_cb(HAL_GetTick);, and I have confirmed that lv_tick_get(void) is getting called, is that different than the lv_tick_inc()?

I have also confirmed that the flush callback is being called, as well as lv_flush_ready() (in a callback for DMA transfer complete).

Hello,

If your flush callback and corresponding lv_flush_ready() are continuously called, then LVGL must have updated some internal buffers. Could you check if the area parameter in your flush callback changes? Everything looks all right as far as I can see here, my suggestion for lv_tick_inc still stands but your callback should work just as well.