How to speed up the V8 version?

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

1 Like