Hi @JamesJJ ,
Can you share your lvgl initialisation code?
Are you using double buffering with DMA?
Have you seen this forum topic?
I initially had an issue with my hardware after porting to v8 as the full screen was being refreshed all the time. I used the methods detailed here to change my driver to just update the parts that had changed.
My initialisation code is:
lv_init();
lv_disp_drv_init((lv_disp_drv_t*)&cpu0_globals->gui.disp_drv);
lv_disp_draw_buf_init(&cpu0_globals->gui.disp_buf, (void*)LV_VDB_ADR, (void*)LV_VDB2_ADR, (LV_HOR_RES_MAX*LV_VER_RES_MAX));
cpu0_globals->gui.disp_drv.flush_cb = vga_disp_flush;
cpu0_globals->gui.disp_drv.hor_res = LV_HOR_RES_MAX; /*Set the horizontal resolution in pixels*/
cpu0_globals->gui.disp_drv.ver_res = LV_VER_RES_MAX; /*Set the vertical resolution in pixels*/
cpu0_globals->gui.disp_drv.draw_buf = &cpu0_globals->gui.disp_buf;
cpu0_globals->gui.disp_drv.full_refresh = pdFALSE;
cpu0_globals->gui.disp_drv.direct_mode = pdTRUE;
cpu0_globals->gui.disp = lv_disp_drv_register((lv_disp_drv_t*)&cpu0_globals->gui.disp_drv);
My flush call back and support functions are:
void vga_irq_handler( void *p ) {
vga->vga_fbuf_addr = cpu0_globals->gui.dma_src;
cpu0_globals->gui.buf_switched = pdTRUE;
XScuGic_Disable(&xInterruptController, XPAR_FABRIC_VGA_IP_0_FRM_CPT_IRQ_INTR);
lv_disp_flush_ready((lv_disp_drv_t*)&cpu0_globals->gui.disp_drv);
}
static void update_dual_buf( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *colour_p ) {
lv_disp_t* disp = _lv_refr_get_disp_refreshing();
lv_coord_t y, hres = lv_disp_get_hor_res(disp);
uint16_t a;
lv_color_t *buf_cpy;
if( colour_p == disp_drv->draw_buf->buf1)
buf_cpy = disp_drv->draw_buf->buf2;
else
buf_cpy = disp_drv->draw_buf->buf1;
for(a = 0; a < disp->inv_p; a++) {
if(disp->inv_area_joined[a]) continue;
lv_coord_t w = lv_area_get_width(&disp->inv_areas[a]);
for(y = disp->inv_areas[a].y1; y <= disp->inv_areas[a].y2 && y < disp_drv->ver_res; y++) {
memcpy(buf_cpy+(y * hres + disp->inv_areas[a].x1), colour_p+(y * hres + disp->inv_areas[a].x1), w * sizeof(lv_color_t));
}
}
}
void vga_disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *colour_p) {
static uint8_t first_call = 1;
if( first_call ) {
cpu0_globals->gui.dma_src = (uint32_t)colour_p;
first_call = 0;
vga->total_pixels &= ~DMA_FIFO_RST; // Release Reset
vga->total_pixels |= DMA_FRAME_READY; // Start Proceedings
vga->irq_reg = VGA_IRQ_EN; // Enable DMA complete interrupt
}
if( lv_disp_flush_is_last( disp_drv ) ) {
cpu0_globals->gui.dma_src = (uint32_t)colour_p;
cpu0_globals->gui.buf_switched = pdFALSE;
XScuGic_Enable(&xInterruptController, XPAR_FABRIC_VGA_IP_0_FRM_CPT_IRQ_INTR);
while(!cpu0_globals->gui.buf_switched);// vTaskDelay(1);
update_dual_buf(disp_drv, area, colour_p);
}
lv_disp_flush_ready( disp_drv );
}
This code is specific to my hardware but hopefully it gives you and idea of how it works.
I hope this helps.
Kind Regards,
Pete