【摘要】 這篇文章介紹在Linux下如何編寫FT5X06系列芯片驅動,完成觸摸屏的驅動開發(fā), FT5X06是一個系列,當前使用的具體型號是FT5206,它是一個電容屏的觸摸芯片,內置了8位的單片機(8051內核),完成了坐標換算等很多處理,在通過IIC,SPI方式傳遞給外部單片機。
1. 前言
這篇文章介紹在Linux下如何編寫FT5X06系列芯片驅動,完成觸摸屏的驅動開發(fā), FT5X06是一個系列,當前使用的具體型號是FT5206,它是一個電容屏的觸摸芯片,內置了8位的單片機(8051內核),完成了坐標換算等很多處理,在通過IIC,SPI方式傳遞給外部單片機。
所說起觸摸屏大家都不會陌生,現在手機、手表、家電、很多地方都支持觸摸了。最開始的觸摸屏都是電阻屏,在諾基亞時代的時候,使用的觸摸屏都是電阻屏,后來Android興起的時候,手機都向電容屏發(fā)展了。電阻屏需要自己去校準,電阻屏的手機上都有這個功能,發(fā)現觸摸不靈敏之后,打開校準選項,根據屏幕上十字圖標指引,按順序點一下,完成坐標校準,電阻屏的屏幕還是軟材質,必須要手指去戳才可以完成控制,而且只能支持單點觸控?,F在電容屏就很方便了,只需要手指去觸摸屏即可完成操作,比電阻屏方便很多,還支持多點觸控,當初Android手機剛興起的時候,大街小巷的體驗店,廣告都是切水果游戲,切水果這個游戲就充分體驗了多點觸摸的效果,可以多個手指去切水果,當初這個游戲還是火爆的。
當前文章介紹的FT5206就是一顆電容屏的驅動芯片,最高支持2點觸控,可以通過獲取兩個坐標點,這個系列的芯片最高支持10點觸控。
當前使用的屏幕型號是S702,這個屏幕是友善之臂生產的LCD屏,S702這款屏幕采用的觸摸芯片就是FT5206,引出了IIC接口,支持筆中斷,官方的內核里也提供了例子驅動可以參考。
開發(fā)板與觸摸芯片的連線示例:
屏幕的實物圖詳情看下圖的介紹:
2. FT5206寄存器介紹
FT5206支持通過IIC和SPI接口與外部主機通信,當前使用的屏幕硬件上只是引出了IIC接口,下面就介紹下IIC接口的時序,設備地址,還有FT5206的寄存器。
IIC傳輸時序:
讀寫時序流程:
字段的解釋:
下面的截圖是介紹FT5206內部的寄存器地址,一些關鍵的地方我做了翻譯:
從圖上可以看出,基本上后面的寄存器地址都是重復的功能,只是坐標點不一樣了,其中的TOUCH2,TOUCH3…這些都是存放觸摸屏的坐標點的值。當前的FT5206只是支持2點觸控,所有就只能讀取兩個寄存器坐標的值。在前面第一個寄存器TD_STATUS里的低4位,存放了當前同時按下的點數量,可以將兩個手指按在屏幕上測試讀取的值。 這些寄存器里讀取的坐標值就是已經轉換過后的值,也就是屏幕坐標,不需要再進行二次轉換校準,非常方便。
3. 編寫觸摸屏驅動
Linux下編寫標準的觸摸屏驅動需要使用到輸入子系統(tǒng),當前文章的重點是讀取觸摸屏的坐標,所以示例代碼里不會加輸入子系統(tǒng)的代碼,只是在驅動層完成觸摸屏筆中斷響應,觸摸屏的坐標點獲取并打印。
驅動代碼里涉及的技術點有: IIC子系統(tǒng)、工作隊列、內核中斷等知識點。
這是開發(fā)板LCD屏幕的硬件原理圖:
3.1 設備端代碼(FT5206)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "FT5X06_DEV"
static struct i2c_adapter *iic_adapter;
static struct i2c_client *iic_client;
static struct i2c_board_info iic_info;
static int __init iic_dev_init(void)
{
/*1. 根據總線編號獲取IIC適配器結構體*/
iic_adapter=i2c_get_adapter(1);
/*2. 填充板級信息*/
iic_info.addr=0x38;
iic_info.irq=gpio_to_irq(EXYNOS4_GPX1(6));
strcpy(iic_info.type,DEVICE_NAME);
/*3. 注冊IIC設備端*/
iic_client=i2c_new_device(iic_adapter,&iic_info);
printk("IIC設備端驅動安裝成功.\n");
return 0;
}
static void __exit iic_dev_exit(void)
{
/*1. 完成設備端注銷*/
i2c_unregister_device(iic_client);
printk("IIC設備端驅動卸載成功.\n");
}
/*驅動的入口:insmod xxx.ko*/
module_init(iic_dev_init);
/*驅動的出口: rmmod xxx.ko*/
module_exit(iic_dev_exit);
/*模塊的許可證*/
MODULE_LICENSE("GPL");
/*模塊的作者*/
MODULE_AUTHOR("wbyq");
3.2 驅動端代碼
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static struct work_struct touch_work;
static struct i2c_client *touch_client;
/*工作函數*/
void tiny4412_touch_work_func(struct work_struct *work)
{
u8 touch_buff[7];
u16 x,y;
/*1. 讀取坐標數據*/
i2c_smbus_read_i2c_block_data(touch_client,0,7,touch_buff);
/*2. 打印數據*/
x=(touch_buff[3]&0xF)<<8|touch_buff[4];
y=(touch_buff[5]&0xF)<<8|touch_buff[6];
printk("x=%d,y=%d,p=%d\n",x,y,touch_buff[2]&0xF);
}
/*
中斷的服務函數
*/
irqreturn_t tiny4412_touch_irq_handler(int irq, void *dev)
{
/*調度工作: 將工作加入到工作隊列*/
schedule_work(&touch_work);
return IRQ_HANDLED;
}
static int iic_probe(struct i2c_client *client, const struct i2c_device_id *dev_id)
{
printk("設備地址:0x%X\n",client->addr);
printk("設備名稱:%s\n",client->name);
touch_client=client;
/*1. 初始化工作隊列*/
INIT_WORK(&touch_work,tiny4412_touch_work_func);
/*2. 注冊中斷*/
request_irq(client->irq,tiny4412_touch_irq_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,client->name,NULL);
return 0;
}
static int iic_remove(struct i2c_client *client)
{
/*1. 注銷中斷*/
free_irq(client->irq,NULL);
return 0;
}
static struct i2c_device_id iic_dev_id[]=
{
{"FT5X06_DEV",0},
{}
};
static struct i2c_driver iic_driver=
{
.probe=iic_probe,
.remove=iic_remove,
.driver=
{
.name="iic_driver"
},
.id_table=iic_dev_id
};
static int __init iic_drv_init(void)
{
/*1. 注冊IIC驅動端*/
i2c_add_driver(&iic_driver);
printk("驅動安裝成功.\n");
return 0;
}
static void __exit iic_drv_exit(void)
{
/*2. 注銷IIC驅動端*/
i2c_del_driver(&iic_driver);
printk("驅動卸載成功.\n");
}
/*驅動的入口:insmod xxx.ko*/
module_init(iic_drv_init);
/*驅動的出口: rmmod xxx.ko*/
module_exit(iic_drv_exit);
/*模塊的許可證*/
MODULE_LICENSE("GPL");
/*模塊的作者*/
MODULE_AUTHOR("wbyq");
-
觸摸屏
+關注
關注
42文章
2301瀏覽量
116117 -
驅動
+關注
關注
12文章
1838瀏覽量
85262 -
ft5x06
+關注
關注
0文章
2瀏覽量
4987
發(fā)布評論請先 登錄
相關推薦
評論