欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
FT5X06 如何應用在10寸電容屏(linux

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

         硬件搭起來(lái)看現象,如下圖:

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

1. FT5406 在Linux 3.5 中的驅動(dòng)要點(diǎn)----數據上報過(guò)程

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

    


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

        

中斷代碼實(shí)現如下:

  1. static void ft5x0x_ts_pen_irq_work(struct work_struct *work) { //底半部中斷
  2. struct ft5x0x_ts_data *ts = container_of(work, struct ft5x0x_ts_data, work);
  3. if (!ft5x0x_read_data(ts)) {
  4. ft5x0x_ts_report(ts);
  5. }
  6. enable_irq(this_client->irq);
  7. }
  8. static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id) {//頂半部中斷
  9. struct ft5x0x_ts_data *ts = dev_id;
  10. disable_irq_nosync(this_client->irq);
  11. if (!work_pending(&ts->work)) {
  12. queue_work(ts->queue, &ts->work);
  13. }
  14. return IRQ_HANDLED;
  15. }

從IC中讀取觸摸數據:

  1. static int ft5x0x_read_data(struct ft5x0x_ts_data *ts) {
  2. struct ft5x0x_event *event = &ts->event;
  3. u8 buf[32] = { 0 };
  4. int ret;
  5. #ifdef CONFIG_FT5X0X_MULTITOUCH
  6. ret = ft5x0x_i2c_rxdata(buf, 31);
  7. #else
  8. ret = ft5x0x_i2c_rxdata(buf, 7);
  9. #endif
  10. if (ret < 0) {
  11. printk("%s: read touch data failed, %d\n", __func__, ret);
  12. return ret;
  13. }
  14. memset(event, 0, sizeof(struct ft5x0x_event));
  15. event->touch_point = buf[2] & 0x07;
  16. if (!event->touch_point) {
  17. ft5x0x_ts_release(ts);
  18. return 1;
  19. }
  20. #ifdef CONFIG_FT5X0X_MULTITOUCH
  21. switch (event->touch_point) {
  22. case 5:
  23. event->x[4] = (s16)(buf[0x1b] & 0x0F)<<8 | (s16)buf[0x1c];
  24. event->y[4] = (s16)(buf[0x1d] & 0x0F)<<8 | (s16)buf[0x1e];
  25. case 4:
  26. event->x[3] = (s16)(buf[0x15] & 0x0F)<<8 | (s16)buf[0x16];
  27. event->y[3] = (s16)(buf[0x17] & 0x0F)<<8 | (s16)buf[0x18];
  28. case 3:
  29. event->x[2] = (s16)(buf[0x0f] & 0x0F)<<8 | (s16)buf[0x10];
  30. event->y[2] = (s16)(buf[0x11] & 0x0F)<<8 | (s16)buf[0x12];
  31. case 2:
  32. event->x[1] = (s16)(buf[0x09] & 0x0F)<<8 | (s16)buf[0x0a];
  33. event->y[1] = (s16)(buf[0x0b] & 0x0F)<<8 | (s16)buf[0x0c];
  34. case 1:
  35. event->x[0] = (s16)(buf[0x03] & 0x0F)<<8 | (s16)buf[0x04];
  36. event->y[0] = (s16)(buf[0x05] & 0x0F)<<8 | (s16)buf[0x06];
  37. break;
  38. default:
  39. printk("%s: invalid touch data, %d\n", __func__, event->touch_point);
  40. return -1;
  41. }
  42. #else
  43. if (event->touch_point == 1) {
  44. event->x[0] = (s16)(buf[0x03] & 0x0F)<<8 | (s16)buf[0x04];
  45. event->y[0] = (s16)(buf[0x05] & 0x0F)<<8 | (s16)buf[0x06];
  46. }
  47. #endif
  48. event->pressure = 200;
  49. return 0;
  50. }

上報過(guò)程代碼:

  1. static void ft5x0x_ts_report(struct ft5x0x_ts_data *ts) {
  2. struct ft5x0x_event *event = &ts->event;
  3. int x, y;
  4. int i;
  5. #ifdef CONFIG_FT5X0X_MULTITOUCH
  6. for (i = 0; i < event->touch_point; i++) {
  7. if (swap_xy) {
  8. x = event->y[i];
  9. y = event->x[i];
  10. } else {
  11. x = event->x[i];
  12. y = event->y[i];
  13. }
  14. if (scal_xy) {
  15. x = (x * ts->screen_max_x) / TOUCH_MAX_X;
  16. y = (y * ts->screen_max_y) / TOUCH_MAX_Y;
  17. }
  18. input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
  19. input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
  20. input_report_abs(ts->input_dev, ABS_MT_PRESSURE, event->pressure);
  21. input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
  22. input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i);
  23. input_mt_sync(ts->input_dev);
  24. }
  25. #else
  26. if (event->touch_point == 1) {
  27. if (swap_xy) {
  28. x = event->y[i];
  29. y = event->x[i];
  30. } else {
  31. x = event->x[i];
  32. y = event->y[i];
  33. }
  34. if (scal_xy) {
  35. x = (x * ts->screen_max_x) / TOUCH_MAX_X;
  36. y = (y * ts->screen_max_y) / TOUCH_MAX_Y;
  37. }
  38. input_report_abs(ts->input_dev, ABS_X, x);
  39. input_report_abs(ts->input_dev, ABS_Y, y);
  40. input_report_abs(ts->input_dev, ABS_PRESSURE, event->pressure);
  41. }
  42. input_report_key(ts->input_dev, BTN_TOUCH, 1);
  43. #endif
  44. input_sync(ts->input_dev);
  45. }

IC驅動(dòng)的大致工作流程就是這樣的,下面就來(lái)看看該怎么去做校正:

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

1.生成configure

  ./autogen.sh

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

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

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

 sudo apt-get install autoconf automake libtool

2./configure --host=交叉編譯器路徑(注意要用對應android平臺自帶的bionic c編譯器而不是配套開(kāi)發(fā)板的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的差異,需要修改幾個(gè)tslib的頭文件編譯才能通過(guò)
將下面路徑文件
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會(huì )出現如下錯誤:

 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相關(guān)環(huán)境變量如下:

# 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 中生成的庫文件,分別全部拷貝開(kāi)發(fā)板的根文件系統對應/system/lib 目錄中,將tests目錄中的ts_calibrate cp到system/bin中

到此完成對tslib的移植。

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

 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);

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

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

  1. #ifdef CONFIG_INPUT_TS_LINEAR
  2. static int ts_linear_scale(int *x, int *y, int swap_xy)
  3. {
  4. int xtemp, ytemp;
  5. int a[7] = {87701,-382,-420352,-89,84218,-936128,65536};
  6. xtemp = *x;
  7. ytemp = *y;
  8. if (a[6] == 0)
  9. return -EINVAL;
  10. *x = (a[2] + a[0] * xtemp + a[1] * ytemp) / a[6];
  11. *y = (a[5] + a[3] * xtemp + a[4] * ytemp) / a[6];
  12. if (swap_xy) {
  13. int tmp = *x;
  14. *x = *y;
  15. *y = tmp;
  16. }
  17. return 0;
  18. }
  19. #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

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


本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
tslib 1.4 在A(yíng)RM板上移植
tslib-1.4的交叉編譯安裝
tslib-1.4在OMAP3530(Cortex-A8)上的移植過(guò)程詳解
Linux驅動(dòng)開(kāi)發(fā)|電容觸摸屏
基于s3c2410的tslib1.4的編譯與移植
移植觸摸屏校正Tslib1.4
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久