STM32 LVGL Repeat key 처리

LVGL은 key_read_cb에서 정상적으로 키를 올려준다면 자동으로 모든 키에 대해 repeat key 처리가 된다. 특정 키에 대해선 repeat key를 처리하지 않으려면 key_read_cb에서 키를 올려주지 않으면 key repeat interval time을 계산하지 않기 때문에 repeat key 처리가 되지 않는다.

 

LVGL에서 repeat key 종류를 등록하는 것이 있는지 모르겠지만, 코드상 분석한 결과 key_read_cb에서 특정 키에 대해 처리하지 않으려면 LVGL 시뮬레이터인 경우 lv_drivers/indev/keyboard.c 파일을 아래와 같이 수정하면 된다.

index 0c08685..d2e2a04 100644
--- a/indev/keyboard.c
+++ b/indev/keyboard.c
@@ -50,11 +50,23 @@ void keyboard_init(void)
  * @param data store the read data here
  * @return false: because the points are not buffered, so no more data to be read
  */
+static uint32_t prev_key;
+
 void keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
 {
     (void) indev_drv;      /*Unused*/
+    if(prev_key == last_key && state == LV_INDEV_STATE_PRESSED)
+    {
+        if(last_key == SDLK_HOME || last_key == SDLK_ESCAPE || last_key == SDLK_KP_ENTER)
+            return;
+    }
     data->state = state;
     data->key = keycode_to_ascii(last_key);
+
+    if(state == LV_INDEV_STATE_PRESSED)
+        prev_key = last_key;
+    else
+        prev_key = 0;
 }
 
 /**
@@ -127,6 +139,9 @@ static uint32_t keycode_to_ascii(uint32_t sdl_key)
         case SDLK_PAGEUP:
             return LV_KEY_PREV;
 
+        case SDLK_HOME:
+            return LV_KEY_HOME;
+
         default:
             return sdl_key;
     }
~

HOME / ESC / ENTER 키에 대해선 repeat key 처리를 하지 않기 위해 값 설정없이 리턴하도록 수정하면 될 것이다. STM32 개발보드에선 GPIO Input 키를 LVGL KeyPad로 연결하였으며, UP/DOWN key만 repeat key 처리하기 위해 아래와 같이 수정하였다.

static void gpio_read_button(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
    for(int i = 0 ; i < MAX_KEY_NUM ; i++)
    {
        uint8_t state = gpio_get_key_state(i);
        if(state == 0 /* for repeat */ || prev_key[i] != state)
        {
            if(i >= KEY_MENU && state == 0 && prev_key[i] == state)
                continue;
                
            switch(i)
            {
                case KEY_UP:   data->key = LV_KEY_UP;    break;
                case KEY_DOWN: data->key = LV_KEY_DOWN;  break;
                case KEY_MENU: data->key = LV_KEY_HOME;  break;
                case KEY_OK:   data->key = LV_KEY_ENTER; break;
                case KEY_ESC:  data->key = LV_KEY_ESC;   break;
            }

            if(state == 0) data->state = LV_INDEV_STATE_PRESSED;
            else           data->state = LV_INDEV_STATE_RELEASED;

            prev_key[i] = state;
        }
    }
}

STM32에서 LVGL Input device 설정은 아래 포스트를 참고하면 될 것이며, 위 소스는 아래 포스트의 코드를 일부 수정한 것이다.

 

STM32 LVGL Input device with GPIO

기존 개발 코드는 Input device를 GPIO로 받아서 처리하였는데, LVGL input device와 연결하지 않고 GPIO를 직접 컨트롤하여 key pressed, key released 및 repeat key 처리를 구현하였다. 이렇게 직접 코딩한 이..

memories.tistory.com

STM32에서 사용할 메뉴 구성을 50%정도 포팅하였다. 기본 와꾸는 거의 만들었으며, 메뉴 설정에 따른 컨트롤 코드를 작성하면 될 듯 하다.