diff --git a/radio/src/gui/colorlcd/lcd.cpp b/radio/src/gui/colorlcd/lcd.cpp index aeb977860..3cd42cc9d 100644 --- a/radio/src/gui/colorlcd/lcd.cpp +++ b/radio/src/gui/colorlcd/lcd.cpp @@ -50,14 +50,19 @@ static lv_area_t screen_area = { 0, 0, LCD_W-1, LCD_H-1 }; +// Call backs static void (*lcd_wait_cb)(lv_disp_drv_t *) = nullptr; +static void (*lcd_flush_cb)(lv_disp_drv_t *, uint16_t* buffer, const rect_t& area) = nullptr; void lcdSetWaitCb(void (*cb)(lv_disp_drv_t *)) { lcd_wait_cb = cb; } -void newLcdRefresh(uint16_t* buffer, const rect_t& copy_area); +void lcdSetFlushCb(void (*cb)(lv_disp_drv_t *, uint16_t*, const rect_t&)) +{ + lcd_flush_cb = cb; +} static void flushLcd(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { @@ -76,7 +81,11 @@ static void flushLcd(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_ refr_area.x2 - refr_area.x1 + 1, refr_area.y2 - refr_area.y1 + 1}; - newLcdRefresh((uint16_t*)color_p, copy_area); + if (lcd_flush_cb) { + lcd_flush_cb(disp_drv, (uint16_t*)color_p, copy_area); + } else { + lv_disp_flush_ready(disp_drv); + } } void lcdInitDisplayDriver() diff --git a/radio/src/gui/colorlcd/lcd.h b/radio/src/gui/colorlcd/lcd.h index 0d7e46250..016cc3381 100644 --- a/radio/src/gui/colorlcd/lcd.h +++ b/radio/src/gui/colorlcd/lcd.h @@ -41,7 +41,9 @@ struct _lv_disp_drv_t; typedef _lv_disp_drv_t lv_disp_drv_t; +// Call backs void lcdSetWaitCb(void (*cb)(lv_disp_drv_t *)); +void lcdSetFlushCb(void (*cb)(lv_disp_drv_t *, uint16_t*, const rect_t&)); // Init LVGL and its display driver void lcdInitDisplayDriver(); diff --git a/radio/src/targets/horus/lcd_driver.cpp b/radio/src/targets/horus/lcd_driver.cpp index 28e7791ef..454ae861a 100644 --- a/radio/src/targets/horus/lcd_driver.cpp +++ b/radio/src/targets/horus/lcd_driver.cpp @@ -43,7 +43,22 @@ #define VFP 2 #endif -uint8_t LCD_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; +static uint8_t LCD_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; + +static uint16_t* next_frame_buffer; +static rect_t next_frame_area; + +static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer, + const rect_t ©_area) +{ + (void)disp_drv; + + next_frame_buffer = buffer; + next_frame_area = copy_area; + + // Enable line IRQ + LTDC_ITConfig(LTDC_IER_LIE, ENABLE); +} inline void LCD_NRST_LOW() { @@ -321,6 +336,8 @@ void lcdInit() // Enable LCD display LTDC_Cmd(ENABLE); + + lcdSetFlushCb(startLcdRefresh); } void DMAFillRect(uint16_t *dest, uint16_t destw, uint16_t desth, uint16_t x, @@ -575,9 +592,6 @@ void lcdCopy(void * dest, void * src) while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } -static uint16_t* next_frame_buffer; -static rect_t next_frame_area; - extern "C" void LTDC_IRQHandler(void) { // clear interrupt flag @@ -594,12 +608,3 @@ extern "C" void LTDC_IRQHandler(void) lcdFlushed(); } -void newLcdRefresh(uint16_t * buffer, const rect_t& copy_area) -{ - next_frame_buffer = buffer; - next_frame_area = copy_area; - - // Enable line IRQ - LTDC_ITConfig(LTDC_IER_LIE, ENABLE); -} - diff --git a/radio/src/targets/nv14/lcd_driver.cpp b/radio/src/targets/nv14/lcd_driver.cpp index 7a3e94196..784780d11 100644 --- a/radio/src/targets/nv14/lcd_driver.cpp +++ b/radio/src/targets/nv14/lcd_driver.cpp @@ -23,7 +23,22 @@ #include "libopenui_config.h" #include "lcd.h" -uint8_t LCD_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; +static uint8_t LCD_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; + +static uint16_t* next_frame_buffer; +static rect_t next_frame_area; + +static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer, + const rect_t ©_area) +{ + (void)disp_drv; + + next_frame_buffer = buffer; + next_frame_area = copy_area; + + // Enable line IRQ + LTDC_ITConfig(LTDC_IER_LIE, ENABLE); +} lcdSpiInitFucPtr lcdInitFunction; lcdSpiInitFucPtr lcdOffFunction; @@ -1312,6 +1327,8 @@ void lcdInit(void) LCD_LayerInit(); LTDC_Cmd(ENABLE); LTDC_ReloadConfig(LTDC_IMReload); + + lcdSetFlushCb(startLcdRefresh); } void DMAFillRect(uint16_t *dest, uint16_t destw, uint16_t desth, uint16_t x, @@ -1566,9 +1583,6 @@ void lcdCopy(void * dest, void * src) while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } -static uint16_t* next_frame_buffer; -static rect_t next_frame_area; - extern "C" void LTDC_IRQHandler(void) { // clear interrupt flag @@ -1584,12 +1598,3 @@ extern "C" void LTDC_IRQHandler(void) // TODO: call on "Transfer Complete" IRQ lcdFlushed(); } - -void newLcdRefresh(uint16_t * buffer, const rect_t& copy_area) -{ - next_frame_buffer = buffer; - next_frame_area = copy_area; - - // Enable line IRQ - LTDC_ITConfig(LTDC_IER_LIE, ENABLE); -} diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 8118ce8fa..eaea1543b 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -146,13 +146,6 @@ static void* bootloaderThread(void*) } #endif -static void lcdExitHandler(lv_disp_drv_t*) -{ - if (simu_shutdown) { - lcdFlushed(); - } -} - void simuStart(bool tests, const char * sdPath, const char * settingsPath) { if (simu_running) @@ -211,8 +204,6 @@ void simuStart(bool tests, const char * sdPath, const char * settingsPath) try { #endif - lcdSetWaitCb(lcdExitHandler); - #if !defined(SIMU_BOOTLOADER) simuMain(); #else diff --git a/radio/src/targets/simu/simulcd.cpp b/radio/src/targets/simu/simulcd.cpp index e8a3b1f19..2c9b8fc9e 100644 --- a/radio/src/targets/simu/simulcd.cpp +++ b/radio/src/targets/simu/simulcd.cpp @@ -54,7 +54,9 @@ void lcdRefresh() #else -void newLcdRefresh(uint16_t *buffer, const rect_t& copy_area) +#include + +static void simuRefreshLcd(lv_disp_drv_t * disp_drv, uint16_t *buffer, const rect_t& copy_area) { #if defined(LCD_VERTICAL_INVERT) coord_t x1 = LCD_W - copy_area.w - copy_area.x; @@ -84,13 +86,28 @@ void newLcdRefresh(uint16_t *buffer, const rect_t& copy_area) dst += LCD_W - copy_area.w; } - // Mark screen dirty for async refresh - simuLcdRefresh = true; + if (lv_disp_flush_is_last(disp_drv)) { + // Mark screen dirty for async refresh + simuLcdRefresh = true; + } else { + lv_disp_flush_ready(disp_drv); + } +} + +extern bool simu_shutdown; + +static void simuLcdExitHandler(lv_disp_drv_t* disp_drv) +{ + if (simu_shutdown) { + lv_disp_flush_ready(disp_drv); + } } void lcdInit() { memset(simuLcdBuf, 0, sizeof(simuLcdBuf)); + lcdSetWaitCb(simuLcdExitHandler); + lcdSetFlushCb(simuRefreshLcd); } void DMAFillRect(uint16_t *dest, uint16_t destw, uint16_t desth, uint16_t x,