Description
I am a beginner with LVGL (but not with programming) and I use a custom board with NXP LPC4088 MCU, external SDRAM (16 MB) and 480*272 TFT (16-bit color). I use MDK 5.27 with its Clang-based compiler.
Now I try to make a calibration screen for my device. The idea is:
- Draw a text “Press the touchscreen for calibration”.
- Wait for some seconds for pressing the touchscreen (I wait 3 sec now)
- If a user presses the TS, draw a calibration screen and do other actions for calibrating.
- Either after calibrating or if a user doesn’t press the TS remove that text and draw something else.
Steps 1 and 2 work good; 3 isn’t implemented yet, so after 3 sec I do the step 4, and it is not correct.
I use “custom” dynamic memory allocator (malloc etc from compiler’s RTL), it works well. My code formally written in C++14 and is placed on separate files (because it is a “carcass” for a relatively big application), but way of execution is very simple and straightforward now so I give only necessary parts (without low-level code for initializing hardware etc).
Code to reproduce
void GUI_Init()
{
// Allocate memory for two screen buffers, it works correct.
Buffer1 = malloc(LCD_Buf_Size);
Buffer2 = malloc(LCD_Buf_Size);
// Initialization of a LCD controller, works good.
LCDC::Init(CPU_Clock, Buffer1);
// Initialization of LVGL.
lv_disp_drv_t Disp_Drv;
lv_disp_t *Disp;
lv_indev_drv_t TS_Drv;
lv_indev_t *TS;
lv_init();
lv_disp_buf_init(&Disp_Buf, Buffer1, Buffer2, LCD_Buf_Size);
lv_disp_drv_init(&Disp_Drv);
Disp_Drv.buffer = &Disp_Buf;
Disp_Drv.flush_cb = Flush_Callback;
Disp = lv_disp_drv_register(&Disp_Drv);
// Touchscreen can work "technically" (all low-level code works good) but doesn't used really.
lv_indev_drv_init(&TS_Drv);
TS_Drv.type = LV_INDEV_TYPE_POINTER;
TS_Drv.read_cb = TS_Read_Callback;
TS = lv_indev_drv_register(&TS_Drv);
}
void Calibrate_Touchscreen()
{
// Creating a label, works good.
lv_obj_t *Label = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text(Label, "Press the touchscreen for calibration");
lv_obj_set_pos(Label, 0, 0);
lv_obj_align(Label, nullptr, LV_ALIGN_CENTER, 0, 0);
uint32 Start_MS = Get_Current_MS_Counter();
do
{
GUI_Task_Handler();
if ( TS->Is_Pressed() )
{
// Not implemented yet.
break;
}
} while ( Get_Current_MS_Counter() - Start_MS < 3000 );
// Code before this line works good; I see a text label on a white screen (the image is in the screen buffer #1).
// After this a screen is BAD, see Screenshot. The image is in the screen buffer #2.
lv_obj_del(Label);
GUI_Task_Handler();
}
extern "C" int main()
{
// Low-level hardware initialization, works good.
HW_Init();
GUI_Init();
// If I comment this line, the next button will be drawn correctly.
Calibrate_Touchscreen();
lv_obj_t *btn = lv_btn_create(lv_scr_act(), NULL);
lv_obj_set_pos(btn, 10, 10);
lv_obj_set_size(btn, 100, 50);
lv_obj_set_event_cb(btn, btn_event_cb);
lv_obj_t *label = lv_label_create(btn, NULL);
lv_label_set_text(label, "Button");
// After ~30 executions of this loop LVGL changes screen buffers again but the new one is bad too
// (it is in the screen buffer #1 so it mostly is white with that old text label at center, only top lines are
// redrawn and, it seems, contain a "defective" button
while (true)
{
// Testing code for touchscreen, works good.
if ( TS->Is_Pressed() )
{
char S[16];
Point R = TS->Get_Raw_Coords();
sprintf(S, "X = %u", R.X);
Console_Write(S);
sprintf(S, " Y = %u\n\r", R.Y);
Console_Write(S);
}
// Calls lv_task_handler(), no other actions just now.
GUI_Task_Handler();
Wait_For_Interrupt();
}
return 0;
}
Screenshots
Unfortunately, this forum doesn’t allow to use more than one image for new users. It is bad idea…