主题 : Mini6410+i2c電容屏…畫幾秒後不動了… 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 52843
精华: 0
发帖: 14
金钱: 70 两
威望: 14 点
综合积分: 28 分
注册时间: 2011-07-26
最后登录: 2017-09-13
楼主  发表于: 2011-09-15 17:49

 Mini6410+i2c電容屏…畫幾秒後不動了…

參考如下網址修改成mini6410+電容屏驅動
可畫線,但畫幾秒後就不動了,在不動的瞬間去量測外部中斷訊號
發現其因為等不到SCL、SDA寫入、接收,所以一直維持在0準位
若將外部中斷訊號重插拔,即恢復高準位,但畫個幾秒又不動了…

嘗試在程試碼中的err 0、err 1、err 2的開頭各加入以下訊息,試圖找出錯誤點
但電容屏不動時,超級終端皆無錯誤訊息
dev_err(&client->dev, " err 0.\n");
dev_err(&client->dev, " err 1.\n");
dev_err(&client->dev, " err 2.\n");


煩請高手解惑~~

參考網址:
http://www.lupaworld.com/home.php?mod=space&uid=273398&do=blog&id=149486
//-------------------------------------------------------------------//
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <linux/i2c.h>
#include <linux/timer.h>
#include <linux/delay.h>

/*resolution definion according to touch screen */
#define MIN_X_COORDINATE    0
#define MAX_X_COORDINATE    1024    
#define MIN_Y_COORDINATE    0
#define MAX_Y_COORDINATE    768

/* touch screen data structure */
struct i2c_ts_priv {
    struct i2c_client *client;
    struct input_dev *input;
    struct delayed_work work;
    int irq;
};

static void i2c_ts_poscheck(struct work_struct *work)
{
    struct i2c_ts_priv *priv = container_of(work, struct i2c_ts_priv, work.work);
    /* buffer for storing data */
    char buf[6];
    int number;
    int xpos, ypos;

    memset(buf, 0, sizeof(buf));

    /* Now do Page Read */
    if (i2c_master_recv(priv->client, buf,6) != 6) {
        dev_err(&priv->client->dev, "Unable to read i2c page\n");
        goto out;
    }
        
    /* convert coordinate */
    number = buf[0]&0x07;
    xpos = ((buf[3] << 8) | buf[2]);
    ypos = ((buf[5] << 8) | buf[4]);
    
     /* report input event */
    if ((number != 0) && (xpos != 0) && (ypos != 0)) {
        input_report_key(priv->input, BTN_TOUCH, 1);
        input_report_abs(priv->input, ABS_X, xpos);
        input_report_abs(priv->input, ABS_Y, ypos);
        input_sync(priv->input);
    } else if (number == 0) {
        input_report_key(priv->input, BTN_TOUCH, 0);
        input_sync(priv->input);
    }

out:
    enable_irq(priv->irq);
}

/* read finger numbers and coordinate and report input event */
static irqreturn_t i2c_ts_isr(int irq, void *dev_id)
{
    struct i2c_ts_priv *priv = dev_id;
      
    /* disable irq */
    disable_irq_nosync(irq);
    schedule_delayed_work(&priv->work, HZ/100);    
    return IRQ_HANDLED;
}


static int i2c_ts_open(struct input_dev *dev)
{
    return 0;
}

static void i2c_ts_close(struct input_dev *dev)
{

}

static int i2c_ts_probe(struct i2c_client *client,
              const struct i2c_device_id *idp)
{
    struct i2c_ts_priv *priv;
    struct input_dev *input;
    int error;
    char buf[2];    

    priv = kzalloc(sizeof(*priv), GFP_KERNEL);
    if (!priv) {
        dev_err(&client->dev, "failed to allocate driver data\n");
        error = -ENOMEM;
        goto err0;
    }

    dev_set_drvdata(&client->dev, priv);

    input = input_allocate_device();
    if (!input) {
        dev_err(&client->dev, "Failed to allocate input device.\n");
        error = -ENOMEM;
        goto err1;
    }

    input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
    input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

    input_set_abs_params(input, ABS_X, MIN_X_COORDINATE, MAX_X_COORDINATE, 0, 0);
    input_set_abs_params(input, ABS_Y, MIN_Y_COORDINATE, MAX_Y_COORDINATE, 0, 0);

    input->name = client->name;
    input->id.bustype = BUS_I2C;
    input->dev.parent = &client->dev;

    input->open = i2c_ts_open;
    input->close = i2c_ts_close;

    input_set_drvdata(input, priv);

    priv->client = client;
    priv->input = input;
    INIT_DELAYED_WORK(&priv->work, i2c_ts_poscheck);
    priv->irq = client->irq;

    error = input_register_device(input);
    if (error)
        goto err1;

    error = request_irq(priv->irq, i2c_ts_isr, IRQF_TRIGGER_FALLING,
                client->name, priv);
    if (error) {
        dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
        goto err2;
    }

    device_init_wakeup(&client->dev,1);
    
    return 0;

err2:
    input_unregister_device(input);
    input = NULL; /* so we dont try to free it below */
err1:
    input_free_device(input);
    kfree(priv);
err0:
    dev_set_drvdata(&client->dev, NULL);
    return error;
}

static int i2c_ts_remove(struct i2c_client *client)
{
    struct i2c_ts_priv *priv = dev_get_drvdata(&client->dev);

    free_irq(priv->irq, priv);
    input_unregister_device(priv->input);
    kfree(priv);

    dev_set_drvdata(&client->dev, NULL);

    return 0;
}

static int i2c_ts_suspend(struct i2c_client *client, pm_message_t mesg)
{
    struct i2c_ts_priv *priv = dev_get_drvdata(&client->dev);
    if(device_may_wakeup(&client->dev))
    enable_irq_wake(priv->irq);
    return 0;
}

static int i2c_ts_resume(struct i2c_client *client)
{
    struct i2c_ts_priv *priv = dev_get_drvdata(&client->dev);
    if(device_may_wakeup(&client->dev))
    disable_irq_wake(priv->irq);
    return 0;
}

static const struct i2c_device_id i2c_ts_id[] = {
    { "i2c-ts", 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, i2c_ts_id);

static struct i2c_driver i2c_ts_driver = {
    .driver = {
        .name = "i2c-ts",
    },
    .probe = i2c_ts_probe,
    .remove = i2c_ts_remove,
    .suspend = i2c_ts_suspend,
    .resume = i2c_ts_resume,
    .id_table = i2c_ts_id,
};

static int __init i2c_ts_init(void)
{
    return i2c_add_driver(&i2c_ts_driver);
}

static void __exit i2c_ts_exit(void)
{
    i2c_del_driver(&i2c_ts_driver);
}

MODULE_DESCRIPTION("i2c Touchscreen driver");
MODULE_AUTHOR("ALlen <allen.p.wang@gmail.com>");
MODULE_LICENSE("GPL");

module_init(i2c_ts_init);
module_exit(i2c_ts_exit);
级别: 新手上路
UID: 22263
精华: 0
发帖: 8
金钱: 40 两
威望: 8 点
综合积分: 16 分
注册时间: 2010-05-29
最后登录: 2015-04-15
1楼  发表于: 2011-10-03 23:21
看看外部引脚上拉电阻多大最好为4.7K 太大可能导致I2C 总线锁死
级别: 侠客
UID: 12401
精华: 0
发帖: 96
金钱: 500 两
威望: 100 点
综合积分: 192 分
注册时间: 2010-01-06
最后登录: 2017-09-13
2楼  发表于: 2012-02-25 17:24
我也遇到这个问题,原来以为是驱动上出了问题,结果按楼上的兄弟把上拉改成4.7K就解决了,浪费我一个星期的时间了。友善在IIC上拉电阻原先是10K。建议友善以后要改BOM,改成4.7K的,否则还会有兄弟遇到这种奇怪问题。
级别: 新手上路
UID: 68174
精华: 0
发帖: 29
金钱: 145 两
威望: 29 点
综合积分: 58 分
注册时间: 2012-04-19
最后登录: 2013-03-04
3楼  发表于: 2012-07-30 21:16

 回 楼主(ele1325) 的帖子

楼主好,请问驱动程序还需要修改别的什么地方啊?