I2C inefficiency caused by the use of read windows with REV Expansion Hubs #542
Description
The implementation of I2cDeviceSynchImplOnSimple
used to wrap LynxI2cDeviceSynch
instances for all REV I2C devices will read extra registers according to the read window that are never used. This isn't really problematic except that the duration of I2C read commands are linear, not constant in the number of registers.
By bypassing the read window, one can achieve fairly significant speedups. In particular, here is the difference between an unoptimized and optimized (read window-less) BNO055 Euler angle read: (This was generated using https://github.com/acmerobotics/relic-recovery/blob/master/TeamCode/src/main/java/com/acmerobotics/relicrecovery/opmodes/test/ExpansionHubBenchmark.java)
To remedy this, one can subclass I2cDeviceSynchImplOnSimple
and use it to construct I2cDeviceSynch
instances without read windows:
public class BetterI2cDeviceSynchImplOnSimple extends I2cDeviceSynchImplOnSimple {
public BetterI2cDeviceSynchImplOnSimple(I2cDeviceSynchSimple simple, boolean isSimpleOwned) {
super(simple, isSimpleOwned);
}
@Override
public void setReadWindow(ReadWindow window) {
// intentionally do nothing
}
}
I2cDeviceSynch optimizedI2cDeviceSynch = new BetterI2cDeviceSynchImplOnSimple(
new LynxI2cDeviceSynchV1(AppUtil.getDefContext(), module, bus), true);