SIM_INTERFACE(i2c_slave_v2) { void (*start)(conf_object_t *device, uint8 address); void (*read)(conf_object_t *device); void (*write)(conf_object_t *device, uint8 value); void (*stop)(conf_object_t *device); attr_value_t (*addresses)(conf_object_t *device); }; #define I2C_SLAVE_V2_INTERFACE "i2c_slave_v2"
The i2c_slave_v2
interface is used together with the i2c_master_v2
interface to model communication over an I2C bus. Most calls to a method in
the i2c_slave_v2
interface expect a response call to a method
in the i2c_master_v2
interface. It is up to each device to
find the caller's interface; usually it is configured with an attribute in
both the master and slave device.
The i2c_slave_v2
and i2c_master_v2
interfaces
replace the obsolete interfaces i2c_master
,
i2c_slave
, i2c_link
, and
i2c_bridge
.
An I2C bus consists of a number of master devices and a number of slave devices. Each slave device listens to one or more 7-bit addresses or 10-bit addresses. It is an error to connect two slave devices to the same bus if they listen to the same address. Communication over the bus is initiated by a master, which can communicate with one slave device at a time. Only one master on a bus can communicate at a time.
Two I2C devices can communicate directly if one implements the
i2c_master_v2
interface and the other one implements the
i2c_slave_v2
interface. An I2C bus with multiple masters or
slaves is typically modeled using an i2c-link-v2 object,
where each device is connected to an endpoint object.
The start method starts a transfer. The
address parameter is the address of the slave device, encoded
as an 8-bit number. To communicate with 7-bit address slave device, using
little-endian bit numbering, bit 0 is a read/write bit (0 → master
writes, 1 → master reads) and bits 1 to 7 is the 7-bit address of
the slave device. The address parameter should normally
be in the (inclusive) range 0x10 - 0xef
; the ranges 0x00 -
0x0f
and 0xf0 - 0xff
are reserved for special addressing modes.
To communicate with 10-bit address slave device, using little-endian bit
numbering, bit 0 is a read/write bit (same as 7-bit address), bits 1 to 2
is part of 10-bit address, and bits 3 to 7 is 10-bit address mode 0b11110.
The slave responds to start using the
acknowledge method. The ack parameter may be
I2C_ack
or I2C_noack
if the start is acked
or noacked, respectively. In a multi-master configuration, the slave may
instead respond by calling the start method in the
i2c_slave_v2
interface of the master device; this signals
that the master lost the bus arbitration. This is discussed further below.
If a start was acked by a slave device, read/write bit in the
start method was 1, the master proceeds with a sequence
of read calls. Each call is followed by a
read_response call from the slave. If the read/write bit in
the start was 0, the master instead proceeds with a
sequence of write calls, each one followed by an
acknowledge call. The ack parameter of the
acknowledge method may be either I2C_ack
or
I2C_noack
, representing ack and noack, respectively.
After sending a number of reads or writes, the master may choose to either call the stop method to issue a stop condition which terminates the transfer, or to call the start method again to issue a repeated start condition. The repeated start condition works like a normal start condition.
When 0 is passed as the address parameter of the start method, a General Call transfer is initiated. A General Call transfer works like a normal write transfer, except that multiple slave devices may acknowledge the start and write requests. The master will conceive a request as acknowledged if it was acknowledged by at least one of the slaves.
When 10-bit address pattern is passed as the address parameter of the start method, a 10-bit address transaction is initiated. A 10-bit address transaction begins with write status (read/write bit should be 0). As mentioned before, bits 1 to 2 are the most significant bits of 10-bit address. Then following is a call to the write method with the last 8 bits of 10-bit address. If the transaction is slave-receiver, the next transfer works like a normal write transfer. If the transaction is slave-transmitter, then the start method is called again with the same address pattern as before, but with bit 0 (the read/write bit) set to 1. This is followed by calls to read like in a normal read transaction.
The addresses method is used to retrieve the set of addresses a
device currently listens to. The method is called by the
i2c-link-v2 to provide an overview of the bus topology, and
to detect address collisions early. The method may not have any
side-effects on the simulation. The return value is a list containing all
the different values of the address parameter in a
start call that the slave would respond to with
I2C_ack
. The list may also contain an element
Nil
to mark that the device might respond to other addresses as
well. If a device is configured to listen to a specific address but is
currently disabled, then that address may still be included in the list.
For example, if a slave device listens to the single 7-bit address
0x55
, the return value of addresses would be
[0xaa, 0xab]
, using Python list syntax.
The specification of the return value may be extended in the future, to
allow other values than Nil
and 8-bit integers. Therefore, callers
should not make any assumptions on how the elements are formatted in the
return value.
For most I2C devices it is sufficient to implement only one of the
i2c_slave_v2
and i2c_master_v2
interfaces. In
some cases it may be useful for a device to implement both interfaces,
either because the device can act both as a master and as a slave on the
bus, or because it needs to use the start and
stop methods to monitor start and stop conditions on the bus.
I2C link endpoints also implement both interfaces.
If multiple master devices are connected to the same i2c link, then all
master devices need to implement the i2c_slave_v2
interface
in addition to i2c_master_v2
, in order to handle bus
arbitration correctly:
Note that there is no need for a master device to implement the
i2c_slave_v2
interface if the device only will be used in
single-master configurations.
The start, write and read methods in the
i2c_slave_v2
interface are allowed to respond synchronously;
i.e., the acknowledge or read_response method may be
called before the corresponding method in the slave interface has returned.
A master that needs to connect directly to a slave device needs to take this
into consideration; however, when communicating via an
i2c-link-v2 object, the link guarantees that all responses
are asynchronous.
addresses | Global Context |
All other methods | Cell Context |