CSDN僅用于增加百度收錄權重,排版未優化,日常不維護。請通路:www.hceng.cn 檢視、評論。
本博文對應位址: https://hceng.cn/2017/12/26/Exynos4412——觸摸屏驅動/#more
移植Exynos4412的I2C接口觸摸屏驅動。
這應該是Exynos4412 LCD部分的最後一部分了。
為了去探索LCD驅動,前面做了一系列的準備工作,最後終于完成了LCD驅動,現在隻剩下觸摸屏這個最後的“尾巴”。
1.工作原理
前面LCD之backligth部分說了,友善之臂這個屏,為了改善大尺寸四線電阻觸摸屏的性能,外加了一個低成本的MCU去控制專業的觸控晶片,将濾波後的穩定資料通過GPIO傳回到ARM上。
但我的闆子LCD是電容屏,查閱相關資料後得知,是通過一個FT5406觸摸屏晶片實作的電容觸摸功能。
根據FT5x06.pdf手冊可得知其工作的架構:
當觸摸屏上發生觸摸操作時,通過TXn(Transmit output pin)和RXn(Receiver input pins)傳輸給FT5406,FT5406經過處理後,将坐标資訊通過Serial Interface(I2C or SPI)發給Host(開發闆)。
查閱FT5x06.pdf,可以看到FT5x06對外有如下接口:
I2C/SPI:與主機進行資料交換的接口
INT:中斷信号接口,通知主處理器觸摸資料準備好讀取
WAKE:主機将FT5x06從休眠模式切換到主動模式的中斷信号
RST:外部低電平信号複位晶片
是以,開發闆至少的有I2C/SPI和INT與FT5x06相連。
2.原理圖
- Tiny4412-1412-Schematic.pdf: I2C使用I2C1,INT使用GPX1_6引腳。
- Tiny4412SDK-1506-Schematic.pdf: 在底闆上經過一次電平轉換引出到LCD1接口上。
- LCD-S702-1509.pdf:
LCD上并沒有FT5x06的相關資訊,隻提供了一個CON5接口。
友善之臂封裝好了LCD和觸摸屏,對外隻提供I2C接口。
對于驅動來說,觸摸屏就是一個帶中斷的信号的I2C裝置。
3. 裝置樹檔案
ft5406 作為 i2c_1 的子節點。
&i2c_1 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-max-bus-freq = <400000>;
status = "okay";
polytouch: [email protected] {
compatible = "edt,edt-ft5406", "edt,edt-ft5x06";
reg = <0x38>;
interrupt-parent = <&gpx1>;
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
touchscreen-size-x = <800>;
touchscreen-size-y = <480>;
};
};
核心已經有了ft5x06驅動,所有對應的也會有裝置樹的描述檔案:
linux-4.13.9/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
linux-4.13.9/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
詳細介紹了裝置樹的必要參數和非必要參數。
4. 驅動程式
核心中ft5x06驅動所在路徑:
linux-4.13.9/drivers/input/touchscreen/edt-ft5x06.c
這塊的内容,暫時不想分析,涉及I2C子系統和輸入子系統,回頭再慢慢分析。
5. 測試程式
{% codeblock lang:c [app.c] https://github.com/hceng/learn/blob/master/tiny4412/03_touchscreen/app.c %}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
int main()
{
int keys_fd;
char ret[2];
struct input_event t;
keys_fd = open("/dev/input/event0", O_RDONLY); //打開TP裝置
if(keys_fd<=0){
printf("open /dev/input/event0 device error!\n");
return 0;
}
while(1)
{
if(read(keys_fd, &t, sizeof(t))==sizeof(t))
{
if (t.type == EV_KEY)
{
printf(" type: EV_KEY, event = %s, value = %d \r\n",
t.code == BTN_TOUCH ? "BTN_TOUCH" : "Unkown", t.value);
}
else if(t.type == EV_ABS)
{
printf(" type: EV_ABS, event = %s, value = %d \r\n",
t.code == ABS_X ? "ABS_X" :
t.code == ABS_Y ? "ABS_Y" :
t.code == ABS_PRESSURE ? "ABS_PRESSURE" :"Unkown", t.value);
}
}
}
close(keys_fd);
return 0;
}
{% endcodeblock %}
參考部落格:Linux和android下測試鍵盤和觸摸屏