En 0755-86038900
行业动态

友坚UT4412BV02开发板电容触摸屏分析(二)

发布时间:2015-04-22

电容触摸屏调试要点:

1. 确定触摸ICI2C设备地址

2. 根据数据手册确定I2C设备数据读写函数是否符合时序

3. 确保I2C能正常通信上报坐标点。

4. 确定TP的固件规定的上报的xy坐标的最大值。

5. 调试上报给上层上报的数据

对于TP的调试,一般公司会要求TP原厂做多大的分辨率的TP固件,我接触到的这个TP是公司要求TP原厂做的固件为1280*800,并拿到了一份TP原厂给的TP源码,我的目的是让TP能够运用在UT4412BV02开发板上。

下面以笔者接触的GT928触摸屏为例分析触摸屏驱动。

1.首先确定TPUT4412BV02开发板的硬件连接。

 

从原理图的连接我们可以得到TP的控制IO
GPX0_4     -------------  CTP-INT

CTSn2_33 /SDA-------------GPA1_2

RTSn2_33 /SCL------------- GPA1_3

TP原厂代码分析

注:下面分析的代码为调试好的代码,并在原厂提供的代码的基础上精简了很多。以便于学习。由于篇幅幅有限,下面只分析重点部分。

 

static const struct i2c_device_id goodix_ts_id[] = {

    { GTP_I2C_NAME, 0 },//初始化设备ID

};

static struct i2c_driver goodix_ts_driver = { //i2c驱动结够体的填充

    .probe      = goodix_ts_probe,

    .remove     = goodix_ts_remove,

    .id_table   = goodix_ts_id,

    .driver = {

        .name     = GTP_I2C_NAME,

        .owner    = THIS_MODULE,

    },

};

static int __devinit goodix_ts_init(void)

    s32 ret;

    GTP_DEBUG_FUNC();   

    GTP_INFO("GTP driver installing...");

    goodix_wq = create_singlethread_workqueue("goodix_wq");

    if (!goodix_wq)

    {

        GTP_ERROR("Creat workqueue failed.");

        return -ENOMEM;

}

//I2C设备注册函数

    ret = i2c_add_driver(&goodix_ts_driver);

    return ret; 

}

//I2C设备探测的关键函数

static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)

{

    s32 ret = -1;

    struct goodix_ts_data *ts;

    u16 version_info;

    printk("-------ut_goodix_ts_probe------- ")

    //do NOT remove these logs

    GTP_INFO("GTP Driver Version: %s", GTP_DRIVER_VERSION);

    GTP_INFO("GTP Driver Built@%s, %s", __TIME__, __DATE__);

    GTP_INFO("GTP I2C Address: 0x%02x", client->addr);

    i2c_connect_client = client;

    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 

    {

        GTP_ERROR("I2C check functionality failed.");

        return -ENODEV;

    }

    ts = kzalloc(sizeof(*ts), GFP_KERNEL);

    if (ts == NULL)

    {

        GTP_ERROR("Alloc GFP_KERNEL memory failed.");

        return -ENOMEM;

    }

    memset(ts, 0, sizeof(*ts));

    INIT_WORK(&ts->work, goodix_ts_work_func);

    ts->client = client;

    spin_lock_init(&ts->irq_lock);          // 2.6.39 later

    i2c_set_clientdata(client, ts);

    ts->gtp_rawdiff_mode = 0;

    ret = gtp_request_io_port(ts);

    if (ret < 0)

    {

        GTP_ERROR("GTP request IO port failed.");

        kfree(ts);

        return ret;

    }

    ret = gtp_i2c_test(client);

    if (ret < 0)

    {

        GTP_ERROR("I2C communication ERROR!");

    }

 

    ret = gtp_read_version(client, &version_info);

    if (ret < 0)

    {

        GTP_ERROR("Read version failed.");

    }

    

   // ret = gtp_init_panel(ts);

  //  if (ret < 0)

   // {

     //   GTP_ERROR("GTP init panel failed.");

        ts->abs_x_max = GTP_MAX_WIDTH; //X上报的最大值

        ts->abs_y_max = GTP_MAX_HEIGHT;//Y上报的最大值

        ts->int_trigger_type = GTP_INT_TRIGGER;//中断的触发方式

   // }

    

    // Create proc file system

    gt91xx_config_proc = proc_create(GT91XX_CONFIG_PROC_FILE, 0666, NULL, &config_proc_ops);

    if (gt91xx_config_proc == NULL)

    {

        GTP_ERROR("create_proc_entry %s failed ", GT91XX_CONFIG_PROC_FILE);

    }

    else

    {

        GTP_INFO("create proc entry %s success", GT91XX_CONFIG_PROC_FILE);

    }

    

    ret = gtp_request_input_dev(ts);

    if (ret < 0)

    {

        GTP_ERROR("GTP request input dev failed");

    }

    

    ret = gtp_request_irq(ts); 

    if (ret < 0)

    {

        GTP_INFO("GTP works in polling mode.");

    }

    else

    {

        GTP_INFO("GTP works in interrupt mode.");

    }

 

    if (ts->use_irq)

    {

        gtp_irq_enable(ts);

    }

    return 0;

}

//当手指按下执行的上报坐标的函数。

static void gtp_touch_down(struct goodix_ts_data* ts,s32 id,s32 x,s32 y,s32 w)

{

 

    GTP_DEBUG("ID:%d, X:%d, Y:%d, W:%d", id, x, y, w);

#if GTP_ICS_SLOT_REPORT // 此宏为1

    input_mt_slot(ts->input_dev, id);

    input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id);

    input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);

input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);

调试过程中主要修改红色的两行代码来确定上报的xy的方向。

    input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);

    input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);

#else

    input_report_key(ts->input_dev, BTN_TOUCH, 1);

    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_TOUCH_MAJOR, w);

    input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);

    input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id);

    input_mt_sync(ts->input_dev);

#endif

}

了解更多的信息在友坚开发板官网:http://www.urbetter.net    http://www.urbetter.com.cn
更多问题请到友坚论坛进行发贴讨论:
http://bbs.urbetter.com