From 8d6a7c2da55eafdeb10af4145f74a171309323c0 Mon Sep 17 00:00:00 2001 From: gagarinlg Date: Sun, 13 Feb 2022 13:34:22 +0100 Subject: [PATCH] preparation for PL18, differentiate between physical and UI screen size adapt to partial draw calls from LVGL --- radio/src/gui/colorlcd/LvglWrapper.cpp | 5 ++-- radio/src/targets/horus/board.h | 2 ++ radio/src/targets/horus/lcd_driver.cpp | 18 ++++++------ radio/src/targets/nv14/board.h | 6 ++-- radio/src/targets/nv14/lcd_driver.cpp | 39 ++++++++++++++++---------- 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/radio/src/gui/colorlcd/LvglWrapper.cpp b/radio/src/gui/colorlcd/LvglWrapper.cpp index 08cd548df..de044c642 100644 --- a/radio/src/gui/colorlcd/LvglWrapper.cpp +++ b/radio/src/gui/colorlcd/LvglWrapper.cpp @@ -208,13 +208,14 @@ static lv_disp_drv_t* init_disp_drv() lv_disp_drv_init(&disp_drv); /*Basic initialization*/ disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/ disp_drv.flush_cb = flushLcd; /*Set a flush callback to draw to the display*/ - disp_drv.hor_res = LCD_W; /*Set the horizontal resolution in pixels*/ - disp_drv.ver_res = LCD_H; /*Set the vertical resolution in pixels*/ + disp_drv.hor_res = LCD_PHYS_W; /*Set the horizontal resolution in pixels*/ + disp_drv.ver_res = LCD_PHYS_H; /*Set the vertical resolution in pixels*/ disp_drv.full_refresh = 0; disp_drv.direct_mode = 0; #if defined (LCD_VERTICAL_INVERT) disp_drv.rotated = LV_DISP_ROT_180; #endif +// disp_drv.rotated = LV_DISP_ROT_90; disp_drv.sw_rotate = 1; return &disp_drv; diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index e5377eb18..14f4bfe0e 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -526,6 +526,8 @@ void ledBlue(); // LCD driver #define LCD_W 480 #define LCD_H 272 +#define LCD_PHYS_H LCD_H +#define LCD_PHYS_W LCD_W #define LCD_DEPTH 16 void lcdInit(); void lcdRefresh(); diff --git a/radio/src/targets/horus/lcd_driver.cpp b/radio/src/targets/horus/lcd_driver.cpp index 8373d532f..e60b7447c 100644 --- a/radio/src/targets/horus/lcd_driver.cpp +++ b/radio/src/targets/horus/lcd_driver.cpp @@ -213,13 +213,13 @@ void LCD_Init_LTDC() /* Configure accumulated vertical back porch */ LTDC_InitStruct.LTDC_AccumulatedVBP = VBP; /* Configure accumulated active width */ - LTDC_InitStruct.LTDC_AccumulatedActiveW = LCD_W + HBP; + LTDC_InitStruct.LTDC_AccumulatedActiveW = LCD_PHYS_W + HBP; /* Configure accumulated active height */ - LTDC_InitStruct.LTDC_AccumulatedActiveH = LCD_H + VBP; + LTDC_InitStruct.LTDC_AccumulatedActiveH = LCD_PHYS_H + VBP; /* Configure total width */ - LTDC_InitStruct.LTDC_TotalWidth = LCD_W + HBP + HFP; + LTDC_InitStruct.LTDC_TotalWidth = LCD_PHYS_W + HBP + HFP; /* Configure total height */ - LTDC_InitStruct.LTDC_TotalHeigh = LCD_H + VBP + VFP; + LTDC_InitStruct.LTDC_TotalHeigh = LCD_PHYS_H + VBP + VFP; // init ltdc LTDC_Init(<DC_InitStruct); @@ -255,9 +255,9 @@ void LCD_LayerInit() Vertical start = vertical synchronization + vertical back porch = 4 Vertical stop = Vertical start + window height -1 = 4 + 320 -1 */ LTDC_Layer_InitStruct.LTDC_HorizontalStart = HBP + 1; - LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_W + HBP); + LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_PHYS_W + HBP); LTDC_Layer_InitStruct.LTDC_VerticalStart = VBP + 1;; - LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_H + VBP); + LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_PHYS_H + VBP); /* Pixel Format configuration*/ LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_RGB565; @@ -280,14 +280,14 @@ void LCD_LayerInit() Active high width = LCD_W number of bytes per pixel = 2 (pixel_format : RGB565) */ - LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_W * 2) + 3); + LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD__PHYS_W * 2) + 3); /* the pitch is the increment from the start of one line of pixels to the start of the next line in bytes, then : Pitch = Active high width x number of bytes per pixel */ - LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_W * 2); + LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_PHYS_W * 2); /* Configure the number of lines */ - LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_H; + LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_PHYS_H; /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */ LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t)LCD_FIRST_FRAME_BUFFER; diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index 9b746bb40..ad7c859e9 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -396,8 +396,10 @@ uint32_t pwrPressedDuration();; const etx_serial_port_t* auxSerialGetPort(int port_nr); // LCD driver -#define LCD_W 320 -#define LCD_H 480 +#define LCD_W 480 +#define LCD_H 320 +#define LCD_PHYS_W 320 +#define LCD_PHYS_H 480 #define LCD_DEPTH 16 #define LCD_CONTRAST_DEFAULT 20 void lcdInit(); diff --git a/radio/src/targets/nv14/lcd_driver.cpp b/radio/src/targets/nv14/lcd_driver.cpp index e300f5aad..8478eef17 100644 --- a/radio/src/targets/nv14/lcd_driver.cpp +++ b/radio/src/targets/nv14/lcd_driver.cpp @@ -1172,13 +1172,13 @@ void LCD_Init_LTDC() { /* Configure accumulated vertical back porch */ LTDC_InitStruct.LTDC_AccumulatedVBP = VBP; /* Configure accumulated active width */ - LTDC_InitStruct.LTDC_AccumulatedActiveW = LCD_W + HBP; + LTDC_InitStruct.LTDC_AccumulatedActiveW = LCD_PHYS_W + HBP; /* Configure accumulated active height */ - LTDC_InitStruct.LTDC_AccumulatedActiveH = LCD_H + VBP; + LTDC_InitStruct.LTDC_AccumulatedActiveH = LCD_PHYS_H + VBP; /* Configure total width */ - LTDC_InitStruct.LTDC_TotalWidth = LCD_W + HBP + HFP; + LTDC_InitStruct.LTDC_TotalWidth = LCD_PHYS_W + HBP + HFP; /* Configure total height */ - LTDC_InitStruct.LTDC_TotalHeigh = LCD_H + VBP + VFP; + LTDC_InitStruct.LTDC_TotalHeigh = LCD_PHYS_H + VBP + VFP; LTDC_Init(<DC_InitStruct); @@ -1198,7 +1198,7 @@ void LCD_Init_LTDC() { NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); - LTDC_LIPConfig(LCD_H); + LTDC_LIPConfig(LCD_PHYS_H); #if 0 DMA2D_ITConfig(DMA2D_CR_TCIE, ENABLE); @@ -1221,9 +1221,9 @@ void LCD_LayerInit() { Vertical start = vertical synchronization + vertical back porch = 4 Vertical stop = Vertical start + window height -1 = 4 + 320 -1 */ LTDC_Layer_InitStruct.LTDC_HorizontalStart = HBP + 1; - LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_W + HBP); + LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_PHYS_W + HBP); LTDC_Layer_InitStruct.LTDC_VerticalStart = VBP + 1; - LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_H + VBP); + LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_PHYS_H + VBP); /* Pixel Format configuration*/ LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_RGB565; @@ -1244,14 +1244,14 @@ void LCD_LayerInit() { Active high width = LCD_W number of bytes per pixel = 2 (pixel_format : RGB565) */ - LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_W * 2) + 3); + LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_PHYS_W * 2) + 3); /* the pitch is the increment from the start of one line of pixels to the start of the next line in bytes, then : Pitch = Active high width x number of bytes per pixel */ - LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_W * 2); + LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_PHYS_W * 2); /* Configure the number of lines */ - LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_H; + LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_PHYS_H; /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */ LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t) LCD_FIRST_FRAME_BUFFER; @@ -1646,12 +1646,21 @@ static void lcdSwitchLayers() // TODO: replace through some smarter mechanism without busy wait while(_frameBufferAddressReloaded == 0); } -void newLcdRefresh(uint16_t *buffer) + +static bool once = false; + +void newLcdRefresh(uint16_t *buffer, const rect_t& copy_area) { - LTDC_Layer1->CFBAR = (intptr_t)buffer; - _frameBufferAddressReloaded = 0; - LTDC->SRCR = LTDC_SRCR_VBR; - while(_frameBufferAddressReloaded == 0); + DMACopyBitmap((uint16_t*)LCD_BACKUP_FRAME_BUFFER, LCD_PHYS_W, LCD_PHYS_H, copy_area.x, copy_area.y, buffer, copy_area.w, copy_area.h, 0, 0, copy_area.w, copy_area.h); + + if(!once) + { + LTDC_Layer1->CFBAR = (intptr_t)LCD_BACKUP_FRAME_BUFFER; + _frameBufferAddressReloaded = 0; + LTDC->SRCR = LTDC_SRCR_VBR; + while(_frameBufferAddressReloaded == 0); + once=true; + } } void lcdRefresh()