Hi @pete-pjb,
I’ve implemented the code following your suggestions in the other answer, here the code:
void lv_port_disp_init(void)
{
memset(s_frameBuffer, 0, sizeof(s_frameBuffer));
lv_disp_draw_buf_init(&disp_buf, s_frameBuffer[0], s_frameBuffer[1], LCD_WIDTH * LCD_HEIGHT);
status_t status;
dc_fb_info_t fbInfo;
#if LV_USE_GPU_NXP_VG_LITE
/* Initialize GPU. */
BOARD_PrepareVGLiteController();
#endif
/*-------------------------
* Initialize your display
* -----------------------*/
BOARD_PrepareDisplayController();
status = g_dc.ops->init(&g_dc);
if (kStatus_Success != status)
{
assert(0);
}
g_dc.ops->getLayerDefaultConfig(&g_dc, 0, &fbInfo);
fbInfo.pixelFormat = DEMO_BUFFER_PIXEL_FORMAT;
fbInfo.width = DEMO_BUFFER_WIDTH;
fbInfo.height = DEMO_BUFFER_HEIGHT;
fbInfo.startX = DEMO_BUFFER_START_X;
fbInfo.startY = DEMO_BUFFER_START_Y;
fbInfo.strideBytes = DEMO_BUFFER_STRIDE_BYTE;
g_dc.ops->setLayerConfig(&g_dc, 0, &fbInfo);
g_dc.ops->setCallback(&g_dc, 0, DEMO_BufferSwitchOffCallback, &disp_drv);
#if defined(SDK_OS_FREE_RTOS)
s_transferDone = xSemaphoreCreateBinary();
if (NULL == s_transferDone)
{
PRINTF("Frame semaphore create failed\r\n");
assert(0);
}
#else
s_transferDone = false;
/* lvgl starts render in frame buffer 0, so show frame buffer 1 first. */
g_dc.ops->setFrameBuffer(&g_dc, 0, (void *)s_frameBuffer[1]);
/* Wait for frame buffer sent to display controller video memory. */
if ((g_dc.ops->getProperty(&g_dc) & kDC_FB_ReserveFrameBuffer) == 0)
{
#if defined(SDK_OS_FREE_RTOS)
if (xSemaphoreTake(s_transferDone, portMAX_DELAY) != pdTRUE)
{
PRINTF("Wait semaphore error: s_transferDone\r\n");
assert(0);
}
#else
while (false == s_transferDone)
{
}
#endif
}
g_dc.ops->enableLayer(&g_dc, 0);
/*-----------------------------------
* Register the display in LittlevGL
*----------------------------------*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set up the functions to access to your display*/
/*Set the resolution of the display*/
disp_drv.hor_res = LCD_WIDTH;
disp_drv.ver_res = LCD_HEIGHT;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = DEMO_FlushDisplay;
disp_drv.wait_cb = DEMO_WaitFlush;
#if (LV_USE_GPU_NXP_VG_LITE || LV_USE_GPU_NXP_PXP)
disp_drv.clean_dcache_cb = DEMO_CleanInvalidateCache;
#endif
/*Set a display buffer*/
disp_drv.draw_buf = &disp_buf;
disp_drv.full_refresh = 0;
disp_drv.direct_mode = 1;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
#if LV_USE_GPU_NXP_VG_LITE
if (vg_lite_init(64, 64) != VG_LITE_SUCCESS)
{
PRINTF("VGLite init error. STOP.");
vg_lite_close();
assert(0);
}
#endif
}
static void DEMO_BufferSwitchOffCallback(void *param, void *switchOffBuffer)
{
lv_disp_drv_t *disp_drv = (lv_disp_drv_t *)param;
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
#if defined(SDK_OS_FREE_RTOS)
BaseType_t taskAwake = pdFALSE;
xSemaphoreGiveFromISR(s_transferDone, &taskAwake);
portYIELD_FROM_ISR(taskAwake);
#else
s_transferDone = true;
#endif
}
#if (LV_USE_GPU_NXP_VG_LITE || LV_USE_GPU_NXP_PXP)
static void DEMO_CleanInvalidateCache(lv_disp_drv_t *disp_drv)
{
#if __CORTEX_M == 4
L1CACHE_CleanInvalidateSystemCache();
#else
SCB_CleanInvalidateDCache();
#endif
}
#endif
static void DEMO_WaitFlush(lv_disp_drv_t *disp_drv)
{
if (xSemaphoreTake(s_transferDone, portMAX_DELAY) != pdTRUE)
{
PRINTF("Display flush failed\r\n");
assert(0);
}
}
static void DEMO_UpdateDualBuffer( 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; /* Only copy areas which aren't part of another area */
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));
}
}
}
static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
/*
* Before new frame flushing, clear previous frame flush done status.
*/
(void)xSemaphoreTake(s_transferDone, 0);
/*CHANGE 4*/
if( lv_disp_flush_is_last( disp_drv ) ) {
DCACHE_CleanInvalidateByRange((uint32_t)color_p, DEMO_FB_SIZE);
g_dc.ops->setFrameBuffer(&g_dc, 0, (void *)color_p);
DEMO_UpdateDualBuffer(disp_drv, area, color_p);
//s_framePending = true;
}
else
lv_disp_flush_ready( disp_drv );
}
without the lv_disp_flush_ready() call in change 4 the application locks.
in the following video the results, as you can see the rendering has many defects:
video (valid for 1 week)
What can be the cause?
thank you,
gianluca