Skip to content

RT-Thread input框架 #1914

Closed
Closed

Description

@BernardXiong

@heyuanjie87 新提交了input框架 #1907 ,API主要包括如下:

int rt_input_device_register(rt_input_t *dev, int devtype, const char *name);
int rt_input_device_unregister(rt_input_t *dev);

 int rt_input_handler_register(struct input_handler *handler);

int rt_input_device_open(struct input_handler *h);
int rt_input_device_close(struct input_handler *h);

int rt_input_report(rt_input_t *dev, int type, int code, int value);
int rt_input_rel_report(rt_input_t *dev, int code, int value);
int rt_input_abs_report(rt_input_t *dev, int code, int value);
int rt_input_key_report(rt_input_t *dev, int code, int value);
int rt_input_sync(rt_input_t *dev);

void _input_gettime(struct input_event *ev);

感觉在进行数据report时很奇异,定义非常模糊。以及input框架在整体的使用场合中,它在整体结构中处于什么样的位置也比较奇怪。这部分还需要分场景进行细化,讨论。

希望大家可以就input框架多进行讨论,最终有一份棒的input框架出来。

Activity

  1. BernardXiong commented on Oct 20, 2018

    @BernardXiong
    MemberAuthor

    @liu2guang 你原来提供过button的package,希望也进行讨论下。

    而在柿饼UI中, @yangfasheng

    关于touch这部分的input,方式是这样的:

    驱动这边有一份touch thread,当触摸屏按下时,会以中断触发方式唤醒touch thread (并关闭touch的中断),在touch thread操作过程中,会以定期轮询的模式读取touch screen的坐标点,直到触摸抬起(恢复中断)。在touch thread处理touch screen数据过程中,它会通过rtgui的接口持续向rtgui thread发送事件(最初的按下事件,中间的touch移动事件,最末的抬起事件)。

    当然柿饼UI这样的处理方式也就会让touch driver与rtgui完全耦合起来了。

  2. heyuanjie87 commented on Oct 20, 2018

    @heyuanjie87
    Contributor

    先贴一下我的驱动和应用参考供大家讨论
    #include <rtthread.h>
    #include <rtdevice.h>
    #include "board.h"

    #ifdef INPUT_USING_TOUCH
    /* 省略部分非关键代码 */

    typedef struct _touch_point
    {
    touch_event_t TOUCH_EVENT;
    uint8_t TOUCH_ID;
    uint16_t TOUCH_X;
    uint16_t TOUCH_Y;
    } touch_point_t;

    typedef struct _ft5406_touch_point
    {
    uint8_t XH;
    uint8_t XL;
    uint8_t YH;
    uint8_t YL;
    uint8_t RESERVED[2];
    } ft5406_touch_point_t;

    typedef struct _ft5406_touch_data
    {
    uint8_t DEVIDE_MODE;
    uint8_t GEST_ID;
    uint8_t TD_STATUS;
    ft5406_touch_point_t TOUCH;
    } ft5406_touch_data_t;

    #define TOUCH_POINT_GET_EVENT(T) ((touch_event_t)((T).XH >> 6))
    #define TOUCH_POINT_GET_ID(T) ((T).YH >> 4)
    #define TOUCH_POINT_GET_X(T) ((((T).XH & 0x0f) << 8) | (T).XL)
    #define TOUCH_POINT_GET_Y(T) ((((T).YH & 0x0f) << 8) | (T).YL)

    static rt_input_t _tsdev;
    static int _isrun;

    static void ft5406_hw_reset(void)
    {
    /略/
    }

    static rt_device_t _i2c_find(const char *name)
    {
    //略
    return dev;
    }

    static int _ft5406_read(rt_input_t *dev, unsigned char cmd, void *buf, int len)
    {
    //略
    }

    static int ft5406_read_touch(touch_point_t *dp)
    {
    ft5406_touch_data_t touch_data;

    _ft5406_read(&_tsdev, 0, &touch_data, sizeof(ft5406_touch_data_t));
    
    dp->TOUCH_X = TOUCH_POINT_GET_Y(touch_data.TOUCH);
    dp->TOUCH_Y = TOUCH_POINT_GET_X(touch_data.TOUCH);
    
    if (touch_data.TD_STATUS != 0)
        return 0;
    else
        return -1;
    

    }

    static void _touch_session(rt_input_t *dev)
    {
    touch_point_t tpd, tmp;

    FTDEBUG("enter\n");
    ft5406_read_touch(&tpd);
    
    rt_input_key_report(dev, BTN_TOUCH, 1);
    rt_input_abs_report(dev, ABS_X, tpd.TOUCH_X);
    rt_input_abs_report(dev, ABS_Y, tpd.TOUCH_Y);
    rt_input_sync(dev);
    
    while (_isrun)
    {
        rt_thread_mdelay(20);
        if (ft5406_read_touch(&tmp) != 0)
            break;
        if (rt_memcmp(&tmp, &tpd, sizeof(tpd)) == 0)
            continue;
    
        tpd = tmp;
        rt_input_abs_report(dev, ABS_X, tpd.TOUCH_X);
        rt_input_abs_report(dev, ABS_Y, tpd.TOUCH_Y);
        rt_input_sync(dev);
    }
    
    rt_input_key_report(dev, BTN_TOUCH, 0);
    rt_input_abs_report(dev, ABS_X, tpd.TOUCH_X);
    rt_input_abs_report(dev, ABS_Y, tpd.TOUCH_Y);
    rt_input_sync(dev);    
    

    }

    static int ft5406_irq(void *args)
    {
    return 0;
    }

    static void _touch_polling(void *p)
    {
    int io_s;

    rt_pin_mode(54, PIN_MODE_INPUT);
    
    while(_isrun)
    {
        rt_thread_mdelay(20);
    
        io_s = rt_pin_read(54);
        if (io_s == 0)
        {
            _touch_session(&_tsdev);
        }
    }
    

    }

    static int ft5406_init(rt_input_t *dev)
    {
    int ret = -1;

    ft5406_hw_reset();
    
    dev->parent.user_data = _i2c_find(I2CBUS_NAME);
    if (dev->parent.user_data == RT_NULL)
        return -1;
    
    {
        rt_thread_t tid;
        
        if (_isrun)
            return -1;
    
        _isrun = 1; 
        tid = rt_thread_create("touch", _touch_polling, RT_NULL, 2048, 10, 20);
        if (tid)
        {
            ret = rt_thread_startup(tid);
        }
    }
    
    return ret;
    

    }

    static void ft5406_deinit(rt_input_t *dev)
    {
    _isrun = 0;
    }

    static const struct input_ops _ops =
    {
    ft5406_init,
    ft5406_deinit
    };

    int ft5406_hw_init(void)
    {
    _tsdev.ops = &_ops;

    return rt_input_device_register(&_tsdev, INPUT_DEVTYPE_TOUCH, "");
    

    }
    INIT_DEVICE_EXPORT(ft5406_hw_init);
    #endif

    /* lvgl应用示例 */
    //初始化
    indev_drv.user_data = (void *)open("/dev/touch", O_NONBLOCK);
    //读坐标
    static bool input_read(lv_indev_data_t *data)
    {
    int fd;
    struct input_event ev;
    int retry;

    fd = (int)data->user_data;
    

    _again:
    if (read(fd, &ev, sizeof(ev)) == sizeof(ev))
    {
    retry = 1;
    if (ev.type == EV_ABS)
    {
    if (ev.code == ABS_X)
    last_x = ev.value;
    else if (ev.code == ABS_Y)
    last_y = ev.value;
    }
    else if (ev.type == EV_KEY)
    {
    if (ev.code == BTN_TOUCH)
    touch_down = ev.value;
    }
    else if (ev.type == EV_SYN)
    {
    rt_kprintf("%d %d %d\n", last_x, last_y, touch_down);
    retry = 0;
    }

        if (retry)
        {
            goto _again;
        }
    }
    
    data->point.x = last_x;
    data->point.y = last_y;
    data->state = (touch_down == RT_TRUE) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
    
    return false;
    

    }

  3. BernardXiong commented on Oct 20, 2018

    @BernardXiong
    MemberAuthor

    @heyuanjie87 代码好多,没有对齐没有高亮,看得好累。

  4. XXXXzzzz000 commented on Oct 25, 2018

    @XXXXzzzz000
    Contributor

    @BernardXiong 这个应该是借鉴了linux 的input子系统,感觉readme 里面的分层图并不怎么清楚。可以参考这个里面的第一个图:https://www.cnblogs.com/deng-tao/p/6094049.html
    我理解这个子系统主要就三个
    device:负责驱动外围器件,包括其初始化,数据的读取,将数据上报
    input core:匹配device 和handler
    handler:将上报的数据通过通用接口传递给用户。
    在应用中就可以直接通过open,read函数读取数据了.
    并且这样的方式一个handler可以对应多个同类型的device.并且可以很大程度上简化驱动,同时还可以通过ioctrl扩展设备功能.

  5. locked and limited conversation to collaborators on Aug 11, 2022
  6. converted this issue into a discussion #6251 on Aug 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions