Description
On the STM32F469I-DISCO I would like to have a window (400x300) that shows the image of a IR cam (interpolated from 32x24). For that I’m using a image (created with lv_img_create) and write the (interpolated) IR-cam image to the buffer I have provided. For a test I switch in main-loop only the color of the buffer (toggeling between memset(img_buff, 0x90, 240000); and memset(img_buff, 0x99, 240000);). Everything works … except it flickers unacceptable. Since the driver already uses double buffering I assume a VSYNC-problem … but I’m unable to solve this by my own.
What MCU/Processor/Board and compiler are you using?
STM32F469I-DISCO
LVGL 8.3.11
What do you want to achieve?
Showing the interpolated image of a IR-cam in a window (image) on the screen
What have you tried so far?
No difference between
lv_img_cache_invalidate_src(img_buff);
or
lv_img_set_src(ui_imgFrame, therm_img_dsc);
No difference in using
memset(img_buff, 0x99, 240000);
or
lv_img_buf_set_px_color
No difference in using
lv_timer_handler();
or
lv_task_handler();
I found a hint that it may help to use a short delay at the end of the flush-cb, that does not change anything
.
.
lv_disp_flush_ready(disp_drv);
HAL_Delay(2);
}
For the hack of it I tried with single-buffer - that makes it much worse.
Code to reproduce
uint32_t startTime = HAL_GetTick();
bool bToggleColor = false;
while (1)
{
if((HAL_GetTick() - startTime) > 1000)
{
if(bToggleColor)
{
memset(img_buff, 0x90, 240000);
// for(int y=0; y<300; ++y)
// for(int x=0; x<400; ++x)
// lv_img_buf_set_px_color(therm_img_dsc, x, y, lv_color_make(50,50,50));
}
else
{
memset(img_buff, 0x99, 240000);
// for(int y=0; y<300; ++y)
// for(int x=0; x<400; ++x)
// lv_img_buf_set_px_color(therm_img_dsc, x, y, lv_color_make(150,150,150));
}
bToggleColor = !bToggleColor;
HAL_Delay(5);
startTime = HAL_GetTick();
// lv_obj_invalidate(ui_imgFrame);
// lv_img_cache_invalidate_src(img_buff); // also makes no difference
lv_img_set_src(ui_imgFrame, therm_img_dsc);
}
HAL_Delay(5);
// lv_timer_handler();
lv_task_handler();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
Here is the flush cb
void stm32_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
// _lv_disp_refr_timer(NULL);
lv_disp_t *disp = _lv_refr_get_disp_refreshing();
uint16_t *dma_xfer_src, *dma_xfer_dst;
if(!lv_disp_flush_is_last(disp_drv))
{
lv_disp_flush_ready(disp_drv);
return;
}
// Swap the buffer for the one to display and reload the screen at the next vertical blanking
HAL_LTDC_SetAddress_NoReload(&hltdc, (uint32_t)color_p, 0);
HAL_LTDC_Reload(&hltdc, LTDC_RELOAD_VERTICAL_BLANKING); // VSYNC
// HAL_LTDC_Reload(&hltdc, LTDC_RELOAD_IMMEDIATE); // makes no difference
// Determine source and destination of transfer
dma_xfer_src = (uint16_t *)color_p;
if(color_p == framebuffer_1){
dma_xfer_dst = (uint16_t *)framebuffer_2;
}else{
dma_xfer_dst = (uint16_t *)framebuffer_1;
}
for(size_t i = 0; i < disp->inv_p; i++){
// If the area was not joined (and thus should not be ignored)
if(!disp->inv_area_joined[i]){
dma2d_copy_area(disp->inv_areas[i], (uint32_t)dma_xfer_src, (uint32_t)dma_xfer_dst);
}
}
lv_disp_flush_ready(disp_drv);
HAL_Delay(2);
}
Screenshot and/or video
If possible, add screenshots and/or videos about the current state.
I do have a short video … but couldnt find a way to upload. Shall I upload it to a share and provide a link?