日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)

發布時間:2025/4/16 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是幾個月以前的東西了,在徹底遺忘之前拿出來好好寫寫。做個筆記,也算是造福后來人了。在做這個項目之前,沒有做過電容屏的驅動,印象中的電容觸摸屏是不需要校正的。IC支持多大的屏就要配多大的屏。但是拿到需求,發現要用FT5406做10寸屏,可是FT5406手冊上明明寫了,最大支持到8.9寸。由于經驗不足,感到略懵。就去核實這個需求方案是不是搞錯了?!得到的答案:藍魔的平板也是這個搭配。這樣, 那需求應該就沒問題了。先看現象再說:?

? ? ? ? ?硬件搭起來看現象,如下圖:

? ? ? ? ? 紅色區域是FT5406上報有效數據的范圍(1280*600),以左上角為原點 ,X軸方向上報數據的最大值1280,Y軸方向上報的最大數據是600.。但是我用的LG的10.1寸屏,分辨率為1366*768。若想把觸摸IC上報的數據和像素點的值一一對應起來,只能通過校正了。開始做校正的時候有點犯抽。竟然自己寫校正算法,代碼冗長不說,校準誤差也特別大。 還好,后來想起了tslib這個東西。tslib是專門為電阻屏設計的一個校正庫,只能校正單點觸摸數據。而FT5406是支持5點觸摸的。 不過只需要校正一點就可以了,這個點與其他四個點的上報數據的偏差大小無區別,只需要在驅動中做相同的消除偏差處理即可。思路有了,下面就從驅動開始說起:

1.?FT5406 在Linux 3.5 中的驅動要點----數據上報過程

FT5406是通過IIC總線同CPU進行數據交互的,內核中的驅動框架符合一個典型IIC設備驅動+輸入子系統(默認大家是了解IIC設備驅動和輸入子系統驅動的)。硬件I/O的初始化和寄存器配置就不在這里贅述了, 照著手冊來就可以了。重點看一下,數據上報過程,先看一個FT5406 原理圖(圖中標的是5206 ,沒關系接口是一樣的)::

? ??


原理圖上可以看到,用到了EINT14這根中斷線。通過這條中斷線,差不多就能猜到上報流程了吧:當用戶觸摸到觸摸板以后,產生中斷,在中斷服務程序中讀IIC。這樣就完成了一次數據的上報。下面就看看內核源碼的實現,先看一個流程圖:

? ? ? ??

中斷代碼實現如下:

[cpp]?view plaincopy
  • static?void?ft5x0x_ts_pen_irq_work(struct?work_struct?*work)?{?//底半部中斷??
  • ????struct?ft5x0x_ts_data?*ts?=?container_of(work,?struct?ft5x0x_ts_data,?work);??
  • ??
  • ????if?(!ft5x0x_read_data(ts))?{??
  • ????????ft5x0x_ts_report(ts);??
  • ????}??
  • ??
  • ????enable_irq(this_client->irq);??
  • }??
  • ??
  • static?irqreturn_t?ft5x0x_ts_interrupt(int?irq,?void?*dev_id)?{//頂半部中斷??
  • ????struct?ft5x0x_ts_data?*ts?=?dev_id;??
  • ??
  • ????disable_irq_nosync(this_client->irq);??
  • ??
  • ????if?(!work_pending(&ts->work))?{??
  • ????????queue_work(ts->queue,?&ts->work);??
  • ????}??
  • ??
  • ????return?IRQ_HANDLED;??
  • }??

  • 從IC中讀取觸摸數據:

    [cpp]?view plaincopy
  • static?int?ft5x0x_read_data(struct?ft5x0x_ts_data?*ts)?{??
  • ????struct?ft5x0x_event?*event?=?&ts->event;??
  • ????u8?buf[32]?=?{?0?};??
  • ????int?ret;??
  • ??
  • #ifdef?CONFIG_FT5X0X_MULTITOUCH??
  • ????ret?=?ft5x0x_i2c_rxdata(buf,?31);??
  • #else??
  • ????ret?=?ft5x0x_i2c_rxdata(buf,?7);??
  • #endif??
  • ????if?(ret?<?0)?{??
  • ????????printk("%s:?read?touch?data?failed,?%d\n",?__func__,?ret);??
  • ????????return?ret;??
  • ????}??
  • ??
  • ????memset(event,?0,?sizeof(struct?ft5x0x_event));??
  • ??
  • ????event->touch_point?=?buf[2]?&?0x07;??
  • ??
  • ????if?(!event->touch_point)?{??
  • ????????ft5x0x_ts_release(ts);??
  • ????????return?1;??
  • ????}??
  • ??
  • #ifdef?CONFIG_FT5X0X_MULTITOUCH??
  • ????switch?(event->touch_point)?{??
  • ????????case?5:??
  • ????????????event->x[4]?=?(s16)(buf[0x1b]?&?0x0F)<<8?|?(s16)buf[0x1c];??
  • ????????????event->y[4]?=?(s16)(buf[0x1d]?&?0x0F)<<8?|?(s16)buf[0x1e];??
  • ????????case?4:??
  • ????????????event->x[3]?=?(s16)(buf[0x15]?&?0x0F)<<8?|?(s16)buf[0x16];??
  • ????????????event->y[3]?=?(s16)(buf[0x17]?&?0x0F)<<8?|?(s16)buf[0x18];??
  • ????????case?3:??
  • ????????????event->x[2]?=?(s16)(buf[0x0f]?&?0x0F)<<8?|?(s16)buf[0x10];??
  • ????????????event->y[2]?=?(s16)(buf[0x11]?&?0x0F)<<8?|?(s16)buf[0x12];??
  • ????????case?2:??
  • ????????????event->x[1]?=?(s16)(buf[0x09]?&?0x0F)<<8?|?(s16)buf[0x0a];??
  • ????????????event->y[1]?=?(s16)(buf[0x0b]?&?0x0F)<<8?|?(s16)buf[0x0c];??
  • ????????case?1:??
  • ????????????event->x[0]?=?(s16)(buf[0x03]?&?0x0F)<<8?|?(s16)buf[0x04];??
  • ????????????event->y[0]?=?(s16)(buf[0x05]?&?0x0F)<<8?|?(s16)buf[0x06];??
  • ????????????break;??
  • ????????default:??
  • ????????????printk("%s:?invalid?touch?data,?%d\n",?__func__,?event->touch_point);??
  • ????????????return?-1;??
  • ????}??
  • #else??
  • ????if?(event->touch_point?==?1)?{??
  • ????????event->x[0]?=?(s16)(buf[0x03]?&?0x0F)<<8?|?(s16)buf[0x04];??
  • ????????event->y[0]?=?(s16)(buf[0x05]?&?0x0F)<<8?|?(s16)buf[0x06];??
  • ????}??
  • #endif??
  • ??
  • ????event->pressure?=?200;??
  • ??
  • ????return?0;??
  • }??

  • 上報過程代碼:

    [cpp]?view plaincopy
  • static?void?ft5x0x_ts_report(struct?ft5x0x_ts_data?*ts)?{??
  • ????struct?ft5x0x_event?*event?=?&ts->event;??
  • ????int?x,?y;??
  • ????int?i;??
  • ??
  • #ifdef?CONFIG_FT5X0X_MULTITOUCH??
  • ????for?(i?=?0;?i?<?event->touch_point;?i++)?{??
  • ????????if?(swap_xy)?{??
  • ????????????x?=?event->y[i];??
  • ????????????y?=?event->x[i];??
  • ????????}?else?{??
  • ????????????x?=?event->x[i];??
  • ????????????y?=?event->y[i];??
  • ????????}??
  • ??
  • ????????if?(scal_xy)?{??
  • ????????????x?=?(x?*?ts->screen_max_x)?/?TOUCH_MAX_X;??
  • ????????????y?=?(y?*?ts->screen_max_y)?/?TOUCH_MAX_Y;??
  • ????????}??
  • ??
  • ????????input_report_abs(ts->input_dev,?ABS_MT_POSITION_X,?x);??
  • ????????input_report_abs(ts->input_dev,?ABS_MT_POSITION_Y,?y);??
  • ??
  • ????????input_report_abs(ts->input_dev,?ABS_MT_PRESSURE,?event->pressure);??
  • ????????input_report_abs(ts->input_dev,?ABS_MT_TOUCH_MAJOR,?event->pressure);??
  • ????????input_report_abs(ts->input_dev,?ABS_MT_TRACKING_ID,?i);??
  • ??
  • ????????input_mt_sync(ts->input_dev);??
  • ????}??
  • #else??
  • ????if?(event->touch_point?==?1)?{??
  • ????????if?(swap_xy)?{??
  • ????????????x?=?event->y[i];??
  • ????????????y?=?event->x[i];??
  • ????????}?else?{??
  • ????????????x?=?event->x[i];??
  • ????????????y?=?event->y[i];??
  • ????????}??
  • ??
  • ????????if?(scal_xy)?{??
  • ????????????x?=?(x?*?ts->screen_max_x)?/?TOUCH_MAX_X;??
  • ????????????y?=?(y?*?ts->screen_max_y)?/?TOUCH_MAX_Y;??
  • ????????}??
  • ??
  • ????????input_report_abs(ts->input_dev,?ABS_X,?x);??
  • ????????input_report_abs(ts->input_dev,?ABS_Y,?y);??
  • ????????input_report_abs(ts->input_dev,?ABS_PRESSURE,?event->pressure);??
  • ????}??
  • ??
  • ????input_report_key(ts->input_dev,?BTN_TOUCH,?1);??
  • #endif??
  • ??
  • ????input_sync(ts->input_dev);??
  • }??

  • IC驅動的大致工作流程就是這樣的,下面就來看看該怎么去做校正:

    一、這個電容屏是往exynos4412 核心 Android4.2設備上移植的,所以第一步要做的是往Anroid移植TSlib1.4庫。簡述移植過程

    1.生成configure

    ??./autogen.sh

    ?安裝tslib中遇到的錯誤:./autogen.sh: 4: autoreconf: not found

    ??是因為在不同版本的?tslib?下執行?autogen.sh?產生。它們產生的原因一樣,

    ?因為沒有安裝? automake?工具,? (ubuntu 13.10)用下面的命令安裝好就可以了。

    ?sudo apt-get install autoconf automake libtool

    2./configure --host=交叉編譯器路徑(注意要用對應Android平臺自帶的bionic c編譯器而不是配套開發板的GNU C編譯器)

    ?? ?ac_cv_func_malloc_0_nonnull=yes -static?

    在tslib/config.h文件中加入如下定義:
    #define TS_CONF? "/system/etc/ts.conf"
    #define PLUGIN_DIR "/system/lib"
    #define TS_POINTERCAL "/data/etc/pointercal"


    另外由于bionic c 和GNU c的差異,需要修改幾個tslib的頭文件編譯才能通過 將下面路徑文件
    tslib/src/ts_open.c
    tslib/tests/ts_calibrate.c
    tslib/tests/fbutils.c
    中的
    #include <sys/fcntl.h>
    修改成
    #include <fcntl.h>

    將tslib/tests/ts_calibrate.c文件中
    static int clearbuf(struct tsdev *ts)
    修改為
    static void clearbuf(struct tsdev *ts)


    如果使用GNU C編譯器在android shell下運行ts_calibrate會出現如下錯誤:

    ?sh: ./system/bin/ts_calibrate: No such file or directory


    ?3.編譯make



    ?etc/ts.conf?的參考配置:

    修改tslib/etc/ts.conf內容如下:
    module_raw input
    module pthres pmin=1
    module variance delta=30
    module dejitter delta=100
    module linear

    4.在android源代碼init.rc中聲明tslib相關環境變量如下:

    # touchscreen parameters
    ??? export TSLIB_FBDEVICE /dev/graphics/fb0
    ??? export TSLIB_CALIBFILE /data/etc/pointercal
    ??? export TSLIB_CONFFILE? /system/etc/ts.conf
    ??? export TSLIB_TRIGGERDEV /dev/input/event0
    ??? export TSLIB_TSDEVICE /dev/input/event1

    ?

    ?5.??????將/src/.lib 中生成的庫文件,分別全部拷貝開發板的根文件系統對應/system/lib 目錄中,將tests目錄中的ts_calibrate cp到system/bin中

    到此完成對tslib的移植。

    在運行ts_calibrate前首先要取消內核對多點觸摸的支持,因為tslib只能處理單點的數據格式,而且單點的數據,必須要滿足以下上報順尋:

    ?input_report_abs(ts->input_dev, ABS_X, x);
    ? ? ? ? ? ? ? ? input_report_abs(ts->input_dev, ABS_Y, y);
    ? ? ? ? ? ? ? ? input_report_abs(ts->input_dev, ABS_PRESSURE, event->pressure);

    通過運行ts_calibrate,獲得校正參數,存放在/data?目錄下的pointercal文件中

    最后要做的就是修改內核驅動?/drivers/input/touchscreen/ft5x06_ts.c,添加校正算法(如下)并添加獲得的校正參數(紅色標注即為獲得的校正參數)。如下:

    [cpp]?view plaincopy
  • #ifdef?CONFIG_INPUT_TS_LINEAR??
  • static?int?ts_linear_scale(int?*x,?int?*y,?int?swap_xy)??
  • {??
  • ????????int?xtemp,?ytemp;??
  • ????????int?a[7]?=?{<span?style="color:?rgb(255,?0,?0);">87701,-382,-420352,-89,84218,-936128,65536</span>};??
  • ????????xtemp?=?*x;??
  • ????????ytemp?=?*y;??
  • ??
  • ????????if?(a[6]?==?0)??
  • ????????????return?-EINVAL;??
  • ??
  • ????????*x?=?(a[2]?+?a[0]?*?xtemp?+?a[1]?*?ytemp)?/?a[6];??
  • ????????*y?=?(a[5]?+?a[3]?*?xtemp?+?a[4]?*?ytemp)?/?a[6];??
  • ??
  • ????????if?(swap_xy)?{??
  • ????????????????int?tmp?=?*x;??
  • ????????????????*x?=?*y;??
  • ????????????????*y?=?tmp;??
  • ????????}??
  • ????????return?0;??
  • }??
  • #endif??

  • static void ft5x0x_ts_report(struct ft5x0x_ts_data *ts) {
    ? ? ? ? struct ft5x0x_event *event = &ts->event;
    ? ? ? ? int x, y;
    ? ? ? ? int i;


    #ifdef CONFIG_FT5X0X_MULTITOUCH
    ? ? ? ? for (i = 0; i < event->touch_point; i++) {
    ? ? ? ? ? ? ? ? if (swap_xy) {
    ? ? ? ? ? ? ? ? ? ? ? ? x = event->y[i];
    ? ? ? ? ? ? ? ? ? ? ? ? y = event->x[i];
    ? ? ? ? ? ? ? ? } else {
    ? ? ? ? ? ? ? ? ? ? ? ? x = event->x[i];
    ? ? ? ? ? ? ? ? ? ? ? ? y = event->y[i];
    ? ? ? ? ? ? ? ? }


    ? ? ? ? ? ? ? ? if (scal_xy) {
    ? ? ? ? ? ? ? ? ? ? ? ? x = (x * ts->screen_max_x) / TOUCH_MAX_X;
    ? ? ? ? ? ? ? ? ? ? ? ? y = (y * ts->screen_max_y) / TOUCH_MAX_Y;
    ? ? ? ? ? ? ? ? }
    #ifdef CONFIG_INPUT_TS_LINEAR
    ? ? ? ? ? ? ? ??ts_linear_scale(&x, &y, swap_xy);
    #endif

    在上報過程 首先通過static int ts_linear_scale(int *x, int *y, int swap_xy)函數將從IC獲得的觸摸點坐標消除偏差。

    總結

    以上是生活随笔為你收集整理的FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。