[I2C] "arb lost in communicate to add 0x40"

Hi,

We have a FPGA which needs to be programmed via I2C. We connected it to i2c-8 and basically worked except for the first time after Xavier rebooted. And it had nothing to do with the FPGA’s state (I tried powering off/on the FPGA, it worked without those errors).

I got these messages (perror outputs)

! Initialize
message: Resource temporarily unavailable
! Check the IDCODE
message: Resource temporarily unavailable

and dmesg outputs

[   76.237734] tegra-i2c 31e0000.i2c: arb lost in communicate to add 0x40
[   76.259712] tegra-i2c 31e0000.i2c: arb lost in communicate to add 0x40

When I run the “FPGA flasher” again, it worked well (and also all the later tries). The “FPGA flasher” is based on i2c-dev and these error were reported when executing “status = ioctl(i2c_fd, I2C_RDWR, &i2c_packets);”

i2c_messages[1].addr = i2c_addr;
        i2c_messages[1].flags = 0;
        i2c_messages[1].buf = a_bByteSend;
        i2c_messages[1].len = (length + 7) / 8;
        i2c_packets.msgs = i2c_messages;
        i2c_packets.nmsgs = 2;
        state_stop = 0;
        status = ioctl(i2c_fd, I2C_RDWR, &i2c_packets);
        if (status < 0) {
            perror("message");
        }

Any suggestions to solve this problem?

Thanks.

What do you mean “basically worked except for the first time after Xavier rebooted”?
Does it failed after reboot and worked well for second access via i2c bus?

Reboot Xavier
->
Run “FPGA Flasher”
->
Error (access I2C via ioctl twice)
perror:
Resource temporarily unavailable;
Resource temporarily unavailable;
dmesg
tegra-i2c 31e0000.i2c: arb lost in communicate to add 0x40
tegra-i2c 31e0000.i2c: arb lost in communicate to add 0x40
“FPGA Flasher” exit
->
Run “FPGA Flasher”
Works well
->
Run “FPGA Flasher”
Works well
……
->
Power off/on FPGA
->
Run “FPGA Flasher”
Works well
->
Reboot Xavier
->
Run “FPGA Flasher”
->
Error (access I2C via ioctl twice)
perror:
Resource temporarily unavailable;
Resource temporarily unavailable;
dmesg
tegra-i2c 31e0000.i2c: arb lost in communicate to add 0x40
tegra-i2c 31e0000.i2c: arb lost in communicate to add 0x40
“FPGA Flasher” exit
……

So it seems that it’s related to the Xavier reboot instead of the state of FPGA.

Could you probe the i2c bus to check what’s the different for the working and failing case.

Hi ShaneCCC,

Thanks for the reply.

It should be a “GPIO” problem instead of “I2C” problem. There is a “RST” pin of the FPGA and should be properly set before accessing I2C. I use these code to set it up:

int rst_fd;
#define SYSFS_GPIO_EXPORT           "/sys/class/gpio/export"
#define SYSFS_GPIO_RST_PIN_VAL      "422"
#define SYSFS_GPIO_RST_DIR          "/sys/class/gpio/gpio422/direction"
#define SYSFS_GPIO_RST_DIR_VAL      "out"
#define SYSFS_GPIO_RST_VAL          "/sys/class/gpio/gpio422/value"
#define SYSFS_GPIO_RST_VAL_H        "1"
#define SYSFS_GPIO_RST_VAL_L        "0"

void init_reset()
{
    rst_fd = open(SYSFS_GPIO_EXPORT, O_WRONLY);
    if(rst_fd == -1)
    {
        printf("ERR: reset pin open error.\n");
        return;
    }
    write(rst_fd, SYSFS_GPIO_RST_PIN_VAL ,sizeof(SYSFS_GPIO_RST_PIN_VAL));
//    usleep(1000000);
    close(rst_fd);

    rst_fd = open(SYSFS_GPIO_RST_DIR, O_WRONLY);
    if(rst_fd == -1)
    {
        printf("ERR: reset pin direction open error.\n");
        return;
    }
    write(rst_fd, SYSFS_GPIO_RST_DIR_VAL, sizeof(SYSFS_GPIO_RST_DIR_VAL));
    usleep(1000);
    close(rst_fd);

    rst_fd = open(SYSFS_GPIO_RST_VAL, O_RDWR);
    if(rst_fd == -1)
    {
        printf("ERR: reset pin value open error.\n");
        return;
    }
    write(rst_fd, SYSFS_GPIO_RST_VAL_H, sizeof(SYSFS_GPIO_RST_VAL_H));
    usleep(1000);
}

After the first executing, I could see “/sys/class/gpio/gpio422”, files and sub-directories in it, and “/sys/class/gpio/gpio422/direction” were set to “out” successfully, however, the “FPGA Flasher” failed. As mentioned in the previous posts, it would be good if I run it again.

I tried these:

1 Manually execute “echo “422” > /sys/class/gpio/export”, and run the “FPGA FLasher”, it works even if it’s the first time after rebooting.

2 Manually execute “echo “422” > /sys/class/gpio/unexport”, and run the “FPGA FLasher”, it fails even if it’s not the first time after rebooting. And it works for later executions.

However, it’s still strange. I tried adding delay here and it made no difference.

write(rst_fd, SYSFS_GPIO_RST_PIN_VAL ,sizeof(SYSFS_GPIO_RST_PIN_VAL));
    usleep(1000000);
    close(rst_fd);

And if it failed here, I shouldn’t see the /sys/class/gpio/gpio422, or “/sys/class/gpio/gpio422/direction” were set to “out” after the first execution, right?