yixuaning 发表于 2013-12-03 21:39

I2C总线上的RTC驱动(HT1382)问题求助

static int ht1382_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
        unsigned char buf = { 0x00 };
        struct i2c_msg msgs[] = {
                {
                        .addr = client->addr,
                        .flags = 0,
                        .len = 1,
                        .buf = buf,
                }, {
                        .addr = client->addr,
                        .flags = I2C_M_RD,
                        .len = sizeof(buf),
                        .buf = buf,
                }
        };

        /* read registers */
        if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
                dev_err(&client->dev, "%s: read error\n", __func__);
                return -EIO;
        }
       

        tm->tm_year   = bcd2bin((buf>>4)*10 + (buf&0x0f) + ORIGINYEAR);
        tm->tm_year   -=1900;
        tm->tm_wday   = bcd2bin(buf&0x0f);
        tm->tm_mon    = bcd2bin((buf>>4)*10+ (buf&0x0f));
        tm->tm_mon    -= 1;
        tm->tm_mday   = bcd2bin((buf>>4)*10+ (buf&0x0f));
        tm->tm_hour   = bcd2bin((buf>>4)*10 + (buf&0x0f));
        tm->tm_min    = bcd2bin(((buf&0x7f)>>4)*10+ (buf&0x0f));
        tm->tm_sec    = bcd2bin(((buf&0x7f)>>4)*10+ (buf&0x0f));
        if (rtc_valid_tm(tm) < 0)
                dev_err(&client->dev, "retrieved date/time is not valid.\n");

        return 0;

}

static int ht1382_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
        unsigned char buf = { 0x00 };
        int i,err;

        dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
                "mday=%d, mon=%d, year=%d, wday=%d\n",
                __func__,
                tm->tm_sec, tm->tm_min, tm->tm_hour,
                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

        buf        = bin2bcd(tm->tm_sec);
        buf        = bin2bcd(tm->tm_min);
        buf        = bin2bcd(tm->tm_hour);
        buf        = bin2bcd(tm->tm_mday);
        buf        = bin2bcd(tm->tm_mon + 1);
        buf        = bin2bcd(tm->tm_wday & 0x07);
        buf        = bin2bcd(tm->tm_wday + 1900);

        /* write register's data */
        for (i = 0; i < 7; i++) {
                unsigned char data = { HT1382_REG_SC + i, buf };

                err = i2c_master_send(client, data, sizeof(data));
                if (err != sizeof(data)) {
                        dev_err(&client->dev,
                                "%s: err=%d addr=%02x, data=%02x\n",
                                __func__, err, data, data);
                        return -EIO;
                }
        };

        return 0;
}

static int ht1382_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
        return ht1382_get_datetime(to_i2c_client(dev), tm);
}

static int ht1382_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
        return ht1382_set_datetime(to_i2c_client(dev), tm);
}
上面是我写的读出数据和写入数据的驱动代码,运行时,读出数据会提示read error,(写数据也是错)报错部分的代码是:
/* read registers */
        if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
                dev_err(&client->dev, "%s: read error\n", __func__);
                return -EIO;
        }
下面的是ht1382手册中说的的读选项


还望高人指点,该如何来实现读的驱动代码,或者简单的给点代码指导,感觉我的代码中I2C_msg那里就是错的,第一次写I2C设备驱动,还望各位海涵
附件中是ht1382的手册,谢谢!

knightlyj 发表于 2013-12-27 10:00

上示波器看波形,双通道一个SCL一个SDA,一目了然

zhj1011 发表于 2014-01-17 16:27

先看SCL,SDA有没有波形,确定时序和数据都是正确的,再看有没有收到数据。

gangguan00 发表于 2014-01-18 23:37

1.确认芯片及硬件电路无问题,可用在uboot命令行模式下,用iprobe命令探测i2c器件;
2.这种代码在内核/driver/rtc目录下应该有其他的芯片可参考吧;
3.其实还有一种测试方法,就是在应用层里调用i2c总线接口。
页: [1]
查看完整版本: I2C总线上的RTC驱动(HT1382)问题求助