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.