pi4j-v2
pi4j-v2 copied to clipboard
Error reporting on I2C write failure
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?
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.
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.
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?
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 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.
Sorry, didn't want to close it
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 yeah, that may be correct. You can send a PR, and i'll review and merge it.