pi4j-v2 icon indicating copy to clipboard operation
pi4j-v2 copied to clipboard

Error reporting on I2C write failure

Open hackerjimbo opened this issue 4 years ago • 8 comments

Using pi4j-v2 and the writeRegister function on an SPI device I've found that I get the error:

WARN com.pi4j.library.pigpio.impl.PiGpioNativeImpl - PIGPIO ERROR: PI_I2C_WRITE_FAILED; I2C write failed

but the return value from writeRegister is the length of the data that I wanted written so I don't get to hear of the problem.

Ideas anyone?

hackerjimbo avatar Jan 28 '21 19:01 hackerjimbo

I've investigated this and found the issue.

It's essentially confusion over whether to return a value that isn't the number of bytes requested or throw an exception. One part of the code assumes an exception will be thrown and another assumes the return value will be used.

The actual error is in libraries/pi4j-library-pigpio/src/main/java/com/pi4j/library/pigpio/PiGpio_I2C.java where we find:

     /** {@inheritDoc} */
    @Override
    public int writeRegister(int register, byte[] data, int offset, int length) throws IOException {
        Objects.checkFromIndexSize(offset, length, data.length);
        piGpio.i2cWriteI2CBlockData(this.handle, register, data, offset, length);
        return length;
    }

This assumes an exception will be thrown and if not it assumes that all went well. I believe the correct code is to return the value of the write block data call but will verify.

hackerjimbo avatar Jan 29 '21 17:01 hackerjimbo

Nope, I was wrong. the write block data call just returns 0 on success rather than the number of bytes actually written. We need to sanitise this so it's at least consistent.

hackerjimbo avatar Jan 29 '21 17:01 hackerjimbo

No comments on here for a while. I also notice that the function I mention above seems to have vanished! Is this now a non-problem due to code reworking?

hackerjimbo avatar Mar 20 '21 15:03 hackerjimbo

Just checked again and this is still an issue! I wouldn't noticed if it weren't for a buggy board I've got!

hackerjimbo avatar Mar 26 '21 16:03 hackerjimbo

@hackerjimbo sorry that this issue has been quiet for so long. Please check out the linuxfs-i2c plugin and see if your results are better. At the moment we are thinking that this plugin should become the default I2C provider and i have checked these methods, and they should return the correct values, i.e. the number of bytes written for the write methods.

If this issue doesn't show up anymore, then you can close this issue.

eitch avatar Jun 09 '21 20:06 eitch

Sorry, didn't want to close it

eitch avatar Jun 09 '21 20:06 eitch

This still seems to be an issue in PiGpio2, the simple fix would be to check the return the value from the i2cWriteI2VBlockData call. This call either returns the number of bytes or a negative number. From there application code can then detect if a device has disconnected and do appropriate handling and logging.

I can create a push request if required for the following function in PiGpio2

public int writeRegister(int register, byte[] data, int offset, int length) { Objects.checkFromIndexSize(offset, length, data.length); return this.piGpio.i2cWriteI2CBlockData(this.handle, register, data, offset, length); }

Also if I switch to linuxfs-i2c as the provider I do get the length back, however, it is always +1 since I think it also includes the regsiter byte? rather than the payload itself.

mbuckton avatar Jul 11 '23 00:07 mbuckton

@mbuckton yeah, that may be correct. You can send a PR, and i'll review and merge it.

eitch avatar Jul 11 '23 06:07 eitch