public interface I2cDeviceSynch extends HardwareDevice, Engagable
I2cDeviceSynch is an interface that exposes functionality for interacting with I2c
devices. Its methods are synchronous, in that they complete their action before returning to the
caller.
Methods are provided to read and write data simply and straightforwardly. Singleton bytes
or larger quantities of data can be read or written using read8() and
write8() or read() and write()
respectively. No attention to 'read mode' or 'write mode' is required. Simply call reads
and writes as you need them, and the right thing happens.
For devices that automatically shutdown if no communication is received within a certain duration, a heartbeat facility is optionally provided.
On causality: regarding the sequencing of reads and writes, two important points are worthy of mention. First, reads and writes are ultimately issued to the controller in the same chronological order they were received by the device client instance. Second, even more importantly, reads *always* see the effect of preceding writes on the controller. That is, a read that follows a write will ensure that, first, the write gets issued to the controller, and then, second, a read from the controller is subsequently issued. By contrast, absent such constraints, a read might quickly return freshly-read data already present without having to interact with the controller. Which brings us to...
Reading data. The simplest way to read data is to call one of the variations of the
read() method. This is always correct, and will return data as accessed
from the I2c device. However, in many situations, reads can be significantly optimized by use
of a read window. With a read window, a larger chunk of the device's I2c register space
can be automatically read even if only a portion of it is needed to service a particular read()
call; this can make subsequent read()s significantly faster. Further, depending on the mode
of ReadWindow used, read
operations will occur in the background, and read()s will be serviced (subject to causality) out
of cached data updated and maintained by the background processing without any synchronous
communication with the I2c device itself. For sensors in particular, this mode of operation
can be particularly advantageous.
Three modes of ReadWindow are
available:
REPEAT. In this
mode, background reads are always scheduled and cached data updated whenever there's no other
(writing) work to do. This is the mode commonly used by sensors, who mostly execute reads
and only issue a write relatively infrequently.BALANCED. In this
mode, background reads are also performed, but only if the user initiates a manual read first after
a write operation. The object does not automatically start background reads on its own, as the
transition from writing to reading can be a relatively expensive one. This mode can be useful
for objects like motor and servo controllers which exhibit a balanced mix of both write and
read operationsONLY_ONCE. In this
mode, no background reading is performed; data is always retrieved with a synchronous
communication to the i2c device.An I2cDeviceSynch has only one read window in effect at any particular time. This can
be updated with setReadWindow(ReadWindow) or ensureReadWindow().
When a read() is made, if the registers requested therein are contained within the current
read window, then that whole window of data is read from the i2c device (if the cache is out
of date) and the appropriate portion thereof returned. In contrast, if the requested registers
are not so contained, then, in effect, a one-off ONLY_ONCE
is used without disturbing the window maintained by setReadWindow(ReadWindow).
| Modifier and Type | Interface and Description |
|---|---|
static class |
I2cDeviceSynch.HeartbeatAction
Instances of HeartBeatAction indicate what action to carry out to perform
a heartbeat should that become necessary.
|
static class |
I2cDeviceSynch.ReadMode
I2cDeviceSynch.ReadMode controls whether when asked to read we read only once or read multiple times. |
static class |
I2cDeviceSynch.ReadWindow
RegWindow is a utility class for managing the window of I2C register bytes that
are read from our I2C device on every hardware cycle
|
static class |
I2cDeviceSynch.TimestampedData
TimestampedData pairs together data which has been read with the timestamp at which
the read occurred, as best that can be determined
|
| Modifier and Type | Method and Description |
|---|---|
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 |
ensureReadWindow(I2cDeviceSynch.ReadWindow windowNeeded,
I2cDeviceSynch.ReadWindow windowToSet)
Ensure that the current register window covers the indicated set of registers.
|
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.
|
int |
getI2cAddr()
Returns the I2C address currently being used by this device client
|
I2cDeviceSynch.ReadWindow |
getReadWindow()
Returns the current register window used for reading.
|
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 |
isWriteCoalescingEnabled()
Answers as to whether write coalescing is currently enabled on this device.
|
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.
|
I2cDeviceSynch.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.
|
I2cDeviceSynch.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.
|
void |
setHeartbeatAction(I2cDeviceSynch.HeartbeatAction action)
Sets the action to take when the current heartbeat interval expires.
|
void |
setHeartbeatInterval(int ms)
Sets the interval within which communication must be received by the I2C device lest
a timeout may occur.
|
void |
setI2cAddr(int i2cAddr8Bit)
Sets the I2C address of the underlying client.
|
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 window)
Set the set of registers that we will read and read and read again on every hardware cycle
|
void |
waitForWriteCompletions()
Waits for any previously issued writes to be written to the USB controller module.
|
void |
write(int ireg,
byte[] data)
Writes data to a set of registers, beginning with the one indicated.
|
void |
write(int ireg,
byte[] data,
boolean waitForCompletion)
Writes data to a set of registers, beginning with the one indicated.
|
void |
write8(int ireg,
int bVal)
Writes a byte to the indicated register.
|
void |
write8(int ireg,
int bVal,
boolean waitForCompletion)
Writes a byte to the indicated register.
|
close, getConnectionInfo, getDeviceName, getVersionvoid setReadWindow(I2cDeviceSynch.ReadWindow window)
window - the register window to read. May be null, indicating that no reads are to occur.getReadWindow()I2cDeviceSynch.ReadWindow getReadWindow()
setReadWindow(ReadWindow)void ensureReadWindow(I2cDeviceSynch.ReadWindow windowNeeded, I2cDeviceSynch.ReadWindow windowToSet)
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 neededwindowToSet - If an update to the current register window is needed, then this
is the window to which it will be set. May be null.setReadWindow(ReadWindow),
read8(int)byte read8(int ireg)
readTimeStamped(int, int) for a
complete description.ireg - the register number to readread(int, int),
readTimeStamped(int, int),
ensureReadWindow(ReadWindow, ReadWindow)byte[] read(int ireg,
int creg)
readTimeStamped(int, int) for a
complete description.ireg - the register number of the first byte register to readcreg - the number of bytes / registers to readread8(int),
readTimeStamped(int, int),
ensureReadWindow(ReadWindow, ReadWindow)I2cDeviceSynch.TimestampedData readTimeStamped(int ireg, int creg)
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
I2cDeviceSynch.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.
ireg - the register number of the first byte register to readcreg - the number of bytes / registers to readread(int, int),
read8(int),
ensureReadWindow(ReadWindow, ReadWindow)I2cDeviceSynch.TimestampedData readTimeStamped(int ireg, int creg, I2cDeviceSynch.ReadWindow readWindowNeeded, I2cDeviceSynch.ReadWindow readWindowSet)
ireg - the register number of the first byte register to readcreg - the number of bytes / registers to readreadWindowNeeded - the read window we requirereadWindowSet - the read window to set if the required read window is not currentensureReadWindow(ReadWindow, ReadWindow),
readTimeStamped(int, int)void write8(int ireg,
int bVal)
write(int, byte[], boolean).ireg - the register number that is to be writtenbVal - the byte which is to be written to that registerwrite(int, byte[], boolean)void write(int ireg,
byte[] data)
write(int, byte[], boolean).ireg - the first of the registers which is to be writtendata - the data which is to be written to the registerswrite(int, byte[], boolean)void write8(int ireg,
int bVal,
boolean waitForCompletion)
write(int, byte[], boolean).ireg - the register number that is to be writtenbVal - the byte which is to be written to that registerwaitForCompletion - whether or not to wait until the write has been sent to the controllerwrite(int, byte[], boolean)void write(int ireg,
byte[] data,
boolean waitForCompletion)
ireg - the first of the registers which is to be writtendata - the data which is to be written to the registerswaitForCompletion - whether or not to wait until the write has been sent to the controllervoid waitForWriteCompletions()
void enableWriteCoalescing(boolean enable)
enable - whether to enable write coalescing or notisWriteCoalescingEnabled()boolean isWriteCoalescingEnabled()
enableWriteCoalescing(boolean)void setHeartbeatInterval(int ms)
ms - the new hearbeat interval, in millisecondsgetHeartbeatInterval()int getHeartbeatInterval()
setHeartbeatInterval(int)void setHeartbeatAction(I2cDeviceSynch.HeartbeatAction action)
action - the action to take at each heartbeat.getHeartbeatAction(),
setHeartbeatInterval(int)I2cDeviceSynch.HeartbeatAction getHeartbeatAction()
setHeartbeatAction(HeartbeatAction)boolean isArmed()
Engagable.engage()void setI2cAddr(int i2cAddr8Bit)
i2cAddr8Bit - the new I2C addressint getI2cAddr()
void setLogging(boolean enabled)
enabled - whether to enable logging or notvoid setLoggingTag(java.lang.String loggingTag)
loggingTag - the logging tag to sue