This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

failed to send 8210 bytes over i2c with i2c_write

Hi,

I use nrf5340 and have issue with i2c large buffer send:
In order to flash page to bootloader with my 
application:

  1. I defined
    1. I defined static array with size of 8210 
    2. enabled i2c as master
    3. bind i2c successfully(i tested with small buffer size and it is working) 
  2. use function i2c_write(i2c_dev, data, size, MAX_ADD);
    1. i2c_dev - a binded device
    2. data - pointer to static buffer 
    3. size - 8210 
    4. MAX_ADD - device i3c address

I get error from function i2c_write ()   -5 with log  [00:01:48.453,613] <err> i2c_nrfx_twim: Error on I2C line occurred for message 0

ret = k_sem_take(&(get_dev_data(dev)->completion_sync),
				 I2C_TRANSFER_TIMEOUT_MSEC)

the ret value is -11 

I need to transmit a full page in one transaction 

Thanks for help.

  • if i use i2c_transfer() function to split buffer to messages with stop condition on the last message as at below:
    Are the mesages buffer send wihout delay? as one transaction? 2+1026*8 = 8210B

    bool max32664_writeMsgWithDelay(uint8_t *data, int size, int delay)
    {
        int chunkLen = 1026;
        int msg_size = ((size - 2) / chunkLen) + 1;
        struct i2c_msg msg[msg_size];
    
        msg[0].buf = (uint8_t *)&data[0];
        msg[0].len = 2;
        msg[0].flags = I2C_MSG_WRITE;
        for (size_t i = 1; i < msg_size; i++)
        {
            msg[i].buf = (uint8_t *)&data[2 + ((i - 1) * chunkLen)];
            msg[i].len = chunkLen;
            msg[i].flags = I2C_MSG_WRITE;
        }
        msg[msg_size - 1].flags |= I2C_MSG_STOP;
    
        i2c_dump_msgs("page", msg, msg_size, MAX_ADD);
        int ret = i2c_transfer(i2c_dev, msg, msg_size, MAX_ADD);
        max32664_status_t statusByte = 0;
        k_msleep(delay);
        ret |= i2c_read(i2c_dev, &statusByte, 1, MAX_ADD);
    
        printk("Result:%d after  Delay:%d\r\n", statusByte, delay);
        if (ret != 0 || statusByte != SUCCESS)
            return false;
        else
            return true;

  • Hi,

    The -5 (EIO) errors seems to come from this section of the driver. This does not seems to be related to the size of the transfer or the API used to start the transfer, but an error on the bus. Another possibility is that the timeout is too short to for the transfer to complete, for instance if you have set a low frequency, or the slave performs clock stretching.

    As far as I can see, the driver will try to concatenate the messages into one transfer when using i2c_transfer(), so it should have a similar effect to calling i2c_write() (which calls i2c_transfer() internally).

    Are you able to provide a logic trace of the transfer? That would help determine what is going wrong with the transfer.

    Best regards,
    Jørgen

  • Hi it looks like  "timeout is too short to for the transfer to complete"

  • is there is a way to override it at config file?

Related