LVGL9.2 适配Linux物理按键驱动

发布于:2025-02-11 ⋅ 阅读:(75) ⋅ 点赞:(0)

LVGL9.2 适配Linux物理按键驱动

驱动代码

/**
 * @file lv_port_indev_templ.c
 *
 */

/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "lv_port_indev_key.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/input.h>
#include <unistd.h>

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void keypad_init(void);
static void keypad_read(lv_indev_t * indev, lv_indev_data_t * data);
static uint32_t keypad_get_key(void);

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_indev_t * indev_keypad;
static lv_group_t * group;

static int fd;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_port_indev_init(void)
{
    /**
     * Here you will find example implementation of input devices supported by LittelvGL:
     *  - Touchpad
     *  - Mouse (with cursor support)
     *  - Keypad (supports GUI usage only with key)
     *  - Encoder (supports GUI usage only with: left, right, push)
     *  - Button (external buttons to press points on the screen)
     *
     *  The `..._read()` function are only examples.
     *  You should shape them according to your hardware
     */

    /*------------------
     * Keypad
     * -----------------*/

    /*Initialize your keypad or keyboard if you have*/
    keypad_init();

    /*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);`*/
    group = lv_group_create();
    lv_indev_set_group(indev_keypad, group);
}

void lv_port_indev_group_add_obj(lv_obj_t * obj)
{
    lv_group_add_obj(group, obj);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/*------------------
 * Keypad
 * -----------------*/

/*Initialize your keypad*/
static void keypad_init(void)
{
    fd = open("/dev/input/event1", O_RDONLY | O_NONBLOCK);
    if(fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
}

/*Will be called by the library to read the mouse*/
static void keypad_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
    static uint32_t last_key = 0;

    /*Get the current x and y coordinates*/
    // mouse_get_xy(&data->point.x, &data->point.y);

    /*Get whether the a key is pressed and save the pressed key*/
    uint32_t act_key = keypad_get_key();
    if(act_key != 0) {
        data->state = LV_INDEV_STATE_PRESSED;

        /*Translate the keys to LVGL control characters according to your key definitions*/
        switch(act_key) {
            case 1: act_key = LV_KEY_UP; break;
            case 2: act_key = LV_KEY_DOWN; break;
            case 3: act_key = LV_KEY_ENTER; break;
        }

        last_key = act_key;
    } else {
        data->state = LV_INDEV_STATE_RELEASED;
    }

    data->key = last_key;
}

/*Get the currently being pressed key.  0 if no key is pressed*/
static uint32_t keypad_get_key(void)
{
    static int last_key = 0;
    struct input_event ev;

    if(read(fd, &ev, sizeof(struct input_event)) != sizeof(struct input_event)) {
        // perror("read");
        return last_key;
    }

    // 检查是否为按键事件
    if(ev.type == EV_KEY) {
        // printf("Key event: code=%d value=%d\n", ev.code, ev.value);
        // ev.code 是按键的编码
        // ev.value 通常是 0 (释放), 1 (按下), 或 2 (保持)
        switch(ev.code) {
            case KEY_UP:
                if(ev.value) last_key = 1;
                break;
            case KEY_DOWN:
                if(ev.value) last_key = 2;
                break;
            case KEY_LEFTCTRL:
                if(ev.value) last_key = 3;
                break;
        }
        if(ev.value == 0) last_key = 0;
    }

    return last_key;
}

#else /*Enable this file at the top*/

/*This dummy typedef exists purely to silence -Wpedantic.*/
typedef int keep_pedantic_happy;
#endif