博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2021-06-16FT5X06触摸实验-40
阅读量:1832 次
发布时间:2019-04-25

本文共 10640 字,大约阅读时间需要 35 分钟。

FT5X06触摸实验

  • 安装完以下ft5x06触摸驱动会打印一下内容,说明驱动编写成功

    [12727.015690] ft5x06_driver_init[12727.015821] this is  ft5x06_probe ft5x06_device_node is ft5x06[12727.015963] ft5x06_irp_gpio is 52[12727.015973] ft5x06_reset_gpio is 41[12727.027780] input: ft5x06_input_test as /devices/virtual/input/input16[12727.029412] i2c_add_driver is success
  • 输入 cat /proc/bus/input/devices 后成功看到如下:name和代码中的要匹配, input 和打印中的要匹配

I: Bus=0000 Vendor=0000 Product=0000 Version=0000N: Name="ft5x06_input_test"P: Phys=S: Sysfs=/devices/virtual/input/input16U: Uniq=H: Handlers=event7 cpufreqB: PROP=0B: EV=bB: KEY=400 0 0 0 0 1000000B: ABS=1000003

busybox hexdump /dev/input/event7

Event types code value value
0000000 ea4e 609b 5f3c 000c 0001 014a 0001 0000
0000010 ea4e 609b 5f3c 000c 0003 0000 0176 0000
0000020 ea4e 609b 5f3c 000c 0003 0001 0270 0000
0000030 ea4e 609b 5f3c 000c 0000 0000 0000 0000
0000040 ea4e 609b ddd3 000c 0001 014a 0000 0000
0000050 ea4e 609b ddd3 000c 0000 0000 0000 0000
#include 
//这个头文件中/* * Event types */#define EV_SYN 0x00#define EV_KEY 0x01#define EV_REL 0x02#define EV_ABS 0x03#define EV_MSC 0x04#define EV_SW 0x05#define EV_LED 0x11#define EV_SND 0x12#define EV_REP 0x14#define EV_FF 0x15#define EV_PWR 0x16#define EV_FF_STATUS 0x17#define EV_MAX 0x1f#define EV_CNT (EV_MAX+1)/* Code 255 is reserved for special needs of AT keyboard driver */#define BTN_DIGI 0x140#define BTN_TOOL_PEN 0x140#define BTN_TOOL_RUBBER 0x141#define BTN_TOOL_BRUSH 0x142#define BTN_TOOL_PENCIL 0x143#define BTN_TOOL_AIRBRUSH 0x144#define BTN_TOOL_FINGER 0x145#define BTN_TOOL_MOUSE 0x146#define BTN_TOOL_LENS 0x147#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */#define BTN_TOUCH 0x14a#define BTN_STYLUS 0x14b#define BTN_STYLUS2 0x14c#define BTN_TOOL_DOUBLETAP 0x14d#define BTN_TOOL_TRIPLETAP 0x14e#define BTN_TOOL_QUADTAP 0x14f /* Four fingers on trackpad *//* * Absolute axes 绝对区域 */#define ABS_X 0x00#define ABS_Y 0x01#define ABS_Z 0x02#define ABS_RX 0x03#define ABS_RY 0x04#define ABS_RZ 0x05#define ABS_THROTTLE 0x06#define ABS_RUDDER 0x07#define ABS_WHEEL 0x08#define ABS_GAS 0x09#define ABS_BRAKE 0x0a#define ABS_HAT0X 0x10#define ABS_HAT0Y 0x11#define ABS_HAT1X 0x12#define ABS_HAT1Y 0x13#define ABS_HAT2X 0x14#define ABS_HAT2Y 0x15#define ABS_HAT3X 0x16#define ABS_HAT3Y 0x17#define ABS_PRESSURE 0x18#define ABS_DISTANCE 0x19#define ABS_TILT_X 0x1a#define ABS_TILT_Y 0x1b#define ABS_TOOL_WIDTH 0x1c#define ABS_VOLUME 0x20#define ABS_MISC 0x28#define ABS_MT_SLOT 0x2f /* MT slot being modified */#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */#define ABS_MT_POSITION_X 0x35 /* Center X touch position */#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */#define ABS_MT_TOOL_X 0x3c /* Center X tool position */#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */#define ABS_MAX 0x3f#define ABS_CNT (ABS_MAX+1)
  • 各种事件
  1. ABS_MT_TRACKING_ID

    参数是类型B特有的。实际上,每个slot会和一个ID相对应,一个非负数的表示一次接触,-1表示这是一个无用的slot(或者理解为一次接触的结束)。无论在接触的类型相对应的slot发生了改变,驱动都应该通过改变这个值来使这个slot失效。并且下一次触摸的ID值会是这次的值加1。

  2. EV_ABS

    事件的一种类型。表示绝对坐标。

  3. EV_KEY

    事件的一种类型。表示是按键事件。

  4. BTN_TOUCH

    触碰按键。其值是DOWN或者UP。

  5. BTN_TOOL_FINGER

    按键的是finger,并且其值也是DOWN或者UP。

  6. ABS_MT_POSITION_X,ABS_MT_POSITION_Y

    相对于屏幕中心的x,y坐标。

  7. ABS_MT_TOUCH_MAJOR

    接触部分的长轴长度。相当于椭圆的长轴。

  8. ABS_MT_TOUCH_MINOR

    接触部分的短轴长度。相当于椭圆的短轴。

  9. EV_SYN

    事件类型的一种。在事件完成的时候更新数据。

  10. SYN_REPORT

    可以看到,在一次触摸中,就有好几次SYN_REPORT。是因为有很多的事件,或者是说SYN_REPORT就是一次事件的结束。上报内核

  • 点击屏幕后出现这些数据,下面我们解释下如上的数据
  1. 后两列是value
  2. 倒数第三列对应code
  3. 倒数第四列对应Event types
  • 第一行

    Event types 0001 代表 EV_KEY

    code 014a 代表 #define BTN_TOUCH 0x14a 是touch 事件 0代表抬起, 1 代表摁下

    value 0001 对应的是摁下

    第一行 这个事件的意思是 单个手指触摸到了屏幕

  • 第二行

    Event types 0003 代表#define EV_ABS 0x03 是触摸的绝对坐标

    code 0000 代表 #define ABS_X 0x00 是x轴的绝对坐标

    value 0176 换算十进制 是 374

    第二行的 这个事件的意思是 单个手指 触摸屏幕的x的坐标是 374

  • 第三行

    Event types 0003 代表#define EV_ABS 0x03 是触摸的绝对坐标

    code 0001 代表 #define ABS_Y 0x00 是y轴的绝对坐标

    value 0270 换算十进制 是624

    这个事件的意思是 单个手指 触摸屏幕的y的绝对坐标 是624

  • 第四行

    Event types 0000 代表 #define EV_SYN 0x00 是上报这个事件信号

    将摁下,触摸屏幕的点的坐标 上报给了内核

  • 第五行

    Event types 0001 代表 EV_KEY

    code 014a 代表 #define BTN_TOUCH 0x14a 是touch 事件 0代表抬起, 1 代表摁下

    value 0000 对应的是抬起

    这个事件意思是 单个手指离开了屏幕

  • 第六行

    Event types 0000 代表 #define EV_SYN 0x00 是上报这个事件信号

    将摁下,触摸屏幕的点的坐标 上报给了内核

代码

  • touch_test.c
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
//工作模式为正常状态的地址#define DEVICE_MOOE 0x00//为工作时的地址#define ID_G_MODE 0xa4struct device_node *ftx06_device_node;struct input_dev *ft5x06_dev;static void ft5x06_fun(struct work_struct *work);DECLARE_WORK(ft5x06_work,ft5x06_fun);static struct i2c_client * ft5x06_client;int irq;static void ft5x06_write_reg(u8 reg_addr, u8 data, u8 len);static void ft5x06_write_reg(u8 reg_addr, u8 data, u8 len){ u8 buff[256]; struct i2c_msg msgs[] = { [0] = { .addr = ft5x06_client->addr, .flags = 0, .len = len + 1, .buf = buff, }, // [1] = { // .addr = ft5x06_client->addr, // .flags = 1, // .len = sizeof(data), // .buf = &data, // } }; buff[0] = reg_addr; memcpy(&buff[1], &data, len); i2c_transfer(ft5x06_client->adapter, msgs, 1);}struct of_device_id ft5x06_id[] = { {.compatible = "edt,ft5x0x_ts", 0}, {.compatible = "edt,ft5x0x_ts", 0}, {.compatible = "edt,ft5x0x_ts", 0}, {}};struct i2c_device_id ft5x06_id_ts[] = { {"xxxxx", 0}, {},};static int ft5x06_read_reg(u8 reg_addr);static int ft5x06_read_reg(u8 reg_addr){ u8 data; struct i2c_msg msgs[] = { [0] = { .addr = ft5x06_client->addr, .flags = 0, .len = sizeof(reg_addr), .buf = ®_addr, }, [1] = { .addr = ft5x06_client->addr, .flags = 1, .len = sizeof(data), .buf = &data, } }; i2c_transfer(ft5x06_client->adapter, msgs, 2); return data;}static void ft5x06_fun(struct work_struct *work){ int TOUCH1_XH, TOUCH1_XL,x; int TOUCH1_YH, TOUCH1_YL,y; int TD_STATUS; //读取TOUCH1_XH 寄存器的值 TOUCH1_XH = ft5x06_read_reg(0x03); //读取TOUCH1_XL 寄存器的值 TOUCH1_XL = ft5x06_read_reg(0x04); //获取x的坐标值 x = ((TOUCH1_XH << 8) | TOUCH1_XL) & 0x0fff; //读取TOUCH1_YH 寄存器的值 TOUCH1_YH = ft5x06_read_reg(0x05); //读取TOUCH1_YL 寄存器的值 TOUCH1_YL = ft5x06_read_reg(0x06); //获取Y的坐标值 y = ((TOUCH1_YH << 8) | TOUCH1_YL) & 0x0fff; //读取寄存器TD_STATUS 的值 TD_STATUS = ft5x06_read_reg(0x02); //获取有没有手指在屏幕上 TD_STATUS = TD_STATUS & 0xf; //判断有没有手指按上,如果有的话就要上报摁下的事件,没有就要上报抬手的事件 if (TD_STATUS ==0) { input_report_key(ft5x06_dev, BTN_TOUCH, 0); input_sync(ft5x06_dev); } else { input_report_key(ft5x06_dev, BTN_TOUCH, 1); input_report_abs(ft5x06_dev, ABS_X, x); input_report_abs(ft5x06_dev, ABS_Y, y); input_sync(ft5x06_dev); } }irq_handler_t ft5x06_handler(int irq, void * args){ schedule_work(&ft5x06_work); return IRQ_HANDLED;}int ft5x06_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id){ int ret; int ft5x06_irp_gpio; int ft5x06_reset_gpio; printk("this is ft5x06_probe \n "); ft5x06_client = i2c_client;//因为我们要在别的函数里面用到这个client,所以我们要把他们复制进来 ftx06_device_node = of_find_node_by_path("/i2c@ff110000/ft5x06@38"); //获得触摸芯片的节点 if (ftx06_device_node == NULL) { printk("of_find_node_by_path is error \n"); return -1; } printk("ft5x06_device_node is %s \n", ftx06_device_node->name); //获得中断号 ft5x06_irp_gpio = of_get_named_gpio(ftx06_device_node, "touch-gpio", 0); if (ft5x06_irp_gpio < 0) { printk("of_get_named_gpio_irq is error \n"); return -1; } //获得复位引脚标号 ft5x06_reset_gpio = of_get_named_gpio(ftx06_device_node, "reset-gpios", 0); if (ft5x06_reset_gpio < 0) { printk("of_get_named_gpio_reset is error \n"); return -1; } printk("ft5x06_irp_gpio is %d \n", ft5x06_irp_gpio); printk("ft5x06_reset_gpio is %d \n", ft5x06_reset_gpio); //申请中断引脚 gpio_free(ft5x06_irp_gpio); ret = gpio_request(ft5x06_irp_gpio, "irq_gpio"); if (ret < 0 ) { printk("gpio_request_irp is error \n "); return -1; } //申请复位引脚 gpio_free(ft5x06_reset_gpio); ret = gpio_request(ft5x06_reset_gpio, "reset_gpio"); if (ret < 0 ) { printk("gpio_request_reset is error \n "); return -1; } //把中断的引脚设置为输入 gpio_direction_input(ft5x06_irp_gpio); //设置复位引脚的方向为输出,然后停止复位 gpio_direction_output(ft5x06_reset_gpio, 0); msleep(5); gpio_set_value(ft5x06_reset_gpio, 1); irq = gpio_to_irq(ft5x06_irp_gpio); ret = request_irq(irq, ft5x06_handler, IRQ_TYPE_EDGE_FALLING|IRQF_TRIGGER_RISING, "ft5x06_irq", NULL); if (ret < 0) { printk("request_irq is error \n"); goto error_request_irq; } //设置工作模式为正常 ft5x06_write_reg(DEVICE_MOOE, 0, 1); // ret = ft5x06_read_reg(ID_G_MODE, 1, 1); ft5x06_write_reg(ID_G_MODE, 1, 1); ft5x06_dev = input_allocate_device(); ft5x06_dev->name = "ft5x06_input_test"; //key 事件 __set_bit(EV_KEY,ft5x06_dev->evbit); //绝对事件 触摸 __set_bit(EV_ABS, ft5x06_dev->evbit); //支持按键检测 事件 __set_bit(BTN_TOUCH,ft5x06_dev->keybit); //支持x坐标值的范围 __set_bit(ABS_X, ft5x06_dev->absbit); //支持y坐标值的范围 __set_bit(ABS_Y, ft5x06_dev->absbit); //支持压力值的检测 __set_bit(ABS_PRESSURE, ft5x06_dev->keybit); //设置x坐标的范围 input_set_abs_params(ft5x06_dev, ABS_X, 0, 800, 0, 0); //设置y坐标的范围 input_set_abs_params(ft5x06_dev, ABS_Y, 0, 1280, 0, 0); //设置按压范围 input_set_abs_params(ft5x06_dev, ABS_PRESSURE, 0, 255, 0, 0); ret = input_register_device(ft5x06_dev); if (ret < 0) { printk("input_register_device is error \n"); goto error_input_register; } return 0;error_request_irq: free_irq(irq, NULL); return ret;error_input_register: free_irq(irq, NULL); input_unregister_device(ft5x06_dev); input_free_device(ft5x06_dev); return ret;}int ft5x06_remove(struct i2c_client *i2c_client){ printk("ft5x06_remove \n "); return 0;}static struct i2c_driver ft5x06_driver = { .probe = ft5x06_probe, .remove = ft5x06_remove, .id_table = ft5x06_id_ts, .driver = { .owner = THIS_MODULE, .name = "ft5x06_test", .of_match_table = ft5x06_id, },};static int ft5x06_driver_init(void){ int ret; printk("ft5x06_driver_init \n"); ret = i2c_add_driver(&ft5x06_driver); if (ret < 0) { printk("i2c_add_driver is error \n "); return ret ; } printk("i2c_add_driver is success \n"); return 0;}static void ft5x06_driver_exit(void){ printk("ft5x06_driver_exit \n"); input_unregister_device(ft5x06_dev); input_free_device(ft5x06_dev); free_irq(irq, NULL); i2c_del_driver(&ft5x06_driver);}module_init(ft5x06_driver_init);module_exit(ft5x06_driver_exit);MODULE_LICENSE("GPL");

转载地址:http://alrkf.baihongyu.com/

你可能感兴趣的文章
Mongodb的集群
查看>>
车联网相关知识点整理
查看>>
SpringBoot整合Mqtt
查看>>
创建Java工程镜像示例
查看>>
Protocol Buffer在Java中的使用方式
查看>>
Mongodb理论点
查看>>
Docker网络模式
查看>>
XXL分布式任务调度平台
查看>>
Storm工作原理&集群环境搭建
查看>>
Storm在Java中的应用
查看>>
Rancher2.x--stable版本环境搭建
查看>>
Rancher2.X与K8S
查看>>
EMQX环境搭建
查看>>
Mongodb的语法
查看>>
APP消息推送
查看>>
APP远程推送-------极光
查看>>
创建Docker基础镜像
查看>>
JT32960与JT808区别
查看>>
商用车生态指南
查看>>
Java整合APNS
查看>>