(七)GT1151触摸屏驱动--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>

目录

一、AT4384 RGB屏幕触摸芯片

二、设备树修改

1、.dtsi文件修改

2、.dts文件修改 

三、驱动编写

1、驱动分析

2、驱动代码

四、内核配置

1、IIC设备使能

2、内核驱动添加

3、gt1151驱动使能

五、触摸测试

1、启动与文件检查

2、触摸测试

六、主要参考内容


一、AT4384 RGB屏幕触摸芯片

使用正点原子屏幕的朋友一定要注意以前原子的触摸屏的触摸芯片是gt9147的,教程里的也是gt9147的驱动,后来,大概在2021年5月份前后,原子的4.3寸屏更换了触摸芯片了,触摸芯片型号是gt1151的。所以,后期买屏幕的朋友可能拿到屏幕的芯片不是gt9147的了,所以按照教程或者前面的帖子来改的话,可能是无法触摸的。所以说,一定要先确定自己触摸屏幕的触摸芯片型号。


二、设备树修改

1、.dtsi文件修改

dtsi文件中添加如下内容,在pio结点下对本次实验所用到的管脚进行功能复用,所用到的功能为I2C通信功能、GPIO输出复位功能、中断检测功能。其中,I2C选择i2c0,也就是PE11、PE12,复位管脚选择PE4,中断检测管脚选择PE3,这是我们的硬件决定的。

pio: pinctrl@1c20800 {
	compatible = "allwinner,suniv-f1c100s-pinctrl";
	reg = <0x01c20800 0x400>;
	interrupts = <38>, <39>, <40>;
	clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
	clock-names = "apb", "hosc", "losc";
	gpio-controller;
	interrupt-controller;
	#interrupt-cells = <3>;
	#gpio-cells = <3>;

	uart0_pe_pins: uart0-pe-pins {
		pins = "PE0", "PE1";
		function = "uart0";
	};

	// modify by kashine
	lcd_rgb666_pins: lcd-rgb666-pins {
		pins = "PD0", "PD1", "PD2", "PD3", "PD4",
			   "PD5", "PD6", "PD7", "PD8", "PD9",
			   "PD10", "PD11", "PD12", "PD13", "PD14",
			   "PD15", "PD16", "PD17", "PD18", "PD19",
			   "PD20", "PD21";
		function = "lcd";
	};

	// modify by kashine
	mmc0_pins: mmc0-pins {
		pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
		function = "mmc0";
	};

	// modify by kashine 2
	i2c0_pins: i2c0_pins {
		pins = "PE11", "PE12";
		function = "i2c0";
	};

	// modify by kashine 2
	ts_reset_pin: ts_reset_pin {
		pins = "PE4";
		function = "gpio_out";
	};
	ts_int_pin: ts_int_pin {
		pins = "PE3";
		function = "gpio_in";
	};

};

soc结点下添加i2c0结点, 描述了i2c0对应的驱动、时钟和所用管脚等信息,在.dtsi文件中该结点的状态属性值为disabled,这意味着需要在.dts文件中使能该结点功能。

i2c0: i2c@1C27000 {
	compatible = "allwinner,sun6i-a31-i2c";
	reg = <0x01C27000 0x400>;
	interrupts = <7>;
	clocks = <&ccu CLK_BUS_I2C0>;
	resets = <&ccu RST_BUS_I2C0>;
	pinctrl-names = "default";
	pinctrl-0 = <&i2c0_pins>;
	status = "disabled";
	#address-cells = <1>;
	#size-cells = <0>;
};

2、.dts文件修改 

dts文件添加以下内容,gt1151触摸屏对应的驱动为goodix,gt1151ATK4384,对于该驱动的编写,我们将在下一节进行描述。注意:gt1151器件地址和gt9147相同,都是0x14。每个I2C器件都有一个设备地址,通过发送具体的设备地址来决定访问哪个I2C器件。I2C设备的读写地址和I2C设备地址不同,I2C设备的读写地址是一个8位的数据,其中高7位是设备地址,最后1位是读写位,为1的话表示这是一个读操作,为0的话表示这是一个写操作。 I2C设备的写地址 = I2C设备地址 << 1,I2C设备的读地址 = (I2C设备地址 << 1) + 1。

&i2c0 {
    status = "okay";

    gt1151: touchscreen@14 {
        compatible = "goodix,gt1151ATK4384";// "goodix,gt1151";
        reg = <0x14>;// gt1151器件地址,器件地址是I2C器件固有的地址编码,器件出厂时已经给定,不可更改
        interrupt-parent = <&pio>;
        interrupts = <4 3 IRQ_TYPE_EDGE_FALLING>; /* (PE3) */
        pinctrl-names = "default";
		pinctrl-0 = <&ts_int_pin>;
        reset-gpios = <&pio 4 4 GPIO_ACTIVE_LOW>; /* RST (PE4) */
        interrupt-gpios = <&pio 4 3 GPIO_ACTIVE_LOW>;
		touchscreen-size-x = <800>;
		touchscreen-size-y = <480>;
		touchscreen-swapped-x-y;
    };
};

三、驱动编写

1、驱动分析

驱动程序编写主要参考《正点原子开发指南》,在裸机开发中进行触摸屏的驱动,主要流程如下:

  ①、电容触摸屏是IIC接口的,需要触摸 IC,以正点原子的 ATK4384 为例,其所使用的触
摸屏控制 IC 为GT1151,因此所谓的电容触摸驱动就是 IIC设备驱动。 
  ②、触摸IC提供了中断信号引脚(INT),可以通过中断来获取触摸信息。 
  ③、电容触摸屏得到的是触摸位置绝对信息以及触摸屏是否有按下。 
  ④、电容触摸屏不需要校准,当然了,这只是理论上的,如果电容触摸屏质量比较差,或
者触摸玻璃和 TFT 之间没有完全对齐,那么也是需要校准的。 

 那么电容触摸屏的Linux驱动主要需要以下几个驱动框架的组合:

  ①、IIC 设备驱动,因为电容触摸IC基本都是IIC接口的,因此大框架就是IIC设备驱动。 
  ②、通过中断引脚(INT)向linux内核上报触摸信息,因此需要用到linux中断驱动框架。
标的上报在中断服务函数中完成。 
  ③、触摸屏的坐标信息、屏幕按下和抬起信息都属于linux的input子系统因此向 linux 内
核上报触摸屏坐标信息就得使用input子系统。

2、驱动代码

我们根据上面的分析编写了如下的gt1151的触摸屏驱动程序,至于代码的的详细解释,请参考正点原子官方文档,或者代码中注释,不在此处赘述。设备(设备树结点)和驱动匹配成功之后,gt1151probe函数就会执行,在该函数内部获取设备树终端和复位引脚、复位并初始化gt1151、获取设备信息后注册input设备,最后初始化中断。注意:设备树匹配表gt1151_of_match_table中的.compatible = "goodix,gt1151ATK4384"用来连接设备树和驱动,在设备树中的compatible一定要于此处完全相同!

// gt1151驱动代码
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/gpio/consumer.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/i2c.h>
#include <asm/unaligned.h>

#define GT_CTRL_REG 	        0X8040  /* GT1151控制寄存器         */
#define GT_MODSW_REG 	        0X804D  /* GT1151模式切换寄存器        */
#define GT_9xx_CFGS_REG 	    0X8047  /* GT1151配置起始地址寄存器    */
#define GT_1xx_CFGS_REG 	    0X8050  /* GT1151配置起始地址寄存器    */
#define GT_CHECK_REG 	        0X80FF  /* GT1151校验和寄存器       */
#define GT_PID_REG 		        0X8140  /* GT1151产品ID寄存器       */

#define GT_GSTID_REG 	        0X814E  /* GT1151当前检测到的触摸情况 */
#define GT_TP1_REG 		        0X814F  /* 第一个触摸点数据地址 */
#define GT_TP2_REG 		        0X8157	/* 第二个触摸点数据地址 */
#define GT_TP3_REG 		        0X815F  /* 第三个触摸点数据地址 */
#define GT_TP4_REG 		        0X8167  /* 第四个触摸点数据地址  */
#define GT_TP5_REG 		        0X816F	/* 第五个触摸点数据地址   */
#define MAX_SUPPORT_POINTS      5       /* 最多5点电容触摸 */

// 存放电容触摸设备相关属性信息
struct gt1151_dev {
	int irq_pin,reset_pin;					/* 中断和复位IO		*/
	int irqnum;								/* 中断号    		*/
	int irqtype;							/* 中断类型         */
	int max_x;								/* 最大横坐标   	*/
	int max_y; 								/* 最大纵坐标		*/
	void *private_data;						/* 私有数据 		*/
	struct input_dev *input;				/* input结构体 		*/
	struct i2c_client *client;				/* I2C客户端 		*/

};
struct gt1151_dev gt1151;

const u8 irq_table[] = {IRQ_TYPE_EDGE_RISING, IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH};  /* 触发方式 */


// 复位GT1151
static int gt1151_ts_reset(struct i2c_client *client, struct gt1151_dev *dev)
{
	int ret = 0;

    /* 申请复位IO*/
	if (gpio_is_valid(dev->reset_pin)) {  		
		/* 申请复位IO,并且默认输出高电平 */
		ret = devm_gpio_request_one(&client->dev,	
					dev->reset_pin, GPIOF_OUT_INIT_HIGH,
					"gt1151 reset");
		if (ret) {
			return ret;
		}
	}

    /* 初始化GT1151,要严格按照GT1151时序要求 */
    gpio_set_value(dev->reset_pin, 0); /* 复位GT1151 */
    msleep(10);

    gpio_set_value(dev->reset_pin, 1); /* 停止复位GT1151 */
    msleep(10);

    // gpio_set_value(dev->irq_pin, 0);    /* 拉低INT引脚 */
    // msleep(50);
	
    // gpio_direction_input(dev->irq_pin); /* INT引脚设置为输入 */
	
	return 0;
}

// 从GT1151读取多个寄存器数据
static int gt1151_read_regs(struct gt1151_dev *dev, u16 reg, u8 *buf, int len)
{
	int ret;
    u8 regdata[2];
	struct i2c_msg msg[2];
	struct i2c_client *client = (struct i2c_client *)dev->client;
    
    /* GT1151寄存器长度为2个字节 */
    regdata[0] = reg >> 8;
    regdata[1] = reg & 0xFF;

	// 别和SPI通信方式搞混了
	/* msg[0]为发送要读取的首地址 */
	msg[0].addr = client->addr;			/* gt1151地址 应该是设备树中的器件地址 */
	msg[0].flags = !I2C_M_RD;			/* 标记为发送数据 */
	msg[0].buf = &regdata[0];			/* 读取的首地址 */
	msg[0].len = 2;						/* reg长度*/

	/* msg[1]读取数据 */
	msg[1].addr = client->addr;			/* gt1151地址 */
	msg[1].flags = I2C_M_RD;			/* 标记为读取数据*/
	msg[1].buf = buf;					/* 读取数据缓冲区 */
	msg[1].len = len;					/* 要读取的数据长度*/

	ret = i2c_transfer(client->adapter, msg, 2);
	if(ret == 2) {
		ret = 0;
	} else {
		ret = -EREMOTEIO;
	}
	return ret;
}

// 向GT1151多个寄存器写入数据
static s32 gt1151_write_regs(struct gt1151_dev *dev, u16 reg, u8 *buf, u8 len)
{
	u8 b[256];
	struct i2c_msg msg;
	struct i2c_client *client = (struct i2c_client *)dev->client;
	
	b[0] = reg >> 8;			/* 寄存器首地址低8位 */
    b[1] = reg & 0XFF;			/* 寄存器首地址高8位 */
	memcpy(&b[2],buf,len);		/* 将要写入的数据拷贝到数组b里面 */

	msg.addr = client->addr;	/* gt1151地址 */
	msg.flags = 0;				/* 标记为写数据 */

	msg.buf = b;				/* 要写入的数据缓冲区 */
	msg.len = len + 2;			/* 要写入的数据长度 */

	return i2c_transfer(client->adapter, &msg, 1);
}

// 中断服务函数
static irqreturn_t gt1151_irq_handler(int irq, void *dev_id)
{
    int touch_num = 0;
    int input_x, input_y;
    int id = 0;
    int ret = 0;
    u8 data;
    u8 touch_data[5];
    struct gt1151_dev *dev = dev_id;

	// printk("enter irq handler!\r\n");

    ret = gt1151_read_regs(dev, GT_GSTID_REG, &data, 1);// GT1151当前检测到的触摸情况
    if (data == 0x00)  {     /* 没有触摸数据,直接返回 */
        goto fail;
    } else {                 /* 统计触摸点数据 */
        touch_num = data & 0x0f;
    }

    /* 由于GT1151没有硬件检测每个触摸点按下和抬起,因此每个触摸点的抬起和按
     * 下不好处理,尝试过一些方法,但是效果都不好,因此这里暂时使用单点触摸 
     */
    if(touch_num) {         /* 单点触摸按下 */
        gt1151_read_regs(dev, GT_TP1_REG, touch_data, 5);
        id = touch_data[0] & 0x0F;
        if(id == 0) { //读取成功
            input_x  = touch_data[1] | (touch_data[2] << 8);
            input_y  = touch_data[3] | (touch_data[4] << 8);

			// 单点id一直等于0即可
            input_mt_slot(dev->input, 0);
		    input_mt_report_slot_state(dev->input, MT_TOOL_FINGER, true);
		    input_report_abs(dev->input, ABS_MT_POSITION_X, input_x);
		    input_report_abs(dev->input, ABS_MT_POSITION_Y, input_y);
        }
    } else if(touch_num == 0){                /* 单点触摸释放 */
        input_mt_slot(dev->input, id);
        input_mt_report_slot_state(dev->input, MT_TOOL_FINGER, false);// 删除触摸点
    }

	input_mt_report_pointer_emulation(dev->input, true);// 没有出现硬件检测到的点比上报的触摸点多的情况
    input_sync(dev->input);

    data = 0x00;                /* 向0X814E寄存器写0 */
    gt1151_write_regs(dev, GT_GSTID_REG, &data, 1);

fail:
	return IRQ_HANDLED;
}


// GT1151中断初始化
static int gt1151_ts_irq(struct i2c_client *client, struct gt1151_dev *dev)
{
	int ret = 0;
	// 由于触摸IC复位需要用到两个IO 在前面已经request了
	/* 2,申请中断,client->irq就是IO中断, */
	ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
					gt1151_irq_handler, irq_table[dev->irqtype] | IRQF_ONESHOT,
					client->name, &gt1151);
	if (ret) {
		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
		return ret;
	}else
	{
		printk("irq init!\r\n");
		printk("dev->irqtype = %d\r\n", dev->irqtype);
	}
	
	return 0;
}

// GT1151读取固件
static int gt1151_read_firmware(struct i2c_client *client, struct gt1151_dev *dev)
{
	int ret = 0, version = 0;
	u16 id = 0;
	u8 data[7]={0};
	char id_str[5];
	ret = gt1151_read_regs(dev, GT_PID_REG, data, 6);
	if (ret) {
		dev_err(&client->dev, "Unable to read PID.\n");
		return ret;
	}
	memcpy(id_str, data, 4);
	id_str[4] = 0;

    if (kstrtou16(id_str, 10, &id))id = 0x1001;

	version = get_unaligned_le16(&data[4]);
	
	dev_info(&client->dev, "ID %d, version: %04x\n", id, version);
	switch (id) {    /* 由于不同的芯片配置寄存器地址不一样需要判断一下  */
    case 1151:
    case 1158:
    case 5663:
    case 5688:    /* 读取固件里面的配置信息  */
        ret = gt1151_read_regs(dev, GT_1xx_CFGS_REG, data, 7);  
		break;
    default:
        ret = gt1151_read_regs(dev, GT_1xx_CFGS_REG, data, 7);
		break;
    }
	if (ret) {
		dev_err(&client->dev, "Unable to read Firmware.\n");
		return ret;
	}
	dev->max_x = (data[2] << 8) + data[1];
	dev->max_y = (data[4] << 8) + data[3];
	dev->irqtype = data[6] & 0x3;
	printk("X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x", dev->max_x, dev->max_y, dev->irqtype);

	return 0;
}

// probe函数
int gt1151_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    u8 data, ret;
    gt1151.client = client;
	printk("Driver and device has mached!!!\r\n");

 	/* 1,获取设备树中的中断和复位引脚 */
	gt1151.irq_pin = of_get_named_gpio(client->dev.of_node, "interrupt-gpios", 0);
	gt1151.reset_pin = of_get_named_gpio(client->dev.of_node, "reset-gpios", 0);

	// printk("irq_pin=%d, reset_pin=%d\r\n", gt1151.irq_pin, gt1151.reset_pin);
	/* 2,复位GT1151 */
	ret = gt1151_ts_reset(client, &gt1151);
	if(ret < 0) {
		goto fail;
    }

    /* 3,初始化GT1151 */
    data = 0x02;
    gt1151_write_regs(&gt1151, GT_CTRL_REG, &data, 1); /* 软复位 */
    mdelay(100);
    data = 0x0;
    gt1151_write_regs(&gt1151, GT_CTRL_REG, &data, 1); /* 停止软复位 */
    mdelay(100);

    /* 4,初始化GT1151,读取固件 */ // 应该是读触摸设备的信息
	ret = gt1151_read_firmware(client, &gt1151);
	if(ret != 0) {
		printk("Fail !!! check !!\r\n");
		goto fail;
    }
	
    /* 5,input设备注册 */
	gt1151.input = devm_input_allocate_device(&client->dev);
	if (!gt1151.input) {
		ret = -ENOMEM;
		goto fail;
	}
	gt1151.input->name = client->name;
	gt1151.input->id.bustype = BUS_I2C;
	gt1151.input->dev.parent = &client->dev;

	__set_bit(EV_KEY, gt1151.input->evbit);
	__set_bit(EV_ABS, gt1151.input->evbit);
	__set_bit(BTN_TOUCH, gt1151.input->keybit);

	input_set_abs_params(gt1151.input, ABS_X, 0, gt1151.max_x, 0, 0);
	input_set_abs_params(gt1151.input, ABS_Y, 0, gt1151.max_y, 0, 0);
	input_set_abs_params(gt1151.input, ABS_MT_POSITION_X,0, gt1151.max_x, 0, 0);
	input_set_abs_params(gt1151.input, ABS_MT_POSITION_Y,0, gt1151.max_y, 0, 0);	     
	ret = input_mt_init_slots(gt1151.input, MAX_SUPPORT_POINTS, 0);
	if (ret) {
		goto fail;
	}

	ret = input_register_device(gt1151.input);
	if (ret)
		goto fail;

    /* 6,最后初始化中断 */
	ret = gt1151_ts_irq(client, &gt1151);
	if(ret < 0) {
		goto fail;
	}

    return 0;

fail:
	return ret;
}

// i2c驱动的remove函数
int gt1151_remove(struct i2c_client *client)
{
    input_unregister_device(gt1151.input);
    return 0;
}

// 传统驱动匹配表
const struct i2c_device_id gt1151_id_table[] = {
	{ "goodix,gt1151ATK4384", 0, },
    { /* sentinel */ }
};


// 设备树匹配表 
const struct of_device_id gt1151_of_match_table[] = {
    {.compatible = "goodix,gt1151ATK4384" },
    { /* sentinel */ }
};

/* i2c驱动结构体 */	
struct i2c_driver gt1151_i2c_driver = {
    .driver = {
        .name  = "gt1151",
        .owner = THIS_MODULE,
        .of_match_table = gt1151_of_match_table,
    },
    .id_table = gt1151_id_table,
    .probe  = gt1151_probe,
    .remove = gt1151_remove,
};

module_i2c_driver(gt1151_i2c_driver);// 展开后和module_init module_exit一样,类似于module_platform_driver

MODULE_LICENSE("GPL");
MODULE_AUTHOR("kashine");



四、内核配置

1、IIC设备使能

首先使能IIC控制器和设备树对i2c设备的支持,使用make menuconfig命令打开图形化配置界面,打开以下路径的Marvell mv64xxx I2C Controller:

Device Drivers

        -> I2C support

                -> I2C Hardware Bus support

全志芯片使用的是marvell的i2c控制器(参考Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt),该选项默认处于使能状态。 

打开以下路径中的I2C device interface选项: 

Device Drivers

        -> I2C support

2、内核驱动添加

将上一节编写的驱动代码命名为gt1151.c,并放在linux-5.7.1/drivers/input/touchscreen目录下,如下图所示,可以看到touchscreen内有很多屏幕的适配驱动。其实gt1151官方也有适配的驱动,就是gt1151.c上方的goodix.c,这是汇顶触摸IC对应的gt系列驱动,那为什么我们还要自己编写呢?因为对于本文所用的硬件接线以及正点原子屏幕的定义,导致使用该驱动对正点原子屏幕的识别出错,得到的x、y坐标是反着的,因此需要对goodix.c进行修改,那就不如自己写喽。

 仅仅将驱动文件放到对应的文件夹下面并不可以,因为内核不知道有这么个tg1151驱动文件,我们需要在touchscreen文件夹下的Makfile进行修改,在最后方添加对gt1151.c的编译请求。

obj-$(CONFIG_TOUCHSCREEN_GT1151)	+= gt1151.o

我们都知道在make menuconfig图形化配置界面可以对驱动进行使能、关闭、编译为模块的配置,如果想要我们的gt1151驱动编译选项能够在make menuconfig调出的图形化配置界面中配置,还需要在touchscreen文件夹下的Kconfig文件中添加如下内容:

config TOUCHSCREEN_GT1151
	tristate "GT1151 touchscreen controller"
	depends on I2C
	
	help
	  Say Y to enable support for the GT1151
	  family of trackpad/touchscreen controllers.

	  To compile this driver as a module, choose M here: the
	  module will be called gt1151.

endif #非添加内容!!!

3、gt1151驱动使能

添加完驱动,并提供了图形化界面配置信息后,我们还要在make menuconfig提供的图形化配置界面中使能我们添加的gt1151驱动。如下图所示,我们需要使能GT1151 touchscreen controller选项(将驱动编译进内核),也就是我们上面添加的选项。

我们自定义了gt1151的驱动,因此goodix.c中的驱动我们就不需要了,所以在相同路径中,失能goodix驱动选项Goodix I2C touchscreen,如下图所示:


五、触摸测试

1、启动与文件检查

经过前几节的配置,我们重新对内核和设备树进行编译,然后上电运行开发板,查看输出信息,发现内核启动时先后加载了i2c驱动和gt1151驱动,并且初始化中断功能,Debian系统启动后直接进入root用户空间。注意:输出Driver and device has mached!!!代表设备树设备和驱动匹配成功,这是由驱动probe函数中的printk决定的!

下面这张图是我们在 “Debian根文件系统制作”这一小节中安装的一些组件,其中evtest是为本节安装的触摸屏测试软件,当时大家可能比较疑惑,现在我们使用该软件测试触摸屏触摸是否正常,当然大家也可以使用hexdump、tslib(非常直观,我移植了两天,宣告失败,有兴趣的尝试尝试,做出来记得@我,F1C200s下tslib移植到Debian文件系统哦)。

进入root用户空间后,首先查看路径/dev/input/event0、/dev/fb0中是否存在对应的文件,其中event0代表我们的电容触摸屏,不同的平台 event 序号不同,也可能是 event3,event4 等,一切以实际情况为准!我的是event0,如下图所示。

如果不存在event0,或者不存在input文件夹,首先检查/driver/input/touchscreen文件夹下面有没有产生gt1151.o文件,如果没有说明没有编译,检查Kconfig、Makfile、图形化配置使能如果有检查compatible属性值,或是检查启动log有无输出Driver and device has mached!!!

2、触摸测试

很幸运你能看到这里,应该庆幸欣慰,给你点赞👍👍👍👍👍👍。在顺利完成上述操作后,我们使用evtest软件对触摸屏进行测试,使用如下命令进入测试:

evtest /dev/input/event0

 从上面的图中可以看出,该软件正确识别到了我们的屏幕,分辨率为800*480,上报X坐标事件码为53,上报Y坐标事件码为54,现在我们来分别触摸屏幕的右下角、右上角、左下角、中间:

通过串口打印的坐标基本符合我们的触摸位置,至此,触摸IC驱动移植结束,恭喜完成本节,离offer又进一步! 🎉🎉🎉


六、主要参考内容

1.【f1c200s/f1c100s】FT5426触摸屏驱动适配_Liangtao`的博客-CSDN博客_ft5426

2. linux设备适配触摸屏(gt1151)_星星-点灯的博客-CSDN博客

3. 《正点原子驱动开发指南》


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kashine

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值