com.qualcomm.robotcore.hardware

## Class I2cDeviceSynchImpl

- java.lang.Object
- - com.qualcomm.robotcore.hardware.I2cDeviceSynchReadHistoryImpl
  - - com.qualcomm.robotcore.hardware.I2cDeviceSynchImpl

- All Implemented Interfaces:
    Engagable, HardwareDevice, HardwareDeviceHealth, I2cAddrConfig, I2cAddressableDevice, I2cDeviceSynch, I2cDeviceSynchReadHistory, I2cDeviceSynchSimple, RobotConfigNameable

      public final class I2cDeviceSynchImpl
      extends I2cDeviceSynchReadHistoryImpl
      implements I2cDeviceSynch, Engagable

  `I2cDeviceSynchImpl` is a utility class that makes it easy to read or write data to an instance of `I2cDevice`. Its functionality is exposed through the `I2cDeviceSynch` interface. Please see that interface, and the `I2cDeviceSynchImpl` constructor here, for further information.
  See Also:
    `I2cDeviceSynchImpl(I2cDevice, I2cAddr, boolean)`, `I2cDeviceSynch`, `I2cDevice`

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `protected class` | `I2cDeviceSynchImpl.Callback`
    `protected static class` | `I2cDeviceSynchImpl.CONTROLLER_PORT_MODE`
    `protected static class` | `I2cDeviceSynchImpl.READ_CACHE_STATUS`
    `protected static class` | `I2cDeviceSynchImpl.WRITE_CACHE_STATUS`
    `protected class` | `I2cDeviceSynchImpl.WriteCacheStatus`

    - ### Nested classes/interfaces inherited from interface com.qualcomm.robotcore.hardware.I2cDeviceSynch

      `I2cDeviceSynch.HeartbeatAction, I2cDeviceSynch.ReadMode, I2cDeviceSynch.ReadWindow`

    - ### Nested classes/interfaces inherited from interface com.qualcomm.robotcore.hardware.HardwareDeviceHealth

      `HardwareDeviceHealth.HealthStatus`

    - ### Nested classes/interfaces inherited from interface com.qualcomm.robotcore.hardware.HardwareDevice

      `HardwareDevice.Manufacturer`

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected I2cDeviceSynchImpl.Callback` | `callback`
    `protected java.lang.Object` | `callbackLock`
    `protected java.lang.Object` | `concurrentClientLock`
    `protected I2cController` | `controller`
    `protected I2cDeviceSynchImpl.CONTROLLER_PORT_MODE` | `controllerPortMode`
    `protected int` | `cregWrite`
    `protected static int` | `dibCacheOverhead`
    `protected boolean` | `disableReadWindows`
    `protected java.lang.Object` | `engagementLock`
    `protected HardwareDeviceHealthImpl` | `hardwareDeviceHealth`
    `protected boolean` | `hasReadWindowChanged`
    `protected I2cDeviceSynch.HeartbeatAction` | `heartbeatAction`
    `protected java.util.concurrent.ExecutorService` | `heartbeatExecutor`
    `protected I2cAddr` | `i2cAddr`
    `protected I2cDevice` | `i2cDevice`
    `protected int` | `iregWriteFirst`
    `protected boolean` | `isClosing`
    `protected boolean` | `isControllerLegacy`
    `protected boolean` | `isEngaged`
    `protected boolean` | `isHooked`
    `protected boolean` | `isI2cDeviceOwned`
    `protected boolean` | `isReadWindowSentToControllerInitialized`
    `protected boolean` | `isWriteCoalescingEnabled`
    `protected boolean` | `loggingEnabled`
    `protected java.lang.String` | `loggingTag`
    `protected static int` | `msCallbackLockAbandon`
    `protected static int` | `msCallbackLockWaitQuantum`
    `protected int` | `msHeartbeatInterval`
    `protected java.lang.String` | `name`
    `protected long` | `nanoTimeReadCacheValid`
    `protected byte[]` | `readCache`
    `protected java.util.concurrent.locks.Lock` | `readCacheLock`
    `protected I2cDeviceSynchImpl.READ_CACHE_STATUS` | `readCacheStatus`
    `protected TimeWindow` | `readCacheTimeWindow`
    `protected java.util.concurrent.atomic.AtomicInteger` | `readerWriterCount`
    `protected java.util.concurrent.locks.ReadWriteLock` | `readerWriterGate`
    `protected java.util.concurrent.atomic.AtomicInteger` | `readerWriterPreventionCount`
    `protected I2cDeviceSynch.ReadWindow` | `readWindow`
    `protected I2cDeviceSynch.ReadWindow` | `readWindowActuallyRead`
    `protected I2cDeviceSynch.ReadWindow` | `readWindowSentToController`
    `protected RobotUsbModule` | `robotUsbModule`
    `protected ElapsedTime` | `timeSinceLastHeartbeat`
    `protected byte[]` | `writeCache`
    `protected java.util.concurrent.locks.Lock` | `writeCacheLock`
    `protected I2cDeviceSynchImpl.WriteCacheStatus` | `writeCacheStatus`

    - ### Fields inherited from class com.qualcomm.robotcore.hardware.I2cDeviceSynchReadHistoryImpl

      `historyQueue, historyQueueCapacity, historyQueueLock`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `I2cDeviceSynchImpl(I2cDevice i2cDevice, boolean isI2cDeviceOwned)` Instantiates an `I2cDeviceSynchImpl` instance on the indicated `I2cDevice`.
    `I2cDeviceSynchImpl(I2cDevice i2cDevice, I2cAddr i2cAddr, boolean isI2cDeviceOwned)` Instantiate an `I2cDeviceSynchImpl` instance on the indicated `I2cDevice` using the indicated I2C address.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected void` | `acquireReaderLockShared()`
    `protected void` | `adjustHooking()`
    `protected void` | `assignReadWindow(I2cDeviceSynch.ReadWindow newWindow)`
    `void` | `close()` Closes this device
    `protected static byte[]` | `concatenateByteArrays(byte[] left, byte[] right)`
    `protected void` | `disableReadsAndWrites()`
    `void` | `disengage()` Disengage the object from underlying services it uses to render its function.
    `protected void` | `enableReadsAndWrites()`
    `void` | `enableWriteCoalescing(boolean enable)` Enables or disables an optimization wherein writes to two sets of adjacent register ranges may be coalesced into a single I2c transaction if the second write comes along while the first is still queued for writing.
    `void` | `engage()` (Re)enage the object with its underlying services.
    `void` | `ensureReadWindow(I2cDeviceSynch.ReadWindow windowNeeded, I2cDeviceSynch.ReadWindow windowToSet)` Ensure that the current register window covers the indicated set of registers.
    `protected void` | `forceDrainReadersAndWriters()`
    `java.lang.String` | `getConnectionInfo()` Get connection information about this device in a human readable format
    `java.lang.String` | `getDeviceName()` Returns a string suitable for display to the user as to the type of device.
    `HardwareDeviceHealth.HealthStatus` | `getHealthStatus()`
    `I2cDeviceSynch.HeartbeatAction` | `getHeartbeatAction()` Returns the current action, if any, to take upon expiration of the heartbeat interval.
    `int` | `getHeartbeatInterval()` Returns the interval within which communication must be received by the I2C device lest a timeout occur.
    `I2cAddr` | `getI2cAddr()` Deprecated.
    `I2cAddr` | `getI2cAddress()` Returns the I2C address currently in use to communicate with an I2C hardware device
    `boolean` | `getLogging()`
    `java.lang.String` | `getLoggingTag()`
    `HardwareDevice.Manufacturer` | `getManufacturer()` Returns an indication of the manufacturer of this device.
    `I2cDeviceSynch.ReadWindow` | `getReadWindow()` Returns the current register window used for reading.
    `java.lang.String` | `getUserConfiguredName()` Returns the human-recognizable name of this device, if same has been set.
    `int` | `getVersion()` Version
    `protected I2cDeviceSynchImpl.WRITE_CACHE_STATUS` | `getWriteCacheStatus()`
    `protected void` | `gracefullyDrainReadersAndWriters()`
    `protected void` | `hook()`
    `protected void` | `initWriteCacheStatus(I2cDeviceSynchImpl.WRITE_CACHE_STATUS status)`
    `boolean` | `isArmed()` Returns whether, as of this instant, this device client is alive and operational in its normally expected mode; that is, whether it is currently in communication with its underlying hardware or whether it is in some other state.
    `boolean` | `isEngaged()` Returns whether the object is currently in the engaged state.
    `protected boolean` | `isOpenForReading()`
    `protected boolean` | `isOpenForWriting()`
    `boolean` | `isWriteCoalescingEnabled()` Answers as to whether write coalescing is currently enabled on this device.
    `protected void` | `log(int verbosity, java.lang.String message)`
    `protected void` | `log(int verbosity, java.lang.String format, java.lang.Object... args)`
    `protected boolean` | `newReadsAndWritesAllowed()`
    `byte[]` | `read(int ireg, int creg)` Read a contiguous set of device I2C registers.
    `byte` | `read8(int ireg)` Read the byte at the indicated register.
    `protected boolean` | `readCacheIsValid()`
    `protected boolean` | `readCacheValidityCurrentOrImminent()`
    `TimestampedData` | `readTimeStamped(int ireg, int creg)` Reads and returns a contiguous set of device I2C registers, together with a best-available timestamp of when the actual I2C read occurred.
    `TimestampedData` | `readTimeStamped(int ireg, int creg, I2cDeviceSynch.ReadWindow readWindowNeeded, I2cDeviceSynch.ReadWindow readWindowSet)` Advanced: Atomically calls ensureReadWindow() with the last two parameters and then readTimeStamped() with the first two without the possibility of a concurrent client interrupting in the middle.
    `protected byte[]` | `readWriteCache()`
    `protected void` | `releaseReaderLockShared()`
    `void` | `resetDeviceConfigurationForOpMode()` Resets the device's configuration to that which is expected at the beginning of an OpMode.
    `void` | `setHealthStatus(HardwareDeviceHealth.HealthStatus status)`
    `void` | `setHeartbeatAction(I2cDeviceSynch.HeartbeatAction action)` Sets the action to take when the current heartbeat interval expires.
    `void` | `setHeartbeatInterval(int msHeartbeatInterval)` Sets the interval within which communication must be received by the I2C device lest a timeout may occur.
    `void` | `setI2cAddr(I2cAddr newAddress)` Deprecated.
    `void` | `setI2cAddress(I2cAddr i2cAddr)` Configures a new I2C address to use
    `void` | `setLogging(boolean enabled)` Turn logging on or off.
    `void` | `setLoggingTag(java.lang.String loggingTag)` Set the tag to use when logging is on.
    `void` | `setReadWindow(I2cDeviceSynch.ReadWindow newWindow)` Set the set of registers that we will read and read and read again on every hardware cycle
    `protected void` | `setReadWindowInternal(I2cDeviceSynch.ReadWindow newWindow)`
    `void` | `setUserConfiguredName(java.lang.String name)` Informs the device of a name by which it would be recognized by the user.
    `protected void` | `setWriteCacheStatus(I2cDeviceSynchImpl.WRITE_CACHE_STATUS status)`
    `protected void` | `unhook()`
    `protected long` | `waitForIdleWriteCache()`
    `protected void` | `waitForValidReadCache()`
    `protected void` | `waitForWriteCompletionInternal(I2cWaitControl writeControl)`
    `void` | `waitForWriteCompletions(I2cWaitControl waitControl)` Waits for the most recent write to complete according to the behavior specified in writeControl.
    `void` | `write(int ireg, byte[] data)` Writes data to a set of registers, beginning with the one indicated, using `I2cWaitControl.ATOMIC` semantics.
    `void` | `write(int ireg, byte[] data, I2cWaitControl waitControl)` Writes data to a set of registers, beginning with the one indicated.
    `void` | `write8(int ireg, int data)` Writes a byte to the indicated register using `I2cWaitControl.ATOMIC` semantics.
    `void` | `write8(int ireg, int data, I2cWaitControl waitControl)` Writes a byte to the indicated register.

    - ### Methods inherited from class com.qualcomm.robotcore.hardware.I2cDeviceSynchReadHistoryImpl

      `addToHistoryQueue, getHistoryQueue, getHistoryQueueCapacity, setHistoryQueueCapacity`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### i2cAddr

          protected I2cAddr i2cAddr

    - #### i2cDevice

          protected I2cDevice i2cDevice

    - #### isI2cDeviceOwned

          protected boolean isI2cDeviceOwned

    - #### controller

          protected I2cController controller

    - #### isControllerLegacy

          protected boolean isControllerLegacy

    - #### hardwareDeviceHealth

          protected HardwareDeviceHealthImpl hardwareDeviceHealth

    - #### robotUsbModule

          protected RobotUsbModule robotUsbModule

    - #### isHooked

          protected boolean isHooked

    - #### isEngaged

          protected boolean isEngaged

    - #### readerWriterPreventionCount

          protected java.util.concurrent.atomic.AtomicInteger readerWriterPreventionCount

    - #### readerWriterGate

          protected java.util.concurrent.locks.ReadWriteLock readerWriterGate

    - #### readerWriterCount

          protected java.util.concurrent.atomic.AtomicInteger readerWriterCount

    - #### isClosing

          protected boolean isClosing

    - #### callback

          protected I2cDeviceSynchImpl.Callback callback

    - #### loggingEnabled

          protected boolean loggingEnabled

    - #### loggingTag

          protected java.lang.String loggingTag

    - #### name

          protected java.lang.String name

    - #### timeSinceLastHeartbeat

          protected ElapsedTime timeSinceLastHeartbeat

    - #### readCacheTimeWindow

          protected TimeWindow readCacheTimeWindow

    - #### readCache

          protected byte[] readCache

    - #### writeCache

          protected byte[] writeCache

    - #### dibCacheOverhead

          protected static final int dibCacheOverhead

      See Also:
        Constant Field Values

    - #### readCacheLock

          protected java.util.concurrent.locks.Lock readCacheLock

    - #### writeCacheLock

          protected java.util.concurrent.locks.Lock writeCacheLock

    - #### msCallbackLockWaitQuantum

          protected static final int msCallbackLockWaitQuantum

      See Also:
        Constant Field Values

    - #### msCallbackLockAbandon

          protected static final int msCallbackLockAbandon

      See Also:
        Constant Field Values

    - #### isWriteCoalescingEnabled

          protected boolean isWriteCoalescingEnabled

    - #### engagementLock

          protected final java.lang.Object engagementLock

    - #### concurrentClientLock

          protected final java.lang.Object concurrentClientLock

    - #### callbackLock

          protected final java.lang.Object callbackLock

    - #### disableReadWindows

          protected boolean disableReadWindows

    - #### readWindow

          protected volatile I2cDeviceSynch.ReadWindow readWindow

    - #### readWindowActuallyRead

          protected volatile I2cDeviceSynch.ReadWindow readWindowActuallyRead

    - #### readWindowSentToController

          protected volatile I2cDeviceSynch.ReadWindow readWindowSentToController

    - #### isReadWindowSentToControllerInitialized

          protected volatile boolean isReadWindowSentToControllerInitialized

    - #### hasReadWindowChanged

          protected volatile boolean hasReadWindowChanged

    - #### nanoTimeReadCacheValid

          protected volatile long nanoTimeReadCacheValid

    - #### readCacheStatus

          protected volatile I2cDeviceSynchImpl.READ_CACHE_STATUS readCacheStatus

    - #### writeCacheStatus

          protected final I2cDeviceSynchImpl.WriteCacheStatus writeCacheStatus

    - #### controllerPortMode

          protected volatile I2cDeviceSynchImpl.CONTROLLER_PORT_MODE controllerPortMode

    - #### iregWriteFirst

          protected volatile int iregWriteFirst

    - #### cregWrite

          protected volatile int cregWrite

    - #### msHeartbeatInterval

          protected volatile int msHeartbeatInterval

    - #### heartbeatAction

          protected volatile I2cDeviceSynch.HeartbeatAction heartbeatAction

    - #### heartbeatExecutor

          protected volatile java.util.concurrent.ExecutorService heartbeatExecutor

  - ### Constructor Detail

    - #### I2cDeviceSynchImpl

          public I2cDeviceSynchImpl(I2cDevice i2cDevice,
                                    I2cAddr i2cAddr,
                                    boolean isI2cDeviceOwned)

      Instantiate an `I2cDeviceSynchImpl` instance on the indicated `I2cDevice` using the indicated I2C address.
      Parameters:
        `i2cDevice` - the `I2cDevice` that the new `I2cDeviceSynchImpl` is to be a client of
        `i2cAddr` - the I2C address to which communications will be targeted
        `isI2cDeviceOwned` - If true, then when this `I2cDeviceSynchImpl` closes, the underlying `I2cDevice` is closed as well; otherwise, it is not. Typically, if the provided `I2cDevice` is retrieved from an OpMode's hardware map, one passes false to `isI2cDeviceOwned`, as such @link I2cDevice}s should remain functional across multiple OpMode invocations.
      See Also:
        `HardwareDevice.close()`, `HardwareDevice.close()`

    - #### I2cDeviceSynchImpl

          public I2cDeviceSynchImpl(I2cDevice i2cDevice,
                                    boolean isI2cDeviceOwned)

      Instantiates an `I2cDeviceSynchImpl` instance on the indicated `I2cDevice`. When this constructor is used, `setI2cAddress(I2cAddr)` must be called later in order for the instance to be functional.
      See Also:
        `I2cDeviceSynchImpl(I2cDevice, I2cAddr, boolean)`

  - ### Method Detail

    - #### setI2cAddr

          @Deprecated
          public void setI2cAddr(I2cAddr newAddress)

      Deprecated.
      Description copied from interface: `I2cDeviceSynchSimple`
      Sets the I2C address of the underlying client. If necessary, the client may be briefly disengaged (and then automatically reengaged) in the process.
      Specified by:
        `setI2cAddr` in interface `I2cDeviceSynchSimple`
      Parameters:
        `newAddress` - the new I2C address

    - #### setI2cAddress

          public void setI2cAddress(I2cAddr i2cAddr)

      Description copied from interface: `I2cAddrConfig`
      Configures a new I2C address to use
      Specified by:
        `setI2cAddress` in interface `I2cAddrConfig`
      Parameters:
        `i2cAddr` - the new I2C address to use

    - #### getI2cAddress

          public I2cAddr getI2cAddress()

      Description copied from interface: `I2cAddressableDevice`
      Returns the I2C address currently in use to communicate with an I2C hardware device
      Specified by:
        `getI2cAddress` in interface `I2cAddressableDevice`
      Returns:
        the I2C address currently in use

    - #### getI2cAddr

          @Deprecated
          public I2cAddr getI2cAddr()

      Deprecated.
      Description copied from interface: `I2cDeviceSynchSimple`
      Returns the I2C address currently being used by this device client
      Specified by:
        `getI2cAddr` in interface `I2cDeviceSynchSimple`
      Returns:
        the current I2C address

    - #### engage

          public void engage()

      Description copied from interface: `Engagable`
      (Re)enage the object with its underlying services. If the object is presently engaged, this method has no effect.
      Specified by:
        `engage` in interface `Engagable`

    - #### hook

          protected void hook()

    - #### adjustHooking

          protected void adjustHooking()

    - #### isEngaged

          public boolean isEngaged()

      Description copied from interface: `Engagable`
      Returns whether the object is currently in the engaged state.
      Specified by:
        `isEngaged` in interface `Engagable`
      Returns:
        whether the object is currently in the engaged state.

    - #### isArmed

          public boolean isArmed()

      Description copied from interface: `I2cDeviceSynchSimple`
      Returns whether, as of this instant, this device client is alive and operational in its normally expected mode; that is, whether it is currently in communication with its underlying hardware or whether it is in some other state. Note that a device client which is not engaged will never report as armed.
      Specified by:
        `isArmed` in interface `I2cDeviceSynchSimple`
      Returns:
        the arming state of this device client
      See Also:
        `Engagable.engage()`

    - #### disengage

          public void disengage()

      Description copied from interface: `Engagable`
      Disengage the object from underlying services it uses to render its function. If the object is presently disenaged, this method has no effect.
      Specified by:
        `disengage` in interface `Engagable`

    - #### unhook

          protected void unhook()

    - #### disableReadsAndWrites

          protected void disableReadsAndWrites()

    - #### enableReadsAndWrites

          protected void enableReadsAndWrites()

    - #### newReadsAndWritesAllowed

          protected boolean newReadsAndWritesAllowed()

    - #### gracefullyDrainReadersAndWriters

          protected void gracefullyDrainReadersAndWriters()

    - #### forceDrainReadersAndWriters

          protected void forceDrainReadersAndWriters()

    - #### getManufacturer

          public HardwareDevice.Manufacturer getManufacturer()

      Description copied from interface: `HardwareDevice`
      Returns an indication of the manufacturer of this device.
      Specified by:
        `getManufacturer` in interface `HardwareDevice`
      Returns:
        the device's manufacturer

    - #### getDeviceName

          public java.lang.String getDeviceName()

      Description copied from interface: `HardwareDevice`
      Returns a string suitable for display to the user as to the type of device. Note that this is a device-type-specific name; it has nothing to do with the name by which a user might have configured the device in a robot configuration.
      Specified by:
        `getDeviceName` in interface `HardwareDevice`
      Returns:
        device manufacturer and name

    - #### getConnectionInfo

          public java.lang.String getConnectionInfo()

      Description copied from interface: `HardwareDevice`
      Get connection information about this device in a human readable format
      Specified by:
        `getConnectionInfo` in interface `HardwareDevice`
      Returns:
        connection info

    - #### getVersion

          public int getVersion()

      Description copied from interface: `HardwareDevice`
      Version
      Specified by:
        `getVersion` in interface `HardwareDevice`
      Returns:
        get the version of this device

    - #### resetDeviceConfigurationForOpMode

          public void resetDeviceConfigurationForOpMode()

      Description copied from interface: `HardwareDevice`
      Resets the device's configuration to that which is expected at the beginning of an OpMode. For example, motors will reset the their direction to 'forward'.
      Specified by:
        `resetDeviceConfigurationForOpMode` in interface `HardwareDevice`

    - #### close

          public void close()

      Description copied from interface: `HardwareDevice`
      Closes this device
      Specified by:
        `close` in interface `HardwareDevice`

    - #### setHealthStatus

          public void setHealthStatus(HardwareDeviceHealth.HealthStatus status)

      Specified by:
        `setHealthStatus` in interface `HardwareDeviceHealth`

    - #### getHealthStatus

          public HardwareDeviceHealth.HealthStatus getHealthStatus()

      Specified by:
        `getHealthStatus` in interface `HardwareDeviceHealth`

    - #### setReadWindow

          public void setReadWindow(I2cDeviceSynch.ReadWindow newWindow)

      Description copied from interface: `I2cDeviceSynch`
      Set the set of registers that we will read and read and read again on every hardware cycle
      Specified by:
        `setReadWindow` in interface `I2cDeviceSynch`
      Parameters:
        `newWindow` - the register window to read. May be null, indicating that no reads are to occur.
      See Also:
        `I2cDeviceSynch.getReadWindow()`

    - #### setReadWindowInternal

          protected void setReadWindowInternal(I2cDeviceSynch.ReadWindow newWindow)

    - #### assignReadWindow

          protected void assignReadWindow(I2cDeviceSynch.ReadWindow newWindow)

    - #### getReadWindow

          public I2cDeviceSynch.ReadWindow getReadWindow()

      Description copied from interface: `I2cDeviceSynch`
      Returns the current register window used for reading.
      Specified by:
        `getReadWindow` in interface `I2cDeviceSynch`
      Returns:
        the current read window
      See Also:
        `I2cDeviceSynch.setReadWindow(ReadWindow)`

    - #### ensureReadWindow

          public void ensureReadWindow(I2cDeviceSynch.ReadWindow windowNeeded,
                                       I2cDeviceSynch.ReadWindow windowToSet)

      Description copied from interface: `I2cDeviceSynch`
      Ensure that the current register window covers the indicated set of registers. If there is currently a non-null register window, and windowNeeded is non-null, and the current register window entirely contains windowNeeded, then do nothing. Otherwise, set the current register window to windowToSet.
      Specified by:
        `ensureReadWindow` in interface `I2cDeviceSynch`
      Parameters:
        `windowNeeded` - Test the current register window, if any, against this window to see if an update to the current register window is needed in order to cover it. May be null, indicating that an update to the current register window is always needed
        `windowToSet` - If an update to the current register window is needed, then this is the window to which it will be set. May be null.
      See Also:
        `I2cDeviceSynch.setReadWindow(ReadWindow)`, `I2cDeviceSynchSimple.read8(int)`

    - #### read8

          public byte read8(int ireg)

      Description copied from interface: `I2cDeviceSynchSimple`
      Read the byte at the indicated register. See `I2cDeviceSynchSimple.readTimeStamped(int, int)` for a complete description.
      Specified by:
        `read8` in interface `I2cDeviceSynchSimple`
      Parameters:
        `ireg` - the register number to read
      Returns:
        the byte that was read
      See Also:
        `I2cDeviceSynchSimple.read(int, int)`, `I2cDeviceSynchSimple.readTimeStamped(int, int)`, `I2cDeviceSynch.ensureReadWindow(I2cDeviceSynch.ReadWindow, I2cDeviceSynch.ReadWindow)`

    - #### read

          public byte[] read(int ireg,
                             int creg)

      Description copied from interface: `I2cDeviceSynchSimple`
      Read a contiguous set of device I2C registers. See `I2cDeviceSynchSimple.readTimeStamped(int, int)` for a complete description.
      Specified by:
        `read` in interface `I2cDeviceSynchSimple`
      Parameters:
        `ireg` - the register number of the first byte register to read
        `creg` - the number of bytes / registers to read
      Returns:
        the data which was read
      See Also:
        `I2cDeviceSynchSimple.read8(int)`, `I2cDeviceSynchSimple.readTimeStamped(int, int)`, `I2cDeviceSynch.ensureReadWindow(I2cDeviceSynch.ReadWindow, I2cDeviceSynch.ReadWindow)`

    - #### readTimeStamped

          public TimestampedData readTimeStamped(int ireg,
                                                 int creg)

      Description copied from interface: `I2cDeviceSynchSimple`
      Reads and returns a contiguous set of device I2C registers, together with a best-available timestamp of when the actual I2C read occurred. Note that this can take many tens of milliseconds to execute, and thus should not be called from the loop() thread.

      You can always just call this method without worrying at all about `read windows`, that will work, but usually it is more efficient to take some thought and care as to what set of registers the I2C device controller is being set up to read, as adjusting that window of registers incurs significant extra time.

      If the current read window can't be used to read the requested registers, then a new read window will automatically be created as follows. If the current read window is non null and wholly contains the registers to read but can't be read because it is a used-up `ReadMode#ONLY_ONCE` window, a new read fresh window will be created with the same set of registers. Otherwise, a window that exactly covers the requested set of registers will be created.

      Specified by:
        `readTimeStamped` in interface `I2cDeviceSynchSimple`
      Parameters:
        `ireg` - the register number of the first byte register to read
        `creg` - the number of bytes / registers to read
      Returns:
        the data which was read, together with the timestamp
      See Also:
        `I2cDeviceSynchSimple.read(int, int)`, `I2cDeviceSynchSimple.read8(int)`, `I2cDeviceSynch.ensureReadWindow(I2cDeviceSynch.ReadWindow, I2cDeviceSynch.ReadWindow)`

    - #### isOpenForReading

          protected boolean isOpenForReading()

    - #### isOpenForWriting

          protected boolean isOpenForWriting()

    - #### acquireReaderLockShared

          protected void acquireReaderLockShared()
                                          throws java.lang.InterruptedException

      Throws:
        `java.lang.InterruptedException`

    - #### releaseReaderLockShared

          protected void releaseReaderLockShared()

    - #### readTimeStamped

          public TimestampedData readTimeStamped(int ireg,
                                                 int creg,
                                                 I2cDeviceSynch.ReadWindow readWindowNeeded,
                                                 I2cDeviceSynch.ReadWindow readWindowSet)

      Description copied from interface: `I2cDeviceSynch`
      Advanced: Atomically calls ensureReadWindow() with the last two parameters and then readTimeStamped() with the first two without the possibility of a concurrent client interrupting in the middle.
      Specified by:
        `readTimeStamped` in interface `I2cDeviceSynch`
      Parameters:
        `ireg` - the register number of the first byte register to read
        `creg` - the number of bytes / registers to read
        `readWindowNeeded` - the read window we require
        `readWindowSet` - the read window to set if the required read window is not current
      Returns:
        the data that was read, together with the timestamp
      See Also:
        `I2cDeviceSynch.ensureReadWindow(ReadWindow, ReadWindow)`, `I2cDeviceSynchSimple.readTimeStamped(int, int)`

    - #### readCacheValidityCurrentOrImminent

          protected boolean readCacheValidityCurrentOrImminent()

    - #### readCacheIsValid

          protected boolean readCacheIsValid()

    - #### write8

          public void write8(int ireg,
                             int data)

      Description copied from interface: `I2cDeviceSynchSimple`
      Writes a byte to the indicated register using `I2cWaitControl.ATOMIC` semantics.
      Specified by:
        `write8` in interface `I2cDeviceSynchSimple`
      Parameters:
        `ireg` - the register number that is to be written
        `data` - the byte which is to be written to that register
      See Also:
        `I2cDeviceSynchSimple.write(int, byte[], I2cWaitControl)`

    - #### write8

          public void write8(int ireg,
                             int data,
                             I2cWaitControl waitControl)

      Description copied from interface: `I2cDeviceSynchSimple`
      Writes a byte to the indicated register. See also `I2cDeviceSynchSimple.write(int, byte[], I2cWaitControl)`.
      Specified by:
        `write8` in interface `I2cDeviceSynchSimple`
      Parameters:
        `ireg` - the register number that is to be written
        `data` - the byte which is to be written to that register
        `waitControl` - controls the behavior of waiting for the completion of the write
      See Also:
        `I2cDeviceSynchSimple.write(int, byte[], I2cWaitControl)`

    - #### write

          public void write(int ireg,
                            byte[] data)

      Description copied from interface: `I2cDeviceSynchSimple`
      Writes data to a set of registers, beginning with the one indicated, using `I2cWaitControl.ATOMIC` semantics.
      Specified by:
        `write` in interface `I2cDeviceSynchSimple`
      Parameters:
        `ireg` - the first of the registers which is to be written
        `data` - the data which is to be written to the registers
      See Also:
        `I2cDeviceSynchSimple.write(int, byte[], I2cWaitControl)`

    - #### write

          public void write(int ireg,
                            byte[] data,
                            I2cWaitControl waitControl)

      Description copied from interface: `I2cDeviceSynchSimple`
      Writes data to a set of registers, beginning with the one indicated. The data will be written to the I2C device in an expeditious manner. Once data is accepted by this API, it is guaranteed that (barring catastrophic failure) the data will be transmitted to the USB controller module before the I2cDeviceSync is closed. The call itself may or may block until the data has been transmitted to the USB controller module according to a caller-provided parameter.
      Specified by:
        `write` in interface `I2cDeviceSynchSimple`
      Parameters:
        `ireg` - the first of the registers which is to be written
        `data` - the data which is to be written to the registers
        `waitControl` - controls the behavior of waiting for the completion of the write

    - #### concatenateByteArrays

          protected static byte[] concatenateByteArrays(byte[] left,
                                                        byte[] right)

    - #### waitForWriteCompletions

          public void waitForWriteCompletions(I2cWaitControl waitControl)

      Description copied from interface: `I2cDeviceSynchSimple`
      Waits for the most recent write to complete according to the behavior specified in writeControl.
      Specified by:
        `waitForWriteCompletions` in interface `I2cDeviceSynchSimple`
      Parameters:
        `waitControl` - controls the behavior of waiting for the completion of the write Note that a value of `I2cWaitControl.NONE` is essentially a no-op.

    - #### readWriteCache

          protected byte[] readWriteCache()

    - #### waitForWriteCompletionInternal

          protected void waitForWriteCompletionInternal(I2cWaitControl writeControl)
                                                 throws java.lang.InterruptedException

      Throws:
        `java.lang.InterruptedException`

    - #### setWriteCacheStatus

          protected void setWriteCacheStatus(I2cDeviceSynchImpl.WRITE_CACHE_STATUS status)

    - #### getWriteCacheStatus

          protected I2cDeviceSynchImpl.WRITE_CACHE_STATUS getWriteCacheStatus()

    - #### initWriteCacheStatus

          protected void initWriteCacheStatus(I2cDeviceSynchImpl.WRITE_CACHE_STATUS status)

    - #### waitForIdleWriteCache

          protected long waitForIdleWriteCache()
                                        throws java.lang.InterruptedException

      Throws:
        `java.lang.InterruptedException`

    - #### waitForValidReadCache

          protected void waitForValidReadCache()
                                        throws java.lang.InterruptedException

      Throws:
        `java.lang.InterruptedException`
      See Also:
        `I2cDeviceSynchImpl.WriteCacheStatus.waitForIdle()`

    - #### enableWriteCoalescing

          public void enableWriteCoalescing(boolean enable)

      Description copied from interface: `I2cDeviceSynchSimple`
      Enables or disables an optimization wherein writes to two sets of adjacent register ranges may be coalesced into a single I2c transaction if the second write comes along while the first is still queued for writing. By default, write coalescing is disabled.
      Specified by:
        `enableWriteCoalescing` in interface `I2cDeviceSynchSimple`
      Parameters:
        `enable` - whether to enable write coalescing or not
      See Also:
        `I2cDeviceSynchSimple.isWriteCoalescingEnabled()`

    - #### isWriteCoalescingEnabled

          public boolean isWriteCoalescingEnabled()

      Description copied from interface: `I2cDeviceSynchSimple`
      Answers as to whether write coalescing is currently enabled on this device.
      Specified by:
        `isWriteCoalescingEnabled` in interface `I2cDeviceSynchSimple`
      Returns:
        whether write coalescing is currently enabled or not.
      See Also:
        `I2cDeviceSynchSimple.enableWriteCoalescing(boolean)`

    - #### setUserConfiguredName

          public void setUserConfiguredName(java.lang.String name)

      Description copied from interface: `RobotConfigNameable`
      Informs the device of a name by which it would be recognized by the user. Note that the provided name may be null, in which case no such user-recognizable name is provided
      Specified by:
        `setUserConfiguredName` in interface `RobotConfigNameable`

    - #### getUserConfiguredName

          public java.lang.String getUserConfiguredName()

      Description copied from interface: `RobotConfigNameable`
      Returns the human-recognizable name of this device, if same has been set.
      Specified by:
        `getUserConfiguredName` in interface `RobotConfigNameable`
      See Also:
        `RobotConfigNameable.setUserConfiguredName(String)`

    - #### setLogging

          public void setLogging(boolean enabled)

      Description copied from interface: `I2cDeviceSynchSimple`
      Turn logging on or off. Logging output can be viewed using the Android Logcat tools.
      Specified by:
        `setLogging` in interface `I2cDeviceSynchSimple`
      Parameters:
        `enabled` - whether to enable logging or not

    - #### getLogging

          public boolean getLogging()

      Specified by:
        `getLogging` in interface `I2cDeviceSynchSimple`
      See Also:
        `I2cDeviceSynchSimple.setLogging(boolean)`

    - #### setLoggingTag

          public void setLoggingTag(java.lang.String loggingTag)

      Description copied from interface: `I2cDeviceSynchSimple`
      Set the tag to use when logging is on.
      Specified by:
        `setLoggingTag` in interface `I2cDeviceSynchSimple`
      Parameters:
        `loggingTag` - the logging tag to sue

    - #### getLoggingTag

          public java.lang.String getLoggingTag()

      Specified by:
        `getLoggingTag` in interface `I2cDeviceSynchSimple`
      See Also:
        `I2cDeviceSynchSimple.setLoggingTag(String)`

    - #### getHeartbeatInterval

          public int getHeartbeatInterval()

      Description copied from interface: `I2cDeviceSynch`
      Returns the interval within which communication must be received by the I2C device lest a timeout occur.
      Specified by:
        `getHeartbeatInterval` in interface `I2cDeviceSynch`
      Returns:
        the current heartbeat interval, in milliseconds
      See Also:
        `I2cDeviceSynch.setHeartbeatInterval(int)`

    - #### setHeartbeatInterval

          public void setHeartbeatInterval(int msHeartbeatInterval)

      Description copied from interface: `I2cDeviceSynch`
      Sets the interval within which communication must be received by the I2C device lest a timeout may occur. The default heartbeat interval is zero, signifying that no heartbeat is maintained.
      Specified by:
        `setHeartbeatInterval` in interface `I2cDeviceSynch`
      Parameters:
        `msHeartbeatInterval` - the new hearbeat interval, in milliseconds
      See Also:
        `I2cDeviceSynch.getHeartbeatInterval()`

    - #### setHeartbeatAction

          public void setHeartbeatAction(I2cDeviceSynch.HeartbeatAction action)

      Description copied from interface: `I2cDeviceSynch`
      Sets the action to take when the current heartbeat interval expires. The default action is null; thus, to be useful, an action must always be explicitly specified.
      Specified by:
        `setHeartbeatAction` in interface `I2cDeviceSynch`
      Parameters:
        `action` - the action to take at each heartbeat.
      See Also:
        `I2cDeviceSynch.getHeartbeatAction()`, `I2cDeviceSynch.setHeartbeatInterval(int)`

    - #### getHeartbeatAction

          public I2cDeviceSynch.HeartbeatAction getHeartbeatAction()

      Description copied from interface: `I2cDeviceSynch`
      Returns the current action, if any, to take upon expiration of the heartbeat interval.
      Specified by:
        `getHeartbeatAction` in interface `I2cDeviceSynch`
      Returns:
        the current heartbeat action. May be null
      See Also:
        `I2cDeviceSynch.setHeartbeatAction(HeartbeatAction)`

    - #### log

          protected void log(int verbosity,
                             java.lang.String message)

    - #### log

          protected void log(int verbosity,
                             java.lang.String format,
                             java.lang.Object... args)