chore(color): reduce busy wait time on LCD refresh (#7483)
This commit is contained in:
@@ -24,9 +24,7 @@
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
#include "edgetx_types.h"
|
||||
#include "dma2d.h"
|
||||
#include "hal.h"
|
||||
#include "delays_driver.h"
|
||||
#include "debug.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd_driver.h"
|
||||
@@ -35,15 +33,12 @@
|
||||
#include "stm32_gpio.h"
|
||||
#include "hal/gpio.h"
|
||||
|
||||
uint8_t TouchControllerType = 0; // 0: other; 1: CST836U
|
||||
static volatile uint16_t lcd_phys_w = LCD_H;
|
||||
static volatile uint16_t lcd_phys_h = LCD_W;
|
||||
|
||||
static LTDC_HandleTypeDef hltdc;
|
||||
static void* initialFrameBuffer = nullptr;
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
@@ -54,16 +49,11 @@ static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
// faster than cleaning by address
|
||||
SCB_CleanDCache();
|
||||
|
||||
// LTDC_Layer1->CFBAR &= ~(LTDC_LxCFBAR_CFBADD);
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
lcdSpiInitFucPtr lcdInitFunction;
|
||||
@@ -71,8 +61,6 @@ lcdSpiInitFucPtr lcdOffFunction;
|
||||
lcdSpiInitFucPtr lcdOnFunction;
|
||||
uint32_t lcdPixelClock;
|
||||
|
||||
volatile uint8_t LCD_ReadBuffer[24] = { 0, 0 };
|
||||
|
||||
static void LCD_Delay(void) {
|
||||
volatile unsigned int i;
|
||||
|
||||
@@ -1884,7 +1872,6 @@ void LCD_Init_LTDC() {
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, lcd_phys_h);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
void LCD_LayerInit() {
|
||||
@@ -2009,5 +1996,6 @@ extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
}
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __LCD_DRIVER_H__
|
||||
#define __LCD_DRIVER_H__
|
||||
#pragma once
|
||||
|
||||
#define HBP ( 24 ) // TODO use names from FlySky
|
||||
#define VBP ( 10 )
|
||||
@@ -66,12 +65,9 @@ extern lcdSpiInitFucPtr lcdOnFunction;
|
||||
|
||||
#define LCD_READ_DATA_PIN() LL_GPIO_IsInputPinSet(LCD_SPI_GPIO, LCD_SPI_MOSI_GPIO_PIN)
|
||||
|
||||
|
||||
#define HORIZONTAL_SYNC_WIDTH ( 4 )
|
||||
#define HORIZONTAL_BACK_PORCH ( 24 )
|
||||
#define HORIZONTAL_FRONT_PORCH ( 140 - HORIZONTAL_BACK_PORCH )
|
||||
#define VERTICAL_SYNC_HEIGHT ( 2 )
|
||||
#define VERTICAL_BACK_PORCH ( 10 )
|
||||
#define VERTICAL_FRONT_PORCH ( 22 - VERTICAL_BACK_PORCH )
|
||||
|
||||
#endif
|
||||
@@ -22,9 +22,7 @@
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "edgetx_types.h"
|
||||
#include "dma2d.h"
|
||||
#include "hal.h"
|
||||
#include "delays_driver.h"
|
||||
#include "debug.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd_driver_480.h"
|
||||
@@ -34,15 +32,9 @@
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_qspi.h"
|
||||
|
||||
uint8_t TouchControllerType = 0; // 0: other; 1: CST836U
|
||||
static volatile uint16_t lcd_phys_w = LCD_PHYS_W;
|
||||
static volatile uint16_t lcd_phys_h = LCD_PHYS_H;
|
||||
|
||||
static LTDC_HandleTypeDef hltdc;
|
||||
static void* initialFrameBuffer = nullptr;
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
@@ -55,23 +47,11 @@ static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
}
|
||||
|
||||
lcdSpiInitFucPtr lcdInitFunction;
|
||||
lcdSpiInitFucPtr lcdOffFunction;
|
||||
lcdSpiInitFucPtr lcdOnFunction;
|
||||
uint32_t lcdPixelClock;
|
||||
|
||||
volatile uint8_t LCD_ReadBuffer[24] = { 0, 0 };
|
||||
|
||||
static void LCD_Delay(void) {
|
||||
volatile unsigned int i;
|
||||
|
||||
@@ -424,13 +404,13 @@ void LCD_Init_LTDC() {
|
||||
/* Configure accumulated vertical back porch */
|
||||
hltdc.Init.AccumulatedVBP = VSH+VBP-1;
|
||||
/* Configure accumulated active width */
|
||||
hltdc.Init.AccumulatedActiveW = lcd_phys_w + HBP+HSW-1;
|
||||
hltdc.Init.AccumulatedActiveW = LCD_PHYS_W + HBP+HSW-1;
|
||||
/* Configure accumulated active height */
|
||||
hltdc.Init.AccumulatedActiveH = lcd_phys_h + VBP+VSH-1;
|
||||
hltdc.Init.AccumulatedActiveH = LCD_PHYS_H + VBP+VSH-1;
|
||||
/* Configure total width */
|
||||
hltdc.Init.TotalWidth = lcd_phys_w + HBP + HFP + HSW -1;
|
||||
hltdc.Init.TotalWidth = LCD_PHYS_W + HBP + HFP + HSW -1;
|
||||
/* Configure total height */
|
||||
hltdc.Init.TotalHeigh = lcd_phys_h + VBP + VFP+VSH-1;
|
||||
hltdc.Init.TotalHeigh = LCD_PHYS_H + VBP + VFP+VSH-1;
|
||||
|
||||
HAL_LTDC_Init(&hltdc);
|
||||
|
||||
@@ -439,8 +419,7 @@ void LCD_Init_LTDC() {
|
||||
NVIC_EnableIRQ(LTDC_IRQn);
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, lcd_phys_h);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, LCD_PHYS_H);
|
||||
}
|
||||
|
||||
void LCD_LayerInit() {
|
||||
@@ -448,9 +427,9 @@ void LCD_LayerInit() {
|
||||
|
||||
/* Windowing configuration */
|
||||
layer.WindowX0 = 0;
|
||||
layer.WindowX1 = lcd_phys_w;
|
||||
layer.WindowX1 = LCD_PHYS_W;
|
||||
layer.WindowY0 = 0;
|
||||
layer.WindowY1 = lcd_phys_h;
|
||||
layer.WindowY1 = LCD_PHYS_H;
|
||||
|
||||
/* Pixel Format configuration*/
|
||||
layer.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
|
||||
@@ -468,8 +447,8 @@ void LCD_LayerInit() {
|
||||
layer.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
|
||||
layer.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
|
||||
|
||||
layer.ImageWidth = lcd_phys_w;
|
||||
layer.ImageHeight = lcd_phys_h;
|
||||
layer.ImageWidth = LCD_PHYS_W;
|
||||
layer.ImageHeight = LCD_PHYS_H;
|
||||
|
||||
/* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */
|
||||
layer.FBStartAdress = (intptr_t)initialFrameBuffer;
|
||||
@@ -508,12 +487,9 @@ void lcdInit(void)
|
||||
/* Send LCD initialization commands */
|
||||
TRACE("LCD INIT (default): ST7365");
|
||||
boardLcdType = "ST7365 (Default)";
|
||||
lcdInitFunction = LCD_ST7365_Init;
|
||||
lcdOffFunction = LCD_ST7365_Off;
|
||||
lcdOnFunction = LCD_ST7365_On;
|
||||
|
||||
__HAL_RCC_LTDC_CLK_ENABLE();
|
||||
lcdInitFunction();
|
||||
LCD_ST7365_Init();
|
||||
|
||||
LCD_Init_LTDC();
|
||||
LCD_LayerInit();
|
||||
@@ -533,6 +509,6 @@ extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
}
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
@@ -19,10 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __LCD_DRIVER_H__
|
||||
#define __LCD_DRIVER_H__
|
||||
|
||||
#include "bsp_io.h"
|
||||
#pragma once
|
||||
|
||||
#define HBP ( 20 )
|
||||
#define VBP ( 10 )
|
||||
@@ -35,9 +32,6 @@
|
||||
|
||||
#define LCD_DELAY() LCD_Delay()
|
||||
|
||||
typedef void (*lcdSpiInitFucPtr)(void);
|
||||
typedef unsigned int LcdReadIDFucPtr( void );
|
||||
|
||||
#define SET_IO_INPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_INPUT )
|
||||
#define SET_IO_OUTPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_OUTPUT )
|
||||
|
||||
@@ -57,9 +51,3 @@ typedef unsigned int LcdReadIDFucPtr( void );
|
||||
#define LCD_MOSI_AS_OUTPUT() SET_IO_OUTPUT( LCD_SPI_MOSI_GPIO, LCD_SPI_MOSI_GPIO_PIN )
|
||||
|
||||
#define LCD_READ_DATA_PIN() LL_GPIO_IsInputPinSet(LCD_SPI_MOSI_GPIO, LCD_SPI_MOSI_GPIO_PIN)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "edgetx_types.h"
|
||||
#include "dma2d.h"
|
||||
#include "hal.h"
|
||||
#include "delays_driver.h"
|
||||
#include "debug.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd_driver_800.h"
|
||||
@@ -34,15 +32,9 @@
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_qspi.h"
|
||||
|
||||
uint8_t TouchControllerType = 0; // 0: other; 1: CST836U
|
||||
static const uint16_t lcd_phys_w = LCD_PHYS_W;
|
||||
static const uint16_t lcd_phys_h = LCD_PHYS_H;
|
||||
|
||||
static LTDC_HandleTypeDef hltdc;
|
||||
static void* initialFrameBuffer = nullptr;
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
@@ -55,23 +47,11 @@ static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
}
|
||||
|
||||
lcdSpiInitFucPtr lcdInitFunction;
|
||||
lcdSpiInitFucPtr lcdOffFunction;
|
||||
lcdSpiInitFucPtr lcdOnFunction;
|
||||
uint32_t lcdPixelClock;
|
||||
|
||||
volatile uint8_t LCD_ReadBuffer[24] = { 0, 0 };
|
||||
|
||||
static void LCD_AF_GPIOConfig(void)
|
||||
{
|
||||
const gpio_t _lcd_af_gpios[] = {
|
||||
@@ -121,8 +101,6 @@ static void lcdReset() {
|
||||
delay_ms(100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LCD_Init_LTDC() {
|
||||
hltdc.Instance = LTDC;
|
||||
|
||||
@@ -166,13 +144,13 @@ void LCD_Init_LTDC() {
|
||||
/* Configure accumulated vertical back porch */
|
||||
hltdc.Init.AccumulatedVBP = VSH+VBP-1;
|
||||
/* Configure accumulated active width */
|
||||
hltdc.Init.AccumulatedActiveW = lcd_phys_w + HBP+HSW-1;
|
||||
hltdc.Init.AccumulatedActiveW = LCD_PHYS_W + HBP+HSW-1;
|
||||
/* Configure accumulated active height */
|
||||
hltdc.Init.AccumulatedActiveH = lcd_phys_h + VBP+VSH-1;
|
||||
hltdc.Init.AccumulatedActiveH = LCD_PHYS_H + VBP+VSH-1;
|
||||
/* Configure total width */
|
||||
hltdc.Init.TotalWidth = lcd_phys_w + HBP + HFP + HSW -1;
|
||||
hltdc.Init.TotalWidth = LCD_PHYS_W + HBP + HFP + HSW -1;
|
||||
/* Configure total height */
|
||||
hltdc.Init.TotalHeigh = lcd_phys_h + VBP + VFP+VSH-1;
|
||||
hltdc.Init.TotalHeigh = LCD_PHYS_H + VBP + VFP+VSH-1;
|
||||
|
||||
HAL_LTDC_Init(&hltdc);
|
||||
|
||||
@@ -181,8 +159,7 @@ void LCD_Init_LTDC() {
|
||||
NVIC_EnableIRQ(LTDC_IRQn);
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, lcd_phys_h);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, LCD_PHYS_H);
|
||||
}
|
||||
|
||||
void LCD_LayerInit() {
|
||||
@@ -190,9 +167,9 @@ void LCD_LayerInit() {
|
||||
|
||||
/* Windowing configuration */
|
||||
layer.WindowX0 = 0;
|
||||
layer.WindowX1 = lcd_phys_w;
|
||||
layer.WindowX1 = LCD_PHYS_W;
|
||||
layer.WindowY0 = 0;
|
||||
layer.WindowY1 = lcd_phys_h;
|
||||
layer.WindowY1 = LCD_PHYS_H;
|
||||
|
||||
/* Pixel Format configuration*/
|
||||
layer.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
|
||||
@@ -210,8 +187,8 @@ void LCD_LayerInit() {
|
||||
layer.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
|
||||
layer.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
|
||||
|
||||
layer.ImageWidth = lcd_phys_w;
|
||||
layer.ImageHeight = lcd_phys_h;
|
||||
layer.ImageWidth = LCD_PHYS_W;
|
||||
layer.ImageHeight = LCD_PHYS_H;
|
||||
|
||||
/* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */
|
||||
layer.FBStartAdress = (intptr_t)initialFrameBuffer;
|
||||
@@ -271,5 +248,6 @@ extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
@@ -32,13 +32,6 @@
|
||||
#define HFP ( 16 )
|
||||
#define VFP ( 8 )
|
||||
|
||||
typedef void (*lcdSpiInitFucPtr)(void);
|
||||
typedef unsigned int LcdReadIDFucPtr( void );
|
||||
|
||||
extern lcdSpiInitFucPtr lcdInitFunction;
|
||||
extern lcdSpiInitFucPtr lcdOffFunction;
|
||||
extern lcdSpiInitFucPtr lcdOnFunction;
|
||||
|
||||
#define SET_IO_INPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_INPUT )
|
||||
#define SET_IO_OUTPUT( PORT, PIN ) LL_GPIO_SetPinMode( PORT, PIN, LL_GPIO_MODE_OUTPUT )
|
||||
|
||||
|
||||
@@ -33,46 +33,40 @@
|
||||
#include "board.h"
|
||||
#include "etx_lv_theme.h"
|
||||
|
||||
pixel_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
pixel_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
pixel_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM __ALIGNED(64);
|
||||
pixel_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM __ALIGNED(64);
|
||||
|
||||
BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H,
|
||||
(uint16_t*)LCD_FIRST_FRAME_BUFFER);
|
||||
BitmapBuffer lcdBuffer2(BMP_RGB565, LCD_W, LCD_H,
|
||||
(uint16_t*)LCD_SECOND_FRAME_BUFFER);
|
||||
|
||||
BitmapBuffer* lcdFront = &lcdBuffer1;
|
||||
BitmapBuffer* lcd = &lcdBuffer2;
|
||||
BitmapBuffer lcd(BMP_RGB565, LCD_W, LCD_H, (uint16_t*)LCD_FIRST_FRAME_BUFFER);
|
||||
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
static lv_disp_drv_t disp_drv;
|
||||
|
||||
static lv_disp_t disp;
|
||||
|
||||
// Call backs
|
||||
static void (*lcd_flush_cb)(lv_disp_drv_t*, uint16_t* buffer,
|
||||
const rect_t& area) = nullptr;
|
||||
|
||||
extern "C" void lcdFlushed()
|
||||
{
|
||||
lv_disp_flush_ready(&disp_drv);
|
||||
}
|
||||
|
||||
void lcdSetFlushCb(void (*cb)(lv_disp_drv_t*, uint16_t*, const rect_t&))
|
||||
{
|
||||
lcd_flush_cb = cb;
|
||||
}
|
||||
|
||||
static lv_disp_drv_t* refr_disp = nullptr;
|
||||
|
||||
static void flushLcd(lv_disp_drv_t* disp_drv, const lv_area_t* area,
|
||||
lv_color_t* color_p)
|
||||
{
|
||||
if (lcd_flush_cb) {
|
||||
refr_disp = disp_drv;
|
||||
|
||||
rect_t copy_area = {area->x1, area->y1, area->x2 - area->x1 + 1,
|
||||
area->y2 - area->y1 + 1};
|
||||
|
||||
lcd_flush_cb(disp_drv, (uint16_t*)color_p, copy_area);
|
||||
} else {
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
static void clear_frame_buffers()
|
||||
@@ -83,24 +77,27 @@ static void clear_frame_buffers()
|
||||
|
||||
static void init_lvgl_disp_drv()
|
||||
{
|
||||
lv_disp_draw_buf_init(&disp_buf, lcdFront->getData(), lcd->getData(), LCD_W * LCD_H);
|
||||
int direct_mode = 1;
|
||||
#if LCD_VERTICAL_INVERT
|
||||
#if defined(RADIO_F16)
|
||||
direct_mode = (hardwareOptions.pcbrev > 0) ? 1 : 0;
|
||||
#else
|
||||
direct_mode = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
lv_disp_draw_buf_init(&disp_buf,
|
||||
LCD_FIRST_FRAME_BUFFER,
|
||||
direct_mode ? LCD_SECOND_FRAME_BUFFER : nullptr,
|
||||
LCD_W * LCD_H);
|
||||
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.wait_cb = nullptr; /*Set a wait callback*/
|
||||
|
||||
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.full_refresh = 0;
|
||||
|
||||
#if !LCD_VERTICAL_INVERT
|
||||
disp_drv.direct_mode = 1;
|
||||
#elif defined(RADIO_F16)
|
||||
disp_drv.direct_mode = (hardwareOptions.pcbrev > 0) ? 1 : 0;
|
||||
#else
|
||||
disp_drv.direct_mode = 0;
|
||||
#endif
|
||||
disp_drv.direct_mode = direct_mode;
|
||||
}
|
||||
|
||||
void lcdInitDisplayDriver()
|
||||
@@ -119,7 +116,7 @@ void lcdInitDisplayDriver()
|
||||
|
||||
// Clear buffers first
|
||||
clear_frame_buffers();
|
||||
lcdSetInitalFrameBuffer(lcdFront->getData());
|
||||
lcdSetInitalFrameBuffer(lcd.getData());
|
||||
|
||||
// Init hardware LCD driver
|
||||
lcdInit();
|
||||
@@ -141,32 +138,24 @@ void lcdInitDisplayDriver()
|
||||
}
|
||||
|
||||
lv_draw_ctx_t* draw_ctx = disp_drv.draw_ctx;
|
||||
lcd->setDrawCtx(draw_ctx);
|
||||
lcdFront->setDrawCtx(draw_ctx);
|
||||
lcd.setDrawCtx(draw_ctx);
|
||||
|
||||
#if defined(LCD_BACKLIGHT_INIT_DELAY_MS)
|
||||
delay_ms(LCD_BACKLIGHT_INIT_DELAY_MS);
|
||||
#endif
|
||||
|
||||
backlightInit();
|
||||
}
|
||||
|
||||
void lcdClear() { lcd->clear(); }
|
||||
|
||||
// Direct drawing - used by boot loader
|
||||
|
||||
void lcdInitDirectDrawing()
|
||||
{
|
||||
static lv_area_t screen_area = {0, 0, LCD_W - 1, LCD_H - 1};
|
||||
|
||||
lv_draw_ctx_t* draw_ctx = disp_drv.draw_ctx;
|
||||
draw_ctx->buf = disp_drv.draw_buf->buf_act;
|
||||
draw_ctx->buf_area = &screen_area;
|
||||
draw_ctx->clip_area = &screen_area;
|
||||
lcd->setData((pixel_t*)draw_ctx->buf);
|
||||
lcd->reset();
|
||||
|
||||
#if defined(LCD_BACKLIGHT_INIT_DELAY_MS)
|
||||
delay_ms(LCD_BACKLIGHT_INIT_DELAY_MS);
|
||||
#endif
|
||||
|
||||
backlightInit();
|
||||
}
|
||||
|
||||
void lcdClear() { lcd.clear(); }
|
||||
|
||||
// Direct drawing - used by boot loader
|
||||
|
||||
//
|
||||
// Private code copied and adapted from LVGL / lv_refr.c
|
||||
// (_call_flush_cb & _draw_buf_flush)
|
||||
@@ -182,21 +171,12 @@ static void _call_flush_cb(lv_disp_drv_t* drv, const lv_area_t* area,
|
||||
drv->flush_cb(drv, &offset_area, color_p);
|
||||
}
|
||||
|
||||
static void _draw_buf_flush(lv_disp_t* disp)
|
||||
void lcdRefresh()
|
||||
{
|
||||
/* Flush the rendered content to the display */
|
||||
lv_disp_t* disp = _lv_refr_get_disp_refreshing();
|
||||
lv_disp_draw_buf_t* draw_buf = lv_disp_get_draw_buf(disp);
|
||||
|
||||
/*Flush the rendered content to the display*/
|
||||
lv_draw_ctx_t* draw_ctx = disp->driver->draw_ctx;
|
||||
if (draw_ctx->wait_for_finish) draw_ctx->wait_for_finish(draw_ctx);
|
||||
|
||||
/* In double buffered mode wait until the other buffer is freed
|
||||
* and driver is ready to receive the new buffer */
|
||||
if (draw_buf->buf1 && draw_buf->buf2) {
|
||||
while (draw_buf->flushing) {
|
||||
if (disp->driver->wait_cb) disp->driver->wait_cb(disp->driver);
|
||||
}
|
||||
}
|
||||
|
||||
draw_buf->flushing = 1;
|
||||
draw_buf->flushing_last = 1;
|
||||
@@ -208,15 +188,17 @@ static void _draw_buf_flush(lv_disp_t* disp)
|
||||
|
||||
/*If there are 2 buffers swap them. */
|
||||
if (draw_buf->buf1 && draw_buf->buf2) {
|
||||
/* In double buffered mode wait until the other buffer is freed
|
||||
* and driver is ready to receive the new buffer */
|
||||
while (draw_buf->flushing);
|
||||
if (draw_buf->buf_act == draw_buf->buf1)
|
||||
draw_buf->buf_act = draw_buf->buf2;
|
||||
else
|
||||
draw_buf->buf_act = draw_buf->buf1;
|
||||
}
|
||||
}
|
||||
|
||||
void lcdRefresh()
|
||||
{
|
||||
lv_disp_t* d = _lv_refr_get_disp_refreshing();
|
||||
_draw_buf_flush(d);
|
||||
// Update draw context and lcd bitmap
|
||||
draw_ctx->buf = draw_buf->buf_act;
|
||||
lcd.setData((pixel_t*)draw_buf->buf_act);
|
||||
lcd.reset();
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ constexpr coord_t PROGRESS_W = LCD_W * 3 / 4;
|
||||
constexpr coord_t PROGRESS_X = (LCD_W - PROGRESS_W) / 2;
|
||||
LAYOUT_VAL_SCALED(PROGRESS_H, 31)
|
||||
|
||||
extern BitmapBuffer * lcd;
|
||||
extern BitmapBuffer lcd;
|
||||
|
||||
#if defined(USB_SW_GPIO)
|
||||
#include "hal/gpio.h"
|
||||
@@ -74,28 +74,28 @@ void blExit(void)
|
||||
|
||||
static void bootloaderDrawTitle(const char* text)
|
||||
{
|
||||
lcd->drawText(LCD_W / 2, TITLE_Y1, text, CENTERED | BL_FOREGROUND);
|
||||
lcd->drawSolidFilledRect(PAD_LARGE, TITLE_Y2, LCD_W - PAD_LARGE * 2, LINE_H, BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, TITLE_Y1, text, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawSolidFilledRect(PAD_LARGE, TITLE_Y2, LCD_W - PAD_LARGE * 2, LINE_H, BL_FOREGROUND);
|
||||
}
|
||||
|
||||
static void bootloaderDrawFooter()
|
||||
{
|
||||
lcd->drawSolidFilledRect(PAD_LARGE, LCD_H - FOOTER_LY, LCD_W - PAD_LARGE * 2, LINE_H, BL_FOREGROUND);
|
||||
lcd.drawSolidFilledRect(PAD_LARGE, LCD_H - FOOTER_LY, LCD_W - PAD_LARGE * 2, LINE_H, BL_FOREGROUND);
|
||||
}
|
||||
|
||||
static void bootloaderDrawVerFooter()
|
||||
{
|
||||
bootloaderDrawFooter();
|
||||
if (LCD_W < LCD_H)
|
||||
lcd->drawText(LCD_W / 2, LCD_H - FOOTER_Y2 + PAD_TINY, TR_BL_CURRENT_FW, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H - FOOTER_Y2 + PAD_TINY, TR_BL_CURRENT_FW, CENTERED | BL_FOREGROUND);
|
||||
const char* fw_ver = getFirmwareVersion();
|
||||
if (!fw_ver) fw_ver = TR_BL_NO_VERSION;
|
||||
lcd->drawText(LCD_W / 2, LCD_H - FOOTER_Y1, fw_ver, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H - FOOTER_Y1, fw_ver, CENTERED | BL_FOREGROUND);
|
||||
}
|
||||
|
||||
static void bootloaderDrawBackground()
|
||||
{
|
||||
lcd->clear(BL_BACKGROUND);
|
||||
lcd.clear(BL_BACKGROUND);
|
||||
}
|
||||
|
||||
bool bootloaderRadioMenu(uint32_t menuItem, event_t event)
|
||||
@@ -157,14 +157,12 @@ void bootloaderInitScreen()
|
||||
|
||||
void bootloaderDrawDFUScreen()
|
||||
{
|
||||
lcdInitDirectDrawing();
|
||||
bootloaderDrawBackground();
|
||||
lcd->drawText(LCD_W / 2, LCD_H / 2, TR_BL_DFU_MODE, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H / 2, TR_BL_DFU_MODE, CENTERED | BL_FOREGROUND);
|
||||
}
|
||||
|
||||
void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
{
|
||||
lcdInitDirectDrawing();
|
||||
bootloaderDrawBackground();
|
||||
|
||||
bootloaderDrawTitle(BOOTLOADER_TITLE);
|
||||
@@ -173,9 +171,9 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
|
||||
const char* msg = (st == ST_START) ? TR_BL_PLUG_USB : TR_BL_COPY_UF2;
|
||||
|
||||
lcd->drawText(LCD_W / 2, LCD_H / 2 - TITLE_Y1, msg, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H / 2 - TITLE_Y1, msg, CENTERED | BL_FOREGROUND);
|
||||
if (st != ST_USB)
|
||||
lcd->drawText(LCD_W / 2, LCD_H / 2 + TITLE_Y1, LV_SYMBOL_NEW_LINE " " TR_BL_EXIT_KEY, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H / 2 + TITLE_Y1, LV_SYMBOL_NEW_LINE " " TR_BL_EXIT_KEY, CENTERED | BL_FOREGROUND);
|
||||
|
||||
bootloaderDrawVerFooter();
|
||||
|
||||
@@ -184,11 +182,11 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
const coord_t pb_y = (LCD_H - PROGRESS_H) / 2;
|
||||
|
||||
const char* msg = (st == ST_FLASH_DONE) ? TR_BL_WRITING_COMPL : TR_BL_WRITING_FW;
|
||||
lcd->drawText(PROGRESS_X, pb_y - TITLE_Y1, msg, BL_FOREGROUND);
|
||||
lcd->drawRect(PROGRESS_X, pb_y, PROGRESS_W, PROGRESS_H, LINE_H, SOLID, BL_SELECTED);
|
||||
lcd.drawText(PROGRESS_X, pb_y - TITLE_Y1, msg, BL_FOREGROUND);
|
||||
lcd.drawRect(PROGRESS_X, pb_y, PROGRESS_W, PROGRESS_H, LINE_H, SOLID, BL_SELECTED);
|
||||
|
||||
LcdFlags color = (st == ST_FLASH_DONE) ? BL_GREEN : BL_RED;
|
||||
lcd->drawSolidFilledRect(PROGRESS_X + PAD_SMALL, pb_y + PAD_SMALL, ((PROGRESS_W - PAD_SMALL * 2) * opt) / 100, PROGRESS_H - PAD_SMALL * 2, color);
|
||||
lcd.drawSolidFilledRect(PROGRESS_X + PAD_SMALL, pb_y + PAD_SMALL, ((PROGRESS_W - PAD_SMALL * 2) * opt) / 100, PROGRESS_H - PAD_SMALL * 2, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,8 +245,8 @@ void bootloaderInitScreen()
|
||||
|
||||
void bootloaderDrawItem(const char* symbol, const char* text, coord_t& y, coord_t& lastX, coord_t symXO = 0)
|
||||
{
|
||||
lcd->drawText(SYM_X - symXO, y, symbol, BL_FOREGROUND);
|
||||
coord_t nx = lcd->drawText(LBL_X, y, text, BL_FOREGROUND) + BOX_GAP;
|
||||
lcd.drawText(SYM_X - symXO, y, symbol, BL_FOREGROUND);
|
||||
coord_t nx = lcd.drawText(LBL_X, y, text, BL_FOREGROUND) + BOX_GAP;
|
||||
if (nx > lastX) lastX = nx;
|
||||
y += SYM_H;
|
||||
}
|
||||
@@ -256,12 +254,11 @@ void bootloaderDrawItem(const char* symbol, const char* text, coord_t& y, coord_
|
||||
void bootloaderDrawSelected(coord_t boxX2, int opt)
|
||||
{
|
||||
boxX2 -= OPTBOX_X;
|
||||
lcd->drawSolidRect(OPTBOX_X, BOX_Y + (opt * SYM_H), boxX2, BOX_H, PAD_TINY, BL_SELECTED);
|
||||
lcd.drawSolidRect(OPTBOX_X, BOX_Y + (opt * SYM_H), boxX2, BOX_H, PAD_TINY, BL_SELECTED);
|
||||
}
|
||||
|
||||
void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
{
|
||||
lcdInitDirectDrawing();
|
||||
bootloaderDrawBackground();
|
||||
|
||||
coord_t y = SYM_Y, boxX2 = 0;
|
||||
@@ -286,9 +283,9 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
|
||||
bootloaderDrawSelected(boxX2, opt);
|
||||
|
||||
lcd->drawBitmap(USB_ICN_X, LCD_H - USB_ICN_Y, (const BitmapBuffer*)&BMP_PLUG_USB);
|
||||
lcd->drawText(USB_TXT_X, LCD_H - USB_TXT_Y1, TR_BL_USB_PLUGIN, USB_TXT_ALIGN | BL_FOREGROUND);
|
||||
lcd->drawText(USB_TXT_X, LCD_H - USB_TXT_Y2, TR_BL_USB_MASS_STORE, USB_TXT_ALIGN | BL_FOREGROUND);
|
||||
lcd.drawBitmap(USB_ICN_X, LCD_H - USB_ICN_Y, (const BitmapBuffer*)&BMP_PLUG_USB);
|
||||
lcd.drawText(USB_TXT_X, LCD_H - USB_TXT_Y1, TR_BL_USB_PLUGIN, USB_TXT_ALIGN | BL_FOREGROUND);
|
||||
lcd.drawText(USB_TXT_X, LCD_H - USB_TXT_Y2, TR_BL_USB_MASS_STORE, USB_TXT_ALIGN | BL_FOREGROUND);
|
||||
|
||||
bootloaderDrawVerFooter();
|
||||
}
|
||||
@@ -301,7 +298,7 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
bootloaderDrawSelected(boxX2, opt);
|
||||
|
||||
bootloaderDrawFooter();
|
||||
int pos = lcd->drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_SD_CARD " " TR_BL_ERASE_KEY, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
int pos = lcd.drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_SD_CARD " " TR_BL_ERASE_KEY, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
#if LANDSCAPE
|
||||
pos = 0;
|
||||
#else
|
||||
@@ -309,12 +306,12 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
pos = (pos - FOOTER_X1) / 2;
|
||||
}
|
||||
#endif
|
||||
lcd->drawText(FOOTER_X2 - pos, LCD_H - FOOTER_Y2, LV_SYMBOL_NEW_LINE " " TR_BL_EXIT_KEY, FOOTER_ALIGN2 | BL_FOREGROUND);
|
||||
lcd.drawText(FOOTER_X2 - pos, LCD_H - FOOTER_Y2, LV_SYMBOL_NEW_LINE " " TR_BL_EXIT_KEY, FOOTER_ALIGN2 | BL_FOREGROUND);
|
||||
}
|
||||
else if (st == ST_CLEAR_FLASH) {
|
||||
bootloaderDrawTitle(TR_BL_ERASE_INT_FLASH);
|
||||
|
||||
lcd->drawText(LCD_W / 2, SYM_Y, TR_BL_ERASE_FLASH_MSG, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, SYM_Y, TR_BL_ERASE_FLASH_MSG, CENTERED | BL_FOREGROUND);
|
||||
bootloaderDrawFooter();
|
||||
}
|
||||
#endif
|
||||
@@ -327,7 +324,7 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
bootloaderDrawSelected(boxX2, opt);
|
||||
|
||||
bootloaderDrawFooter();
|
||||
int pos = lcd->drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_USB " " TR_BL_TOGGLE_KEY, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
int pos = lcd.drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_USB " " TR_BL_TOGGLE_KEY, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
#if LANDSCAPE
|
||||
pos = 0;
|
||||
#else
|
||||
@@ -335,13 +332,13 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
pos = (pos - FOOTER_X1) / 2;
|
||||
}
|
||||
#endif
|
||||
lcd->drawText(FOOTER_X2 - pos, LCD_H - FOOTER_Y2, LV_SYMBOL_NEW_LINE " " TR_BL_EXIT_KEY, FOOTER_ALIGN2 | BL_FOREGROUND);
|
||||
lcd.drawText(FOOTER_X2 - pos, LCD_H - FOOTER_Y2, LV_SYMBOL_NEW_LINE " " TR_BL_EXIT_KEY, FOOTER_ALIGN2 | BL_FOREGROUND);
|
||||
}
|
||||
#endif
|
||||
else if (st == ST_USB) {
|
||||
y = (LCD_H - BMP_USB_PLUGGED.height()) / 2;
|
||||
lcd->drawBitmap(USB_PLG_X, y, (const BitmapBuffer*)&BMP_USB_PLUGGED);
|
||||
lcd->drawText(USB_TXT_X, y + USB_PLG_TXT_YO, TR_BL_USB_CONNECTED, USB_TXT_ALIGN | BL_FOREGROUND);
|
||||
lcd.drawBitmap(USB_PLG_X, y, (const BitmapBuffer*)&BMP_USB_PLUGGED);
|
||||
lcd.drawText(USB_TXT_X, y + USB_PLG_TXT_YO, TR_BL_USB_CONNECTED, USB_TXT_ALIGN | BL_FOREGROUND);
|
||||
}
|
||||
else if (st == ST_FILE_LIST || st == ST_DIR_CHECK || st == ST_FLASH_CHECK ||
|
||||
st == ST_FLASHING || st == ST_FLASH_DONE) {
|
||||
@@ -356,37 +353,37 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
opt = 100; // Completed > 100%
|
||||
}
|
||||
|
||||
lcd->drawRect(PROGRESS_X, (LCD_H - PROGRESS_H) / 2, PROGRESS_W, PROGRESS_H, LINE_H, SOLID, BL_SELECTED);
|
||||
lcd->drawSolidFilledRect(PROGRESS_X + PAD_SMALL, (LCD_H - PROGRESS_H) / 2 + PAD_SMALL, ((PROGRESS_W - PAD_SMALL * 2) * opt) / 100, PROGRESS_H - PAD_SMALL * 2, color);
|
||||
lcd.drawRect(PROGRESS_X, (LCD_H - PROGRESS_H) / 2, PROGRESS_W, PROGRESS_H, LINE_H, SOLID, BL_SELECTED);
|
||||
lcd.drawSolidFilledRect(PROGRESS_X + PAD_SMALL, (LCD_H - PROGRESS_H) / 2 + PAD_SMALL, ((PROGRESS_W - PAD_SMALL * 2) * opt) / 100, PROGRESS_H - PAD_SMALL * 2, color);
|
||||
} else if (st == ST_DIR_CHECK) {
|
||||
if (opt == FR_NO_PATH) {
|
||||
lcd->drawText(LCD_W / 2, LCD_H / 2, LV_SYMBOL_CLOSE " " TR_BL_DIR_MISSING, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H / 2, LV_SYMBOL_CLOSE " " TR_BL_DIR_MISSING, CENTERED | BL_FOREGROUND);
|
||||
} else {
|
||||
lcd->drawText(LCD_W / 2, LCD_H / 2, LV_SYMBOL_CLOSE " " TR_BL_DIR_EMPTY, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H / 2, LV_SYMBOL_CLOSE " " TR_BL_DIR_EMPTY, CENTERED | BL_FOREGROUND);
|
||||
}
|
||||
} else if (st == ST_FLASH_CHECK) {
|
||||
bootloaderDrawFilename(str, 0, true);
|
||||
|
||||
if (opt == FC_ERROR) {
|
||||
lcd->drawText(LCD_W / 2, LCD_H / 2, LV_SYMBOL_CLOSE " " TR_BL_INVALID_FIRMWARE, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H / 2, LV_SYMBOL_CLOSE " " TR_BL_INVALID_FIRMWARE, CENTERED | BL_FOREGROUND);
|
||||
} else if (opt == FC_OK) {
|
||||
VersionTag tag;
|
||||
memset(&tag, 0, sizeof(tag));
|
||||
getFileFirmwareVersion(&tag);
|
||||
|
||||
if (strcmp(tag.flavour, FLAVOUR)) {
|
||||
lcd->drawText(LCD_W / 2, LCD_H / 2, LV_SYMBOL_CLOSE " " TR_BL_INVALID_FIRMWARE, CENTERED | BL_FOREGROUND);
|
||||
lcd.drawText(LCD_W / 2, LCD_H / 2, LV_SYMBOL_CLOSE " " TR_BL_INVALID_FIRMWARE, CENTERED | BL_FOREGROUND);
|
||||
} else {
|
||||
lcd->drawText(VERCHK_X, VERCHK_Y, TR_BL_FORK, RIGHT | BL_FOREGROUND);
|
||||
lcd->drawSizedText(VERCHK_X + PAD_MEDIUM, VERCHK_Y, tag.fork, 6, BL_FOREGROUND);
|
||||
lcd.drawText(VERCHK_X, VERCHK_Y, TR_BL_FORK, RIGHT | BL_FOREGROUND);
|
||||
lcd.drawSizedText(VERCHK_X + PAD_MEDIUM, VERCHK_Y, tag.fork, 6, BL_FOREGROUND);
|
||||
|
||||
lcd->drawText(VERCHK_X, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT, TR_BL_VERSION, RIGHT | BL_FOREGROUND);
|
||||
lcd->drawText(VERCHK_X + PAD_MEDIUM, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT, tag.version, BL_FOREGROUND);
|
||||
lcd.drawText(VERCHK_X, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT, TR_BL_VERSION, RIGHT | BL_FOREGROUND);
|
||||
lcd.drawText(VERCHK_X + PAD_MEDIUM, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT, tag.version, BL_FOREGROUND);
|
||||
|
||||
lcd->drawText(VERCHK_X, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT * 2, TR_BL_RADIO, RIGHT | BL_FOREGROUND);
|
||||
lcd->drawText(VERCHK_X + PAD_MEDIUM, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT * 2, tag.flavour, BL_FOREGROUND);
|
||||
lcd.drawText(VERCHK_X, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT * 2, TR_BL_RADIO, RIGHT | BL_FOREGROUND);
|
||||
lcd.drawText(VERCHK_X + PAD_MEDIUM, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT * 2, tag.flavour, BL_FOREGROUND);
|
||||
|
||||
lcd->drawText(VERCHK_ICN_X, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT, LV_SYMBOL_OK, BL_GREEN);
|
||||
lcd.drawText(VERCHK_ICN_X, VERCHK_Y + EdgeTxStyles::STD_FONT_HEIGHT, LV_SYMBOL_OK, BL_GREEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,16 +394,16 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
int align = FOOTER_ALIGN2;
|
||||
if ( st != ST_DIR_CHECK && (st != ST_FLASH_CHECK || opt == FC_OK)) {
|
||||
if (st == ST_FILE_LIST) {
|
||||
pos = lcd->drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_CHARGE " " TR_BL_SELECT_KEY, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
pos = lcd.drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_CHARGE " " TR_BL_SELECT_KEY, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
}
|
||||
else if (st == ST_FLASH_CHECK && opt == FC_OK) {
|
||||
pos = lcd->drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_CHARGE " " TR_BL_FLASH_KEY, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
pos = lcd.drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_CHARGE " " TR_BL_FLASH_KEY, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
}
|
||||
else if (st == ST_FLASHING) {
|
||||
pos = lcd->drawText(LCD_W / 2, LCD_H - FOOTER_Y1, LV_SYMBOL_CHARGE " " TR_BL_WRITING_FW, CENTERED | BL_FOREGROUND);
|
||||
pos = lcd.drawText(LCD_W / 2, LCD_H - FOOTER_Y1, LV_SYMBOL_CHARGE " " TR_BL_WRITING_FW, CENTERED | BL_FOREGROUND);
|
||||
}
|
||||
else if (st == ST_FLASH_DONE) {
|
||||
pos = lcd->drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_CHARGE " " TR_BL_WRITING_COMPL, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
pos = lcd.drawText(FOOTER_X1, LCD_H - FOOTER_Y1, LV_SYMBOL_CHARGE " " TR_BL_WRITING_COMPL, FOOTER_ALIGN1 | BL_FOREGROUND);
|
||||
}
|
||||
}
|
||||
#if LANDSCAPE
|
||||
@@ -419,18 +416,18 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
}
|
||||
#endif
|
||||
if (st != ST_FLASHING) {
|
||||
lcd->drawText(FOOTER_X2 - pos, LCD_H - FOOTER_Y2, LV_SYMBOL_NEW_LINE " " TR_BL_EXIT_KEY, align | BL_FOREGROUND);
|
||||
lcd.drawText(FOOTER_X2 - pos, LCD_H - FOOTER_Y2, LV_SYMBOL_NEW_LINE " " TR_BL_EXIT_KEY, align | BL_FOREGROUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bootloaderDrawFilename(const char* str, uint8_t line, bool selected)
|
||||
{
|
||||
lcd->drawText(FILENAM_X1, FILENAM_Y1 + (line * FILENAM_H), LV_SYMBOL_FILE, BL_FOREGROUND);
|
||||
lcd->drawText(FILENAM_X2, FILENAM_Y1 + (line * FILENAM_H), str, BL_FOREGROUND);
|
||||
lcd.drawText(FILENAM_X1, FILENAM_Y1 + (line * FILENAM_H), LV_SYMBOL_FILE, BL_FOREGROUND);
|
||||
lcd.drawText(FILENAM_X2, FILENAM_Y1 + (line * FILENAM_H), str, BL_FOREGROUND);
|
||||
|
||||
if (selected) {
|
||||
lcd->drawSolidRect(FILESEL_X, BOX_Y + (line * FILENAM_H), FILESEL_W, BOX_H, PAD_TINY, BL_SELECTED);
|
||||
lcd.drawSolidRect(FILESEL_X, BOX_Y + (line * FILENAM_H), FILESEL_W, BOX_H, PAD_TINY, BL_SELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,49 +40,43 @@ char* get_lvgl_mem(int nbytes)
|
||||
}
|
||||
#endif
|
||||
|
||||
pixel_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
pixel_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
|
||||
BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H,
|
||||
(uint16_t*)LCD_FIRST_FRAME_BUFFER);
|
||||
BitmapBuffer lcdBuffer2(BMP_RGB565, LCD_W, LCD_H,
|
||||
(uint16_t*)LCD_SECOND_FRAME_BUFFER);
|
||||
|
||||
static BitmapBuffer* lcdFront = &lcdBuffer1;
|
||||
static BitmapBuffer* lcd = &lcdBuffer2;
|
||||
pixel_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM __ALIGNED(64);
|
||||
pixel_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE] __SDRAM __ALIGNED(64);
|
||||
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
static lv_disp_drv_t disp_drv;
|
||||
|
||||
// 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 lcdSetFlushCb(void (*cb)(lv_disp_drv_t*, uint16_t*, const rect_t&))
|
||||
{
|
||||
lcd_flush_cb = cb;
|
||||
}
|
||||
|
||||
static lv_disp_drv_t* refr_disp = nullptr;
|
||||
#if defined(SIMU)
|
||||
// Only used in simulator to prevent lock up when closing simulator
|
||||
// TODO: find a better way to handle this
|
||||
static void (*lcd_wait_cb)(lv_disp_drv_t*) = nullptr;
|
||||
void lcdSetWaitCb(void (*cb)(lv_disp_drv_t*)) { lcd_wait_cb = cb; }
|
||||
#endif
|
||||
|
||||
extern "C" void lcdFlushed()
|
||||
{
|
||||
lv_disp_flush_ready(&disp_drv);
|
||||
}
|
||||
|
||||
void lcdRefresh() {}
|
||||
|
||||
static void flushLcd(lv_disp_drv_t* disp_drv, const lv_area_t* area,
|
||||
lv_color_t* color_p)
|
||||
{
|
||||
#if !LCD_VERTICAL_INVERT || defined(RADIO_F16)
|
||||
#if defined(RADIO_F16)
|
||||
if (hardwareOptions.pcbrev > 0)
|
||||
#endif
|
||||
{
|
||||
// we're only interested in the last flush in direct mode
|
||||
if (!lv_disp_flush_is_last(disp_drv)) {
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
return;
|
||||
}
|
||||
// we're only interested in the last flush in direct mode
|
||||
if (disp_drv->direct_mode && !lv_disp_flush_is_last(disp_drv)) {
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
if (area->x1 != 0 || area->x2 != LCD_W - 1 || area->y1 != 0 ||
|
||||
@@ -95,15 +89,13 @@ static void flushLcd(lv_disp_drv_t* disp_drv, const lv_area_t* area,
|
||||
#endif
|
||||
|
||||
if (lcd_flush_cb) {
|
||||
refr_disp = disp_drv;
|
||||
|
||||
rect_t copy_area = {area->x1, area->y1, area->x2 - area->x1 + 1,
|
||||
area->y2 - area->y1 + 1};
|
||||
|
||||
lcd_flush_cb(disp_drv, (uint16_t*)color_p, copy_area);
|
||||
} else {
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
static void clear_frame_buffers()
|
||||
@@ -114,25 +106,30 @@ static void clear_frame_buffers()
|
||||
|
||||
static void init_lvgl_disp_drv()
|
||||
{
|
||||
lv_disp_draw_buf_init(&disp_buf, lcdFront->getData(), lcd->getData(),
|
||||
int direct_mode = 1;
|
||||
#if LCD_VERTICAL_INVERT
|
||||
#if defined(RADIO_F16)
|
||||
direct_mode = (hardwareOptions.pcbrev > 0) ? 1 : 0;
|
||||
#else
|
||||
direct_mode = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
lv_disp_draw_buf_init(&disp_buf,
|
||||
LCD_FIRST_FRAME_BUFFER,
|
||||
direct_mode ? LCD_SECOND_FRAME_BUFFER : nullptr,
|
||||
LCD_W * LCD_H);
|
||||
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*/
|
||||
#if defined(SIMU)
|
||||
disp_drv.wait_cb = lcd_wait_cb; /*Set a wait callback*/
|
||||
#endif
|
||||
|
||||
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.full_refresh = 0;
|
||||
|
||||
#if !LCD_VERTICAL_INVERT
|
||||
disp_drv.direct_mode = 1;
|
||||
#elif defined(RADIO_F16)
|
||||
disp_drv.direct_mode = (hardwareOptions.pcbrev > 0) ? 1 : 0;
|
||||
#else
|
||||
disp_drv.direct_mode = 0;
|
||||
#endif
|
||||
disp_drv.direct_mode = direct_mode;
|
||||
}
|
||||
|
||||
void lcdInitDisplayDriver()
|
||||
@@ -153,7 +150,7 @@ void lcdInitDisplayDriver()
|
||||
|
||||
// Clear buffers first
|
||||
clear_frame_buffers();
|
||||
lcdSetInitalFrameBuffer(lcdFront->getData());
|
||||
lcdSetInitalFrameBuffer(LCD_FIRST_FRAME_BUFFER);
|
||||
|
||||
// Init hardware LCD driver
|
||||
lcdInit();
|
||||
@@ -167,17 +164,3 @@ void lcdInitDisplayDriver()
|
||||
// remove all styles on default screen (makes it transparent as well)
|
||||
lv_obj_remove_style_all(lv_scr_act());
|
||||
}
|
||||
|
||||
void lcdFlushed()
|
||||
{
|
||||
// Only used in simulator
|
||||
|
||||
// its possible to get here before flushLcd is ever called.
|
||||
// so check for nullptr first. (Race condition if you put breakpoints in
|
||||
// startup code)
|
||||
if (refr_disp != nullptr) lv_disp_flush_ready(refr_disp);
|
||||
}
|
||||
|
||||
#if defined(SIMU)
|
||||
void lcdRefresh() {}
|
||||
#endif
|
||||
|
||||
@@ -39,17 +39,16 @@ 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&));
|
||||
#if defined(SIMU)
|
||||
void lcdSetWaitCb(void (*cb)(lv_disp_drv_t *));
|
||||
#endif
|
||||
|
||||
// Init LVGL and its display driver
|
||||
void lcdInitDisplayDriver();
|
||||
|
||||
void lcdClear();
|
||||
|
||||
// Patch the draw context to allow for direct drawing
|
||||
void lcdInitDirectDrawing();
|
||||
|
||||
void lcdRefresh();
|
||||
|
||||
void lcdFlushed();
|
||||
extern "C" void lcdFlushed();
|
||||
|
||||
@@ -173,3 +173,5 @@ void drawTelemetryTopBar();
|
||||
void lcdDraw1bitBitmap(coord_t x, coord_t y, const unsigned char * img, uint8_t idx, LcdFlags att=0);
|
||||
|
||||
uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0);
|
||||
|
||||
void lcdFlushed();
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "lcd.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <vector>
|
||||
|
||||
#if defined(RADIO_T18)
|
||||
#define HBP 43
|
||||
@@ -60,17 +61,29 @@ static void* initialFrameBuffer = nullptr;
|
||||
|
||||
#if LCD_VERTICAL_INVERT
|
||||
typedef uint16_t pixel_t;
|
||||
static pixel_t _LCD_BUF_1[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
static pixel_t _LCD_BUF_2[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
|
||||
static pixel_t _line_buffer[LCD_W];
|
||||
static pixel_t _LCD_BUF_1[DISPLAY_BUFFER_SIZE] __SDRAM __ALIGNED(64);
|
||||
#if defined(RADIO_F16)
|
||||
// F16 can be either normal or inverted
|
||||
static pixel_t _LCD_BUF_2[DISPLAY_BUFFER_SIZE] __SDRAM __ALIGNED(64);
|
||||
#else
|
||||
// LVGL will only use one buffer when display is inverted so reuse 2nd
|
||||
// buffer here
|
||||
extern pixel_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE];
|
||||
#define _LCD_BUF_2 LCD_SECOND_FRAME_BUFFER
|
||||
#endif
|
||||
|
||||
// Frame buffer pointers
|
||||
static uint16_t* _front_buffer = _LCD_BUF_1;
|
||||
static uint16_t* _back_buffer = _LCD_BUF_2;
|
||||
|
||||
// Vector to save areas that need to be copied from front buffer to back buffer
|
||||
static std::vector<lv_area_t> dma_areas;
|
||||
|
||||
// Copy 2 pixels at once to speed up a little
|
||||
static void _copy_rotate_180(uint16_t* dst, uint16_t* src, const rect_t& copy_area)
|
||||
{
|
||||
static pixel_t _line_buffer[LCD_W];
|
||||
|
||||
coord_t x1 = LCD_W - copy_area.w - copy_area.x;
|
||||
coord_t y1 = LCD_H - copy_area.h - copy_area.y;
|
||||
|
||||
@@ -106,50 +119,44 @@ static void _copy_rotate_180(uint16_t* dst, uint16_t* src, const rect_t& copy_ar
|
||||
dst -= LCD_W;
|
||||
}
|
||||
}
|
||||
|
||||
static void _rotate_area_180(lv_area_t& area)
|
||||
{
|
||||
lv_coord_t tmp_coord;
|
||||
tmp_coord = area.y2;
|
||||
area.y2 = LCD_H - area.y1 - 1;
|
||||
area.y1 = LCD_H - tmp_coord - 1;
|
||||
tmp_coord = area.x2;
|
||||
area.x2 = LCD_W - area.x1 - 1;
|
||||
area.x1 = LCD_W - tmp_coord - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void _update_frame_buffer_addr(uint16_t* addr)
|
||||
{
|
||||
LTDC_Layer1->CFBAR = (uint32_t)addr;
|
||||
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
#if LCD_VERTICAL_INVERT
|
||||
#if defined(RADIO_F16)
|
||||
if(hardwareOptions.pcbrev > 0) {
|
||||
// Direct mode
|
||||
if (disp_drv->direct_mode) {
|
||||
// Direct mode / not inverted
|
||||
_update_frame_buffer_addr(buffer);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy areas that were updated last frame to the back buffer
|
||||
if (dma_areas.size() > 0) {
|
||||
for (auto a: dma_areas) {
|
||||
DMACopyBitmap(_back_buffer, LCD_W, LCD_H, a.x1, a.y1,
|
||||
_front_buffer, LCD_W, LCD_H, a.x1, a.y1,
|
||||
a.x2 - a.x1 + 1, a.y2 - a.y1 + 1);
|
||||
}
|
||||
dma_areas.clear();
|
||||
DMAWait();
|
||||
}
|
||||
|
||||
// Copy changes from LVGL to LCD back buffer with 180 degree rotation
|
||||
_copy_rotate_180(_back_buffer, buffer, copy_area);
|
||||
|
||||
// Check for last LVGL update before we need to swap buffers
|
||||
if (lv_disp_flush_is_last(disp_drv)) {
|
||||
|
||||
// swap back/front
|
||||
// swap back/front buffers
|
||||
if (_front_buffer == _LCD_BUF_1) {
|
||||
_front_buffer = _LCD_BUF_2;
|
||||
_back_buffer = _LCD_BUF_1;
|
||||
@@ -161,30 +168,22 @@ static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
// Trigger async refresh
|
||||
_update_frame_buffer_addr(_front_buffer);
|
||||
|
||||
// Copy refreshed & rotated areas into new back buffer
|
||||
uint16_t* src = _front_buffer;
|
||||
uint16_t* dst = _back_buffer;
|
||||
|
||||
// Save areas that need to be updated next time around
|
||||
lv_disp_t* disp = _lv_refr_get_disp_refreshing();
|
||||
for(int i = 0; i < disp->inv_p; i++) {
|
||||
if(disp->inv_area_joined[i]) continue;
|
||||
|
||||
// Rotate area 180 degrees
|
||||
lv_area_t refr_area;
|
||||
lv_area_copy(&refr_area, &disp->inv_areas[i]);
|
||||
refr_area.x1 = LCD_W - disp->inv_areas[i].x2 - 1;
|
||||
refr_area.x2 = LCD_W - disp->inv_areas[i].x1 - 1;
|
||||
refr_area.y1 = LCD_H - disp->inv_areas[i].y2 - 1;
|
||||
refr_area.y2 = LCD_H - disp->inv_areas[i].y1 - 1;
|
||||
|
||||
// TRACE("Vert invert refresh {%d,%d,%d,%d}", refr_area.x1,
|
||||
// refr_area.y1, refr_area.x2 - refr_area.x1 + 1, refr_area.y2 - refr_area.y1 + 1);
|
||||
|
||||
_rotate_area_180(refr_area);
|
||||
|
||||
auto area_w = refr_area.x2 - refr_area.x1 + 1;
|
||||
auto area_h = refr_area.y2 - refr_area.y1 + 1;
|
||||
|
||||
DMACopyBitmap(dst, LCD_W, LCD_H, refr_area.x1, refr_area.y1,
|
||||
src, LCD_W, LCD_H, refr_area.x1, refr_area.y1,
|
||||
area_w, area_h);
|
||||
dma_areas.push_back(refr_area);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
#else
|
||||
// Direct mode
|
||||
@@ -337,7 +336,6 @@ void LCD_Init_LTDC()
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, LCD_PHYS_H);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
#if 0
|
||||
DMA2D_ITConfig(DMA2D_CR_TCIE, ENABLE);
|
||||
@@ -425,8 +423,8 @@ void lcdInit()
|
||||
{
|
||||
#if LCD_VERTICAL_INVERT
|
||||
// Clear buffer first
|
||||
memset(_LCD_BUF_1, 0, sizeof(_LCD_BUF_1));
|
||||
memset(_LCD_BUF_2, 0, sizeof(_LCD_BUF_2));
|
||||
memset(_LCD_BUF_1, 0, DISPLAY_BUFFER_SIZE * sizeof(pixel_t));
|
||||
memset(_LCD_BUF_2, 0, DISPLAY_BUFFER_SIZE * sizeof(pixel_t));
|
||||
#endif
|
||||
|
||||
// Initialize the LCD
|
||||
@@ -439,11 +437,11 @@ void lcdInit()
|
||||
lcdSetFlushCb(startLcdRefresh);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
// clear interrupt flag
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
}
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
@@ -36,24 +36,17 @@
|
||||
static LTDC_HandleTypeDef hltdc;
|
||||
static void* initialFrameBuffer = nullptr;
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t* disp_drv, uint16_t* buffer,
|
||||
const rect_t& copy_area)
|
||||
{
|
||||
(void)disp_drv;
|
||||
(void)copy_area;
|
||||
|
||||
LTDC_Layer1->CFBAR &= ~(LTDC_LxCFBAR_CFBADD);
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while (_frame_addr_reloaded == 0);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
uint32_t lcdPixelClock;
|
||||
@@ -389,7 +382,6 @@ void LCD_Init_LTDC()
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, LCD_W);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
void LCD_LayerInit()
|
||||
@@ -466,5 +458,6 @@ extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
@@ -120,6 +120,8 @@ static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
set_row_addr(y1, y2);
|
||||
|
||||
memory_write(buffer, copy_area.w * copy_area.h);
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
lcdSpiInitFucPtr lcdInitFunction;
|
||||
|
||||
@@ -40,24 +40,17 @@ static void* initialFrameBuffer = nullptr;
|
||||
|
||||
#define GPIO_AF_LTDC GPIO_AF14
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
(void)disp_drv;
|
||||
(void)copy_area;
|
||||
|
||||
LTDC_Layer1->CFBAR &= ~(LTDC_LxCFBAR_CFBADD);
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
lcdSpiInitFucPtr lcdInitFunction;
|
||||
@@ -2763,7 +2756,6 @@ void LCD_Init_LTDC() {
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, lcd_phys_h);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
void LCD_LayerInit() {
|
||||
@@ -2887,6 +2879,6 @@ extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
}
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
@@ -84,7 +84,6 @@ rotenc_t rotaryEncoderGetValue()
|
||||
extern const etx_hal_adc_driver_t simu_adc_driver;
|
||||
|
||||
void lcdCopy(void * dest, void * src);
|
||||
void lcdFlushed();
|
||||
|
||||
#if defined(AUX_SERIAL) || defined(AUX2_SERIAL)
|
||||
static void hostSerialInit();
|
||||
@@ -733,7 +732,8 @@ void simuLuaReloadPermanentScripts()
|
||||
|
||||
void simuLcdFlushed()
|
||||
{
|
||||
::lcdFlushed();
|
||||
if (simu_running)
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
uint8_t simuGetMaxTrainerChannels()
|
||||
|
||||
@@ -40,8 +40,6 @@ static volatile uint16_t lcd_phys_h = LCD_PHYS_H;
|
||||
static LTDC_HandleTypeDef hltdc;
|
||||
static void* initialFrameBuffer = nullptr;
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
@@ -53,16 +51,10 @@ static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
SCB_CleanDCache();
|
||||
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
}
|
||||
|
||||
lcdSpiInitFucPtr lcdInitFunction;
|
||||
@@ -2760,7 +2752,6 @@ void LCD_Init_LTDC() {
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, lcd_phys_h);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
void LCD_LayerInit() {
|
||||
@@ -2885,5 +2876,6 @@ extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
@@ -417,8 +417,6 @@ extern "C" void backlightInit()
|
||||
LPTIMx_PWM_Init(&hlcd_lptim);
|
||||
}
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
@@ -427,18 +425,11 @@ static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
|
||||
SCB_CleanDCache();
|
||||
|
||||
LTDC_Layer1->CFBAR &= ~(LTDC_LxCFBAR_CFBADD);
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
|
||||
__HAL_LTDC_ENABLE_IT(&hlcd_ltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
}
|
||||
|
||||
extern "C" void lcdSetInitalFrameBuffer(void* fbAddress)
|
||||
@@ -460,5 +451,6 @@ extern "C" void LTDC_IRQHandler(void)
|
||||
// clear interrupt flag
|
||||
__HAL_LTDC_CLEAR_FLAG(&hlcd_ltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hlcd_ltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
@@ -312,7 +312,6 @@ void lcdSetInvert(bool invert);
|
||||
#ifdef __cplusplus
|
||||
void lcdSetContrast(bool useDefault = false);
|
||||
#endif
|
||||
void lcdFlushed();
|
||||
|
||||
// Top LCD driver
|
||||
#if defined(TOPLCD_GPIO)
|
||||
|
||||
Reference in New Issue
Block a user