From fb7fe32bf4604dc6e31235d0c01e1f149981bb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ko=C5=82ucki?= Date: Tue, 26 May 2026 19:58:49 +0200 Subject: [PATCH 1/2] Add keypad support --- include/lv_ctr_indev.h | 2 ++ source/lv_ctr_indev.c | 74 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/include/lv_ctr_indev.h b/include/lv_ctr_indev.h index d997b3c..ef6ae59 100644 --- a/include/lv_ctr_indev.h +++ b/include/lv_ctr_indev.h @@ -34,6 +34,8 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ void lv_ctr_indev_init(void); +lv_indev_t * lv_ctr_indev_get_touchpad(void); +lv_indev_t * lv_ctr_indev_get_keypad(void); /********************** * MACROS diff --git a/source/lv_ctr_indev.c b/source/lv_ctr_indev.c index 9f3791b..fef8d94 100644 --- a/source/lv_ctr_indev.c +++ b/source/lv_ctr_indev.c @@ -24,11 +24,13 @@ **********************/ static void touchpad_read(lv_indev_t * indev, lv_indev_data_t * data); +static void keypad_read(lv_indev_t * indev, lv_indev_data_t * data); /********************** * STATIC VARIABLES **********************/ lv_indev_t * indev_touchpad; +lv_indev_t * indev_keypad; /********************** * MACROS @@ -45,12 +47,27 @@ void lv_ctr_indev_init(void) lv_indev_set_type(indev_touchpad, LV_INDEV_TYPE_POINTER); lv_indev_set_read_cb(indev_touchpad, touchpad_read); + /*Register a keypad input device*/ + indev_keypad = lv_indev_create(); + lv_indev_set_type(indev_keypad, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_read_cb(indev_keypad, keypad_read); + /*Later you should create group(s) with `lv_group_t * group = lv_group_create()`, *add objects to the group with `lv_group_add_obj(group, obj)` *and assign this input device to group to navigate in it: *`lv_indev_set_group(indev_keypad, group);`*/ } +lv_indev_t * lv_ctr_indev_get_touchpad(void) +{ + return indev_touchpad; +} + +lv_indev_t * lv_ctr_indev_get_keypad(void) +{ + return indev_keypad; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -64,8 +81,6 @@ static void touchpad_read(lv_indev_t * indev_drv, lv_indev_data_t * data) static int32_t last_x = 0; static int32_t last_y = 0; touchPosition touch; - - hidScanInput(); /*Save the pressed coordinates and the state*/ if(hidKeysHeld() & KEY_TOUCH) { @@ -83,6 +98,61 @@ static void touchpad_read(lv_indev_t * indev_drv, lv_indev_data_t * data) data->point.y = last_y; } +/*------------------ + * Keypad + * -----------------*/ + +/* What do you mean you can't handle more than one button at the same time!? */ +static void keypad_read(lv_indev_t * indev_drv, lv_indev_data_t * data) +{ + static uint32_t last_key = 0; + bool key_pressed = false; + + u32 kDown = hidKeysDown(); + u32 kHeld = hidKeysHeld(); + u32 kUp = hidKeysUp(); + + if (kHeld & KEY_UP) { + last_key = LV_KEY_UP; + key_pressed = true; + } + else if (kHeld & KEY_DOWN) { + last_key = LV_KEY_DOWN; + key_pressed = true; + } + else if (kHeld & KEY_LEFT) { + last_key = LV_KEY_LEFT; + key_pressed = true; + } + else if (kHeld & KEY_RIGHT) { + last_key = LV_KEY_RIGHT; + key_pressed = true; + } + else if (kHeld & KEY_A) { + last_key = LV_KEY_ENTER; + key_pressed = true; + } + else if (kHeld & KEY_B) { + last_key = LV_KEY_ESC; + key_pressed = true; + } + else if (kHeld & KEY_L) { + last_key = LV_KEY_PREV; + key_pressed = true; + } + else if (kHeld & KEY_R) { + last_key = LV_KEY_NEXT; + key_pressed = true; + } + + data->key = last_key; + + if (key_pressed) + data->state = LV_INDEV_STATE_PRESSED; + else + data->state = LV_INDEV_STATE_RELEASED; +} + #else /*Enable this file at the top*/ /*This dummy typedef exists purely to silence -Wpedantic.*/ From f0448257915bba9a46a6a62d250ba94f7f434fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ko=C5=82ucki?= Date: Tue, 26 May 2026 19:59:00 +0200 Subject: [PATCH 2/2] More debug UI --- source/main.c | 93 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 20 deletions(-) diff --git a/source/main.c b/source/main.c index fe572b7..ac4a2b1 100644 --- a/source/main.c +++ b/source/main.c @@ -11,6 +11,7 @@ static lv_obj_t * cursor; static lv_obj_t * label; static lv_obj_t * label2; static lv_obj_t * fps_label; +static lv_obj_t * keypad_label; long unsigned int sys_tick(void) @@ -30,30 +31,71 @@ void sys_free(void) gfxExit(); } -static void cursor_timer_cb(lv_timer_t * t) +static void ui_timer_cb(lv_timer_t * t) { LV_UNUSED(t); - + lv_indev_t * indev = lv_indev_get_next(NULL); + + while (indev) { + if (lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER) { + lv_point_t p; + lv_indev_get_point(indev, &p); - if (!indev) - return; + if (lv_indev_get_state(indev) == LV_INDEV_STATE_PRESSED) { + lv_obj_set_pos(cursor, p.x - 5, p.y - 5); + lv_obj_clear_flag(cursor, LV_OBJ_FLAG_HIDDEN); - lv_point_t p; - lv_indev_get_point(indev, &p); + lv_label_set_text_fmt(label2, + "x: %d\ny: %d", + p.x, + p.y); + } + else { + lv_obj_add_flag(cursor, LV_OBJ_FLAG_HIDDEN); + } + } + if (lv_indev_get_type(indev) == LV_INDEV_TYPE_KEYPAD) { + uint32_t key = lv_indev_get_key(indev); + uint32_t state = lv_indev_get_state(indev); + const char * txt = "None"; - if (lv_indev_get_state(indev) == LV_INDEV_STATE_PRESSED) { + switch(key) { + case LV_KEY_UP: + txt = "UP"; + break; + case LV_KEY_DOWN: + txt = "DOWN"; + break; + case LV_KEY_LEFT: + txt = "LEFT"; + break; + case LV_KEY_RIGHT: + txt = "RIGHT"; + break; + case LV_KEY_ENTER: + txt = "A"; + break; + case LV_KEY_ESC: + txt = "B"; + break; + case LV_KEY_PREV: + txt = "L"; + break; + case LV_KEY_NEXT: + txt = "R"; + break; + default: + txt = "None"; + break; + } - lv_obj_set_pos(cursor, p.x - 5, p.y - 5); - lv_obj_clear_flag(cursor, LV_OBJ_FLAG_HIDDEN); - - lv_label_set_text_fmt(label2, - "x: %d\ny: %d", - p.x, - p.y); - } - else { - lv_obj_add_flag(cursor, LV_OBJ_FLAG_HIDDEN); + if (state == LV_INDEV_STATE_PRESSED) + lv_label_set_text_fmt(keypad_label, "Pressed: %s", txt); + else + lv_label_set_text_fmt(keypad_label, "Released", txt); + } + indev = lv_indev_get_next(indev); } } @@ -131,6 +173,10 @@ static void ui_prepare(void) label2 = lv_label_create(lv_screen_active()); lv_obj_align(label2, LV_ALIGN_TOP_LEFT, 4, 4); + /* Keypad label */ + keypad_label = lv_label_create(lv_screen_active()); + lv_obj_align(keypad_label, LV_ALIGN_TOP_LEFT, 4, 36); + /* FPS label */ fps_label = lv_label_create(lv_screen_active()); lv_obj_align(fps_label, @@ -139,7 +185,11 @@ static void ui_prepare(void) -4); /* Main loop UI update timer */ - lv_timer_create(cursor_timer_cb, 16, NULL); + lv_timer_create(ui_timer_cb, 16, NULL); + + /* Dummy group to make indev happy */ + lv_group_t * group = lv_group_create(); + lv_indev_set_group(lv_ctr_indev_get_keypad(), group); lv_obj_invalidate(lv_screen_active()); } @@ -157,13 +207,16 @@ int main(int argc, char* argv[]) // Main loop while (aptMainLoop()) { + // scan HID inputs + hidScanInput(); + + // call LVGL timer handler u64 start = osGetTime(); lv_timer_handler(); u64 end = osGetTime(); lv_label_set_text_fmt(fps_label, "render: %llums", end - start); - hidScanInput(); - + // evacuate the dance floor! u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; // break in order to return to hbmenu