Hi @gianlucacornacchia ,
My hardware will be different to yours but I am doing the same thing from a hardware/software functional point of view.
You haven’t shared all of your relevant code but here is my approach, hopefully it will show something to help:
void gui_update_thread(void *p) {
cpu0_globals->spawn_stat |= GUI_RUN;
// Initialise VGA Hardware
set_vga_prams( VGA_1440X900_60HZ_CVTR );
// Initialise GUI
lv_init();
lv_theme_default_init(cpu0_globals->gui.disp, shmem_p->personality == OTG_IDU ? confp->sys.IDU_gui_colour :
confp->sys.ODU_gui_colour, lv_palette_main(LV_PALETTE_PURPLE), (((shmem_p->personality == OTG_IDU) ? confp->sys.IDU_style :
confp->sys.ODU_style) ? 0 : 1), LV_FONT_DEFAULT);
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);
lv_disp_set_bg_opa(NULL, LV_OPA_TRANSP);
startup_gui_create();
lv_timer_create((lv_timer_cb_t)process_msg_q, 10, NULL); // Check for GUI thread messages every 10ms
while(1) {
lv_task_handler();
vTaskDelay(pdMS_TO_TICKS(4));
}
}
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 );
}
Also it may be worth checking your artefacts aren’t being caused by an unflushed cache.
Kind Regards,
Pete