diff --git a/app/tasks/lvgl_task.cpp b/app/tasks/lvgl_task.cpp index 921e4c8..c7c5e39 100644 --- a/app/tasks/lvgl_task.cpp +++ b/app/tasks/lvgl_task.cpp @@ -3,12 +3,17 @@ #include "lv_port_disp.h" #include "lv_port_indev.h" #include "monitor_task.h" +#include "work_task.h" +#include "led_driver.h" +#include "touch.h" #include "lcd.h" #include #define LVGL_TASK_PRIORITY (RT_THREAD_PRIORITY_MAX - 2) #define LVGL_TASK_STACK_SIZE 8192 +extern Led led0, led1, led2, led3; + rt_thread_t lvgl_thread = RT_NULL; static const lv_color_t COLOR_BG = lv_color_hex(0x0D1117); @@ -20,6 +25,8 @@ static const lv_color_t COLOR_YELLOW = lv_color_hex(0xD29922); static const lv_color_t COLOR_RED = lv_color_hex(0xF85149); static const lv_color_t COLOR_TEXT = lv_color_hex(0xF0F6FC); static const lv_color_t COLOR_TEXT_DIM = lv_color_hex(0x8B949E); +static const lv_color_t COLOR_BUTTON = lv_color_hex(0x21262D); +static const lv_color_t COLOR_BTN_ACTIVE = lv_color_hex(0x2EA043); static lv_obj_t *uptime_label; static lv_obj_t *cpu_speed_label; @@ -31,11 +38,18 @@ static lv_obj_t *job_id_label; static lv_obj_t *work_bar; static lv_obj_t *work_status_label; static lv_obj_t *work_desc_label; -static lv_obj_t *led_indicators[4]; +static lv_obj_t *led_dots[4]; static lv_obj_t *touch_status_label; static lv_obj_t *frame_counter_label; +static lv_obj_t *touch_coord_label; + +static lv_obj_t *led_buttons[4]; +static lv_obj_t *led_btn_labels[4]; +static lv_obj_t *start_job_btn; +static lv_obj_t *start_job_label; static uint32_t frame_count = 0; +static uint8_t led_states[4] = {0, 0, 0, 0}; static lv_obj_t *create_card(lv_obj_t *parent, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h) { @@ -61,6 +75,81 @@ static void create_card_title(lv_obj_t *card, const char *text) lv_obj_align(title, LV_ALIGN_TOP_LEFT, 0, 0); } +static void led_btn_cb(lv_event_t *e) +{ + uint32_t idx = (uint32_t)(uintptr_t)lv_event_get_user_data(e); + if (idx >= 4) return; + + Led *leds[] = {&led0, &led1, &led2, &led3}; + leds[idx]->toggle(); + led_states[idx] = !led_states[idx]; + + if (led_states[idx]) + { + lv_obj_set_style_bg_color(led_buttons[idx], COLOR_GREEN, 0); + lv_obj_set_style_border_color(led_buttons[idx], lv_color_hex(0x2EA043), 0); + lv_label_set_text(led_btn_labels[idx], "ON"); + lv_obj_set_style_text_color(led_btn_labels[idx], COLOR_GREEN, 0); + } + else + { + lv_obj_set_style_bg_color(led_buttons[idx], COLOR_BUTTON, 0); + lv_obj_set_style_border_color(led_buttons[idx], lv_color_hex(0x30363D), 0); + lv_label_set_text(led_btn_labels[idx], "OFF"); + lv_obj_set_style_text_color(led_btn_labels[idx], COLOR_TEXT_DIM, 0); + } +} + +static void start_job_cb(lv_event_t *e) +{ + (void)e; + static uint32_t job_counter = 0; + job_counter++; + work_task_send(job_counter); + printf("[UI] START JOB #%lu dispatched\r\n", (unsigned long)job_counter); + + lv_obj_set_style_bg_color(start_job_btn, COLOR_GREEN, 0); + lv_obj_set_style_border_color(start_job_btn, lv_color_hex(0x2EA043), 0); + lv_label_set_text(start_job_label, "RUNNING"); + lv_obj_set_style_text_color(start_job_label, COLOR_GREEN, 0); + + lv_label_set_text(work_desc_label, "Job started..."); +} + +static lv_obj_t *create_led_btn(lv_obj_t *parent, lv_coord_t x, lv_coord_t y, + lv_coord_t w, lv_coord_t h, const char *text, + lv_event_cb_t cb, uint32_t idx) +{ + lv_obj_t *btn = lv_btn_create(parent); + lv_obj_set_size(btn, w, h); + lv_obj_set_pos(btn, x, y); + lv_obj_set_style_bg_color(btn, COLOR_BUTTON, 0); + lv_obj_set_style_bg_grad_color(btn, COLOR_BUTTON, 0); + lv_obj_set_style_border_width(btn, 1, 0); + lv_obj_set_style_border_color(btn, lv_color_hex(0x30363D), 0); + lv_obj_set_style_radius(btn, 6, 0); + lv_obj_set_style_shadow_width(btn, 0, 0); + lv_obj_set_style_pad_all(btn, 0, 0); + lv_obj_set_style_transform_width(btn, 0, LV_STATE_PRESSED); + lv_obj_set_style_transform_height(btn, 0, LV_STATE_PRESSED); + + lv_obj_t *name = lv_label_create(btn); + lv_label_set_text(name, text); + lv_obj_set_style_text_color(name, COLOR_TEXT, 0); + lv_obj_set_style_text_font(name, &lv_font_montserrat_12, 0); + lv_obj_align(name, LV_ALIGN_TOP_MID, 0, 4); + + lv_obj_t *state = lv_label_create(btn); + lv_label_set_text(state, "OFF"); + lv_obj_set_style_text_color(state, COLOR_TEXT_DIM, 0); + lv_obj_set_style_text_font(state, &lv_font_montserrat_14, 0); + lv_obj_align(state, LV_ALIGN_BOTTOM_MID, 0, -4); + + lv_obj_add_event_cb(btn, cb, LV_EVENT_SHORT_CLICKED, (void *)(uintptr_t)idx); + + return btn; +} + static void create_system_monitor_ui(void) { lv_obj_t *scr = lv_scr_act(); @@ -72,7 +161,7 @@ static void create_system_monitor_ui(void) lv_obj_set_style_bg_color(header, COLOR_HEADER_BG, 0); lv_obj_set_style_bg_opa(header, LV_OPA_COVER, 0); lv_obj_set_style_radius(header, 0, 0); - lv_obj_set_size(header, 480, 56); + lv_obj_set_size(header, 480, 52); lv_obj_set_pos(header, 0, 0); lv_obj_t *title = lv_label_create(header); @@ -85,9 +174,9 @@ static void create_system_monitor_ui(void) lv_label_set_text(uptime_label, "Uptime: 00h 00m 00s"); lv_obj_set_style_text_color(uptime_label, COLOR_TEXT_DIM, 0); lv_obj_set_style_text_font(uptime_label, &lv_font_montserrat_12, 0); - lv_obj_align(uptime_label, LV_ALIGN_CENTER, 0, 16); + lv_obj_align(uptime_label, LV_ALIGN_CENTER, 0, 14); - lv_obj_t *cpu_card = create_card(scr, 10, 68, 222, 80); + lv_obj_t *cpu_card = create_card(scr, 10, 64, 222, 76); create_card_title(cpu_card, "CPU"); cpu_speed_label = lv_label_create(cpu_card); lv_label_set_text(cpu_speed_label, "168 MHz"); @@ -99,9 +188,9 @@ static void create_system_monitor_ui(void) lv_label_set_text(tick_label, "Ticks: 0"); lv_obj_set_style_text_color(tick_label, COLOR_TEXT_DIM, 0); lv_obj_set_style_text_font(tick_label, &lv_font_montserrat_12, 0); - lv_obj_align(tick_label, LV_ALIGN_BOTTOM_LEFT, 0, -6); + lv_obj_align(tick_label, LV_ALIGN_BOTTOM_LEFT, 0, -4); - lv_obj_t *mem_card = create_card(scr, 242, 68, 228, 80); + lv_obj_t *mem_card = create_card(scr, 242, 64, 228, 76); create_card_title(mem_card, "MEMORY"); mem_info_label = lv_label_create(mem_card); lv_label_set_text(mem_info_label, "Free: -- KB"); @@ -111,7 +200,7 @@ static void create_system_monitor_ui(void) mem_bar = lv_bar_create(mem_card); lv_obj_set_size(mem_bar, 208, 8); - lv_obj_align(mem_bar, LV_ALIGN_BOTTOM_LEFT, 0, -10); + lv_obj_align(mem_bar, LV_ALIGN_BOTTOM_LEFT, 0, -8); lv_obj_set_style_bg_color(mem_bar, lv_color_hex(0x21262D), LV_PART_MAIN); lv_obj_set_style_bg_color(mem_bar, COLOR_GREEN, LV_PART_INDICATOR); lv_obj_set_style_radius(mem_bar, 4, LV_PART_MAIN); @@ -125,18 +214,18 @@ static void create_system_monitor_ui(void) lv_obj_set_style_text_font(mem_pct_label, &lv_font_montserrat_12, 0); lv_obj_align(mem_pct_label, LV_ALIGN_RIGHT_MID, -4, 0); - lv_obj_t *work_card = create_card(scr, 10, 160, 460, 115); + lv_obj_t *work_card = create_card(scr, 10, 152, 460, 90); create_card_title(work_card, "WORK TASK"); job_id_label = lv_label_create(work_card); lv_label_set_text(job_id_label, "Idle"); lv_obj_set_style_text_color(job_id_label, COLOR_TEXT_DIM, 0); lv_obj_set_style_text_font(job_id_label, &lv_font_montserrat_14, 0); - lv_obj_align(job_id_label, LV_ALIGN_TOP_LEFT, 0, 20); + lv_obj_align(job_id_label, LV_ALIGN_TOP_LEFT, 0, 18); work_bar = lv_bar_create(work_card); lv_obj_set_size(work_bar, 440, 14); - lv_obj_align(work_bar, LV_ALIGN_LEFT_MID, 0, 10); + lv_obj_align(work_bar, LV_ALIGN_LEFT_MID, 0, 6); lv_obj_set_style_bg_color(work_bar, lv_color_hex(0x21262D), LV_PART_MAIN); lv_obj_set_style_bg_color(work_bar, COLOR_ACCENT, LV_PART_INDICATOR); lv_obj_set_style_radius(work_bar, 7, LV_PART_MAIN); @@ -145,53 +234,128 @@ static void create_system_monitor_ui(void) lv_bar_set_value(work_bar, 0, LV_ANIM_OFF); work_status_label = lv_label_create(work_card); - lv_label_set_text(work_status_label, "0%"); + lv_label_set_text(work_status_label, "Idle"); lv_obj_set_style_text_color(work_status_label, COLOR_TEXT, 0); lv_obj_set_style_text_font(work_status_label, &lv_font_montserrat_14, 0); - lv_obj_align(work_status_label, LV_ALIGN_RIGHT_MID, 0, 10); + lv_obj_align(work_status_label, LV_ALIGN_RIGHT_MID, 0, 6); work_desc_label = lv_label_create(work_card); - lv_label_set_text(work_desc_label, "Waiting for jobs..."); + lv_label_set_text(work_desc_label, "Tap START JOB below"); lv_obj_set_style_text_color(work_desc_label, COLOR_TEXT_DIM, 0); lv_obj_set_style_text_font(work_desc_label, &lv_font_montserrat_12, 0); - lv_obj_align(work_desc_label, LV_ALIGN_BOTTOM_LEFT, 0, -6); + lv_obj_align(work_desc_label, LV_ALIGN_BOTTOM_LEFT, 0, -4); - lv_obj_t *peri_card = create_card(scr, 10, 287, 460, 90); - create_card_title(peri_card, "PERIPHERALS"); + lv_obj_t *ctrl_card = create_card(scr, 10, 254, 460, 260); + create_card_title(ctrl_card, "CONTROL"); - const char *led_labels[] = {"LED0", "LED1", "LED2", "LED3"}; - const lv_color_t led_colors[] = { - lv_color_hex(0xFF4444), - lv_color_hex(0x44FF44), - lv_color_hex(0x4444FF), - lv_color_hex(0xFFFF44)}; + lv_obj_t *led_hint = lv_label_create(ctrl_card); + lv_label_set_text(led_hint, "LED Indicators"); + lv_obj_set_style_text_color(led_hint, COLOR_TEXT_DIM, 0); + lv_obj_set_style_text_font(led_hint, &lv_font_montserrat_12, 0); + lv_obj_align(led_hint, LV_ALIGN_TOP_LEFT, 0, 16); + + int dot_x = 0; + for (int i = 0; i < 4; i++) + { + led_dots[i] = lv_obj_create(ctrl_card); + lv_obj_remove_style_all(led_dots[i]); + lv_obj_set_size(led_dots[i], 10, 10); + lv_obj_set_pos(led_dots[i], dot_x, 36); + lv_obj_set_style_bg_color(led_dots[i], lv_color_hex(0x21262D), 0); + lv_obj_set_style_bg_opa(led_dots[i], LV_OPA_COVER, 0); + lv_obj_set_style_radius(led_dots[i], 5, 0); + + lv_obj_t *ln = lv_label_create(ctrl_card); + lv_label_set_text(ln, "OFF"); + lv_obj_set_style_text_color(ln, COLOR_TEXT_DIM, 0); + lv_obj_set_style_text_font(ln, &lv_font_montserrat_12, 0); + lv_obj_set_pos(ln, dot_x + 14, 34); + + dot_x += 110; + } + + lv_obj_t *btn_hint = lv_label_create(ctrl_card); + lv_label_set_text(btn_hint, "Toggle Switches"); + lv_obj_set_style_text_color(btn_hint, COLOR_TEXT_DIM, 0); + lv_obj_set_style_text_font(btn_hint, &lv_font_montserrat_12, 0); + lv_obj_align(btn_hint, LV_ALIGN_TOP_LEFT, 0, 56); + + const char *led_names[] = {"LED0", "LED1", "LED2", "LED3"}; + int led_w = 100; + int led_gap = 12; + int btn_start_x = (460 - (4 * led_w + 3 * led_gap)) / 2; for (int i = 0; i < 4; i++) { - led_indicators[i] = lv_led_create(peri_card); - lv_obj_set_size(led_indicators[i], 20, 20); - lv_led_set_color(led_indicators[i], led_colors[i]); - lv_led_off(led_indicators[i]); - lv_obj_set_pos(led_indicators[i], 10 + i * 65, 24); - - lv_obj_t *led_lbl = lv_label_create(peri_card); - lv_label_set_text(led_lbl, led_labels[i]); - lv_obj_set_style_text_color(led_lbl, COLOR_TEXT_DIM, 0); - lv_obj_set_style_text_font(led_lbl, &lv_font_montserrat_12, 0); - lv_obj_align_to(led_lbl, led_indicators[i], LV_ALIGN_OUT_BOTTOM_MID, 0, 4); + int bx = btn_start_x + i * (led_w + led_gap); + led_buttons[i] = create_led_btn(ctrl_card, bx, 74, led_w, 40, led_names[i], led_btn_cb, i); + led_btn_labels[i] = lv_obj_get_child(led_buttons[i], 1); } - touch_status_label = lv_label_create(peri_card); - lv_label_set_text(touch_status_label, "Touch: Connected"); + lv_obj_t *sep = lv_obj_create(ctrl_card); + lv_obj_remove_style_all(sep); + lv_obj_set_size(sep, 440, 1); + lv_obj_set_style_bg_color(sep, lv_color_hex(0x30363D), 0); + lv_obj_set_style_bg_opa(sep, LV_OPA_COVER, 0); + lv_obj_align(sep, LV_ALIGN_BOTTOM_LEFT, 0, -86); + + lv_obj_t *task_hint = lv_label_create(ctrl_card); + lv_label_set_text(task_hint, "Task"); + lv_obj_set_style_text_color(task_hint, COLOR_TEXT_DIM, 0); + lv_obj_set_style_text_font(task_hint, &lv_font_montserrat_12, 0); + lv_obj_align(task_hint, LV_ALIGN_BOTTOM_LEFT, 0, -70); + + start_job_btn = lv_btn_create(ctrl_card); + lv_obj_set_size(start_job_btn, 130, 44); + lv_obj_align(start_job_btn, LV_ALIGN_BOTTOM_LEFT, 0, -16); + lv_obj_set_style_bg_color(start_job_btn, COLOR_BUTTON, 0); + lv_obj_set_style_border_width(start_job_btn, 1, 0); + lv_obj_set_style_border_color(start_job_btn, lv_color_hex(0x30363D), 0); + lv_obj_set_style_radius(start_job_btn, 6, 0); + lv_obj_set_style_shadow_width(start_job_btn, 0, 0); + lv_obj_set_style_transform_width(start_job_btn, 0, LV_STATE_PRESSED); + lv_obj_set_style_transform_height(start_job_btn, 0, LV_STATE_PRESSED); + + start_job_label = lv_label_create(start_job_btn); + lv_label_set_text(start_job_label, "START JOB"); + lv_obj_set_style_text_color(start_job_label, COLOR_TEXT, 0); + lv_obj_set_style_text_font(start_job_label, &lv_font_montserrat_14, 0); + lv_obj_align(start_job_label, LV_ALIGN_CENTER, 0, 0); + + lv_obj_add_event_cb(start_job_btn, start_job_cb, LV_EVENT_SHORT_CLICKED, NULL); + + lv_obj_t *task_info = lv_label_create(ctrl_card); + lv_label_set_text(task_info, "Sends async work job"); + lv_obj_set_style_text_color(task_info, COLOR_TEXT_DIM, 0); + lv_obj_set_style_text_font(task_info, &lv_font_montserrat_12, 0); + lv_obj_align(task_info, LV_ALIGN_BOTTOM_LEFT, 140, -16); + + lv_obj_t *touch_card = create_card(scr, 10, 526, 460, 50); + create_card_title(touch_card, "TOUCH"); + + touch_status_label = lv_label_create(touch_card); + lv_label_set_text(touch_status_label, "Touch: OK"); lv_obj_set_style_text_color(touch_status_label, COLOR_GREEN, 0); lv_obj_set_style_text_font(touch_status_label, &lv_font_montserrat_12, 0); - lv_obj_align(touch_status_label, LV_ALIGN_RIGHT_MID, -10, 0); + lv_obj_align(touch_status_label, LV_ALIGN_LEFT_MID, 0, 6); + + touch_coord_label = lv_label_create(touch_card); + lv_label_set_text(touch_coord_label, "(0, 0)"); + lv_obj_set_style_text_color(touch_coord_label, COLOR_TEXT_DIM, 0); + lv_obj_set_style_text_font(touch_coord_label, &lv_font_montserrat_12, 0); + lv_obj_align(touch_coord_label, LV_ALIGN_RIGHT_MID, -10, 6); + + lv_obj_t *ver_label = lv_label_create(touch_card); + lv_label_set_text(ver_label, "LVGL v8.3"); + lv_obj_set_style_text_color(ver_label, COLOR_TEXT_DIM, 0); + lv_obj_set_style_text_font(ver_label, &lv_font_montserrat_12, 0); + lv_obj_align(ver_label, LV_ALIGN_CENTER, 0, 6); frame_counter_label = lv_label_create(scr); - lv_label_set_text(frame_counter_label, "LVGL v8.3 | Frames: 0 | Monitor: OK"); + lv_label_set_text(frame_counter_label, "Frames: 0"); lv_obj_set_style_text_color(frame_counter_label, COLOR_TEXT_DIM, 0); lv_obj_set_style_text_font(frame_counter_label, &lv_font_montserrat_12, 0); - lv_obj_align(frame_counter_label, LV_ALIGN_BOTTOM_MID, 0, -8); + lv_obj_align(frame_counter_label, LV_ALIGN_BOTTOM_MID, 0, -6); } static void update_ui(void) @@ -201,24 +365,37 @@ static void update_ui(void) uint32_t m = (sec % 3600) / 60; uint32_t s = sec % 60; - char buf[48]; + char buf[64]; snprintf(buf, sizeof(buf), "Uptime: %02luh %02lum %02lus", (unsigned long)h, (unsigned long)m, (unsigned long)s); lv_label_set_text(uptime_label, buf); uint32_t free_kb = g_free_heap_size / 1024; - snprintf(buf, sizeof(buf), "Free: %lu KB", (unsigned long)free_kb); + rt_size_t total_rt = 0; + rt_memory_info(NULL, &total_rt, NULL); + uint32_t total_kb = total_rt / 1024; + + snprintf(buf, sizeof(buf), "Free: %lu / %lu KB", (unsigned long)free_kb, (unsigned long)total_kb); lv_label_set_text(mem_info_label, buf); - uint32_t total_kb = 1024; - uint32_t used_kb = (g_free_heap_size < total_kb * 1024) ? (total_kb - g_free_heap_size / 1024) : 0; - uint8_t pct = (uint8_t)((used_kb * 100) / total_kb); - if (pct > 100) - pct = 100; + uint8_t pct = 0; + if (total_kb > 0) + { + uint32_t used_kb = total_kb - (g_free_heap_size / 1024); + pct = (uint8_t)((used_kb * 100) / total_kb); + if (pct > 100) pct = 100; + } lv_bar_set_value(mem_bar, pct, LV_ANIM_OFF); snprintf(buf, sizeof(buf), "%u%%", (unsigned int)pct); lv_label_set_text(mem_pct_label, buf); + if (pct > 80) + lv_obj_set_style_bg_color(mem_bar, COLOR_RED, LV_PART_INDICATOR); + else if (pct > 60) + lv_obj_set_style_bg_color(mem_bar, COLOR_YELLOW, LV_PART_INDICATOR); + else + lv_obj_set_style_bg_color(mem_bar, COLOR_GREEN, LV_PART_INDICATOR); + snprintf(buf, sizeof(buf), "Ticks: %lu", (unsigned long)rt_tick_get()); lv_label_set_text(tick_label, buf); @@ -228,29 +405,59 @@ static void update_ui(void) snprintf(buf, sizeof(buf), "%d%%", g_work_progress); lv_label_set_text(work_status_label, buf); lv_obj_set_style_bg_color(work_bar, COLOR_ACCENT, LV_PART_INDICATOR); + lv_label_set_text(work_desc_label, "Processing..."); + lv_label_set_text(job_id_label, "Job active"); } else { lv_bar_set_value(work_bar, 0, LV_ANIM_OFF); lv_label_set_text(work_status_label, "Idle"); lv_obj_set_style_bg_color(work_bar, COLOR_TEXT_DIM, LV_PART_INDICATOR); + lv_label_set_text(job_id_label, "Idle"); + lv_label_set_text(work_desc_label, "Tap START JOB below"); } - static uint32_t last_toggle = 0; - uint32_t now = rt_tick_get() / (RT_TICK_PER_SECOND / 4); - if (now != last_toggle) + for (int i = 0; i < 4; i++) { - last_toggle = now; - for (int i = 0; i < 4; i++) + if (led_states[i]) { - if (now % 2) - lv_led_on(led_indicators[i]); - else - lv_led_off(led_indicators[i]); + lv_color_t cols[] = { + lv_color_hex(0xFF4444), + lv_color_hex(0x44FF44), + lv_color_hex(0x4444FF), + lv_color_hex(0xFFFF44) + }; + lv_obj_set_style_bg_color(led_dots[i], cols[i], 0); + } + else + { + lv_obj_set_style_bg_color(led_dots[i], lv_color_hex(0x21262D), 0); } } - snprintf(buf, sizeof(buf), "LVGL v8.3 | Frames: %lu | Monitor: OK", (unsigned long)frame_count); + GT1151 &touch = GT1151::instance(); + if (touch.isActive(0)) + { + snprintf(buf, sizeof(buf), "(%d, %d)", touch.x(0), touch.y(0)); + lv_label_set_text(touch_coord_label, buf); + lv_label_set_text(touch_status_label, "Touch: Touched"); + lv_obj_set_style_text_color(touch_status_label, COLOR_ACCENT, 0); + } + else + { + lv_label_set_text(touch_status_label, "Touch: OK"); + lv_obj_set_style_text_color(touch_status_label, COLOR_GREEN, 0); + } + + if (g_work_progress < 0) + { + lv_obj_set_style_bg_color(start_job_btn, COLOR_BUTTON, 0); + lv_obj_set_style_border_color(start_job_btn, lv_color_hex(0x30363D), 0); + lv_label_set_text(start_job_label, "START JOB"); + lv_obj_set_style_text_color(start_job_label, COLOR_TEXT, 0); + } + + snprintf(buf, sizeof(buf), "Frames: %lu", (unsigned long)frame_count); lv_label_set_text(frame_counter_label, buf); } @@ -300,6 +507,7 @@ static void lvgl_work(void *parameter) while (1) { lv_timer_handler(); + lv_port_indev_feed(); frame_count++; update_counter++; diff --git a/bsp/device/touch/touch.cpp b/bsp/device/touch/touch.cpp index b762b42..36fa859 100644 --- a/bsp/device/touch/touch.cpp +++ b/bsp/device/touch/touch.cpp @@ -212,7 +212,7 @@ uint8_t GT1151::scan(uint8_t mode) uint8_t tempsta; static uint8_t t = 0; t++; - if ((t % 10) == 0 || t < 10) + if ((t % 2) == 0 || t < 2) { readReg(GT_GSTID_REG, &mode, 1); if (mode & 0X80 && ((mode & 0XF) < 6)) @@ -272,7 +272,7 @@ uint8_t GT1151::scan(uint8_t mode) } } if (t > 240) - t = 10; + t = 2; return res; } diff --git a/bsp/device/touch/touch.h b/bsp/device/touch/touch.h index 10df67a..9e6e05c 100644 --- a/bsp/device/touch/touch.h +++ b/bsp/device/touch/touch.h @@ -23,6 +23,8 @@ public: static volatile uint8_t irq_flag; + void readRegister(uint16_t reg, uint8_t *buf, uint8_t len) { readReg(reg, buf, len); } + private: GT1151(); ~GT1151() = default; diff --git a/drv/lvgl/lv_port_indev.cpp b/drv/lvgl/lv_port_indev.cpp index 496949a..5b2d369 100644 --- a/drv/lvgl/lv_port_indev.cpp +++ b/drv/lvgl/lv_port_indev.cpp @@ -1,6 +1,7 @@ #include "lv_port_indev.h" #include "lvgl.h" #include "touch.h" +#include static lv_indev_drv_t indev_drv; static lv_indev_t *indev_dev; @@ -10,24 +11,46 @@ static void touch_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) (void)drv; static int16_t last_x = 0; static int16_t last_y = 0; + static uint32_t stale_cnt = 0; GT1151 &touch = GT1151::instance(); touch.scan(0); - if (touch.isActive(0)) + bool active = touch.isActive(0); + + if (active) { - data->point.x = touch.x(0); - data->point.y = touch.y(0); - data->state = LV_INDEV_STATE_PRESSED; - last_x = data->point.x; - last_y = data->point.y; + int16_t rx = (int16_t)touch.x(0); + int16_t ry = (int16_t)touch.y(0); + + if (rx != last_x || ry != last_y) + { + stale_cnt = 0; + } + else + { + stale_cnt++; + } + + if (stale_cnt > 10) + { + active = false; + stale_cnt = 0; + } + else + { + last_x = rx; + last_y = ry; + } } else { - data->point.x = last_x; - data->point.y = last_y; - data->state = LV_INDEV_STATE_RELEASED; + stale_cnt = 0; } + + data->point.x = last_x; + data->point.y = last_y; + data->state = active ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; } RetCode lv_port_indev_init(void) @@ -37,6 +60,24 @@ RetCode lv_port_indev_init(void) indev_drv.read_cb = touch_read_cb; indev_dev = lv_indev_drv_register(&indev_drv); + if (indev_dev == NULL) + { + printf("[TOUCH] indev register FAILED!\r\n"); + return RET_ERROR; + } + printf("[TOUCH] indev registered OK\r\n"); + printf("[TOUCH] indev disp=%p, read_timer=%p\r\n", + (void *)indev_dev->driver->disp, + (void *)indev_dev->driver->read_timer); return RET_OK; } + +void lv_port_indev_feed(void) +{ + if (indev_dev == NULL) return; + + lv_timer_t fake_timer; + fake_timer.user_data = indev_dev; + lv_indev_read_timer_cb(&fake_timer); +} diff --git a/drv/lvgl/lv_port_indev.h b/drv/lvgl/lv_port_indev.h index 9ba1e00..ac236c1 100644 --- a/drv/lvgl/lv_port_indev.h +++ b/drv/lvgl/lv_port_indev.h @@ -4,5 +4,6 @@ #include "common_types.h" RetCode lv_port_indev_init(void); +void lv_port_indev_feed(void); #endif