diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index addfff02e..9e4795e01 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -458,7 +458,9 @@ static void lv_refr_area_part(const lv_area_t * area_p) /*In non double buffered mode, before rendering the next part wait until the previous image is * flushed*/ if(lv_disp_is_double_buf(disp_refr) == false) { - while(vdb->flushing) ; + while(vdb->flushing) { + if(disp_refr->driver.wait_cb) disp_refr->driver.wait_cb(&disp_refr->driver); + } } lv_obj_t * top_p; @@ -654,7 +656,9 @@ static void lv_refr_vdb_flush(void) /*In double buffered mode wait until the other buffer is flushed before flushing the current * one*/ if(lv_disp_is_double_buf(disp_refr)) { - while(vdb->flushing); + while(vdb->flushing) { + if(disp_refr->driver.wait_cb) disp_refr->driver.wait_cb(&disp_refr->driver); + } } vdb->flushing = 1; diff --git a/src/lv_gpu/lv_gpu_stm32_dma2d.c b/src/lv_gpu/lv_gpu_stm32_dma2d.c index 38c682558..169a24eaa 100644 --- a/src/lv_gpu/lv_gpu_stm32_dma2d.c +++ b/src/lv_gpu/lv_gpu_stm32_dma2d.c @@ -33,6 +33,7 @@ /********************** * STATIC PROTOTYPES **********************/ +static void dma2d_wait(void); /********************** * STATIC VARIABLES @@ -70,12 +71,10 @@ void lv_gpu_stm32_dma2d_fill(lv_color_t * buf, lv_coord_t buf_w, lv_color_t colo hdma2d.LayerCfg[1].InputOffset = 0; /* DMA2D Initialization */ - if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { - if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { - HAL_DMA2D_Start(&hdma2d, (uint32_t)lv_color_to32(color), (uint32_t)buf, fill_w, fill_h); - HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); - } - } + HAL_DMA2D_Init(&hdma2d) { + HAL_DMA2D_ConfigLayer(&hdma2d, 1) + HAL_DMA2D_Start(&hdma2d, (uint32_t)lv_color_to32(color), (uint32_t)buf, fill_w, fill_h); + dma2d_wait(); } /** @@ -119,7 +118,7 @@ void lv_gpu_stm32_dma2d_fill_mask(lv_color_t * buf, lv_coord_t buf_w, lv_color_t HAL_DMA2D_ConfigLayer(&hdma2d, 0); HAL_DMA2D_ConfigLayer(&hdma2d, 1); HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t) mask, (uint32_t) buf, (uint32_t)buf, fill_w, fill_h); - HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); + dma2d_wait(); } /** @@ -150,13 +149,11 @@ void lv_gpu_stm32_dma2d_copy(lv_color_t * buf, lv_coord_t buf_w, const lv_color_ hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; /* DMA2D Initialization */ - if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { - HAL_DMA2D_ConfigLayer(&hdma2d, 0); - if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { - HAL_DMA2D_Start(&hdma2d, (uint32_t)map, (uint32_t)buf, copy_w, copy_h); - HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); - } - } + HAL_DMA2D_Init(&hdma2d); + HAL_DMA2D_ConfigLayer(&hdma2d, 0); + HAL_DMA2D_ConfigLayer(&hdma2d, 1); + HAL_DMA2D_Start(&hdma2d, (uint32_t)map, (uint32_t)buf, copy_w, copy_h); + dma2d_wait(); } /** @@ -194,18 +191,23 @@ void lv_gpu_stm32_dma2d_blend(lv_color_t * buf, lv_coord_t buf_w, const lv_color hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; /* DMA2D Initialization */ - if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) { - HAL_DMA2D_ConfigLayer(&hdma2d, 0); - if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) == HAL_OK) { - HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t)map, (uint32_t)buf, (uint32_t)buf, copy_w, copy_h); - HAL_DMA2D_PollForTransfer(&hdma2d, HAL_MAX_DELAY); - } - } + HAL_DMA2D_Init(&hdma2d); { + HAL_DMA2D_ConfigLayer(&hdma2d, 0); + HAL_DMA2D_ConfigLayer(&hdma2d, 1); + HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t)map, (uint32_t)buf, (uint32_t)buf, copy_w, copy_h); + dma2d_wait(); } /********************** * STATIC FUNCTIONS **********************/ +static void dma2d_wait(void) +{ + lv_disp_t * disp = lv_refr_get_disp_refreshing(); + while(HAL_DMA2D_PollForTransfer(&hdma2d, 0) == HAL_BUSY) { + if(disp->driver.wait_cb) disp->driver.wait_cb(&disp->driver); + } +} #endif diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h index da664f6ac..2e1ad41a5 100644 --- a/src/lv_hal/lv_hal_disp.h +++ b/src/lv_hal/lv_hal_disp.h @@ -104,6 +104,11 @@ typedef struct _disp_drv_t { * number of flushed pixels */ void (*monitor_cb)(struct _disp_drv_t * disp_drv, uint32_t time, uint32_t px); + /** OPTIONAL: Called periodically while lvgl waits for operation to be completed. + * For example flushing or GPU + * User can execute very simple tasks here or yield the task */ + void (*wait_cb)(struct _disp_drv_t * disp_drv); + #if LV_USE_GPU /** OPTIONAL: Blend two memories using opacity (GPU only)*/ void (*gpu_blend_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length,