AnsweredAssumed Answered

I2C ack to slow about 0.04s

Question asked by ben wei on Nov 9, 2017
Latest reply on Nov 13, 2017 by Wigros Sun

Hello ,

 

What's issus cause i2c ack too slow as below function?

check my dts file , clock-frequency set 375000 . but receive response still slow.

 

[   17.756617] [i2c-core.c][i2c_transfer], line:[2111] i2c_transfer start
[   17.757515] i2c i2c-0: master_xfer[0] W, addr=0x68, len=1
[   17.758213] i2c i2c-0: master_xfer[1] R, addr=0x68, len=1
[   17.805545] [i2c-core.c][i2c_transfer], line:[2134] i2c_transfer done

 

int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
    int ret;

 

    /* REVISIT the fault reporting model here is weak:
     *
     *  - When we get an error after receiving N bytes from a slave,
     *    there is no way to report "N".
     *
     *  - When we get a NAK after transmitting N bytes to a slave,
     *    there is no way to report "N" ... or to let the master
     *    continue executing the rest of this combined message, if
     *    that's the appropriate response.
     *
     *  - When for example "num" is two and we successfully complete
     *    the first message but get an error part way through the
     *    second, it's unclear whether that should be reported as
     *    one (discarding status on the second message) or errno
     *    (discarding status on the first one).
     */
    KDBG("i2c_transfer start");
    if (adap->algo->master_xfer) {
//#ifdef DEBUG
        for (ret = 0; ret < num; ret++) {
            dev_info(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
                "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)
                ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
                (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
        }
//#endif

 

        if (in_atomic() || irqs_disabled()) {
            ret = i2c_trylock_adapter(adap);
            if (!ret)
                /* I2C activity is ongoing. */
            KDBG("i2c_transfer done");
                return -EAGAIN;
        } else {
            i2c_lock_adapter(adap);
        }

 

        ret = __i2c_transfer(adap, msgs, num);
        i2c_unlock_adapter(adap);
        KDBG("i2c_transfer done");

        return ret;
    } else {
        dev_dbg(&adap->dev, "I2C level transfers not supported\n");
        return -EOPNOTSUPP;
    }
}

 

Thanks,

Ben

Outcomes