i2c_bridge i2c_device
API Reference Manual  /  4 Model-to-Model Interfaces  / 

i2c_bus

Description
SIM_INTERFACE(i2c_bus) {
        int (*start)(conf_object_t *i2c_bus, uint8 address);
        int (*stop)(conf_object_t *i2c_bus);
        uint8 (*read_data)(conf_object_t *i2c_bus);
        void (*write_data)(conf_object_t *i2c_bus, uint8 value);
        int (*register_device)(conf_object_t *i2c_bus,
                               conf_object_t *device,
                               uint8 address, uint8 mask,
                               i2c_device_flag_t flags);
        void (*unregister_device)(conf_object_t *i2c_bus,
                                  conf_object_t *device,
                                  uint8 address, uint8 mask);
};

#define I2C_BUS_INTERFACE "i2c_bus"

The i2c_bus interface is implemented by the I2C bus. The interface is used by I2C devices to communicate with the I2C bus.

To connect an I2C device to an I2C bus, first you call register_device with a 7-bit address and mask. The address is actually an address pattern. When there is traffic on the I2C bus (as initiated by a call to the bus interface start function), the target address is matched against each registered device by checking if (target_address ^ device_address) & device_mask == 0. The flags attribute sets the type of connection. The alternatives are exclusive or shared. An I2C device connected exclusive can not share a transfer with another I2C device. An I2C device connected shared supports that other I2C devices connected shared to the I2C bus handles the same transfer. The register_device function returns 0 on success and -1 on failure.

Use unregister_device to disconnect an I2C device from the I2C bus. To completely remove a device use the same address and mask attributes as when the device was registered. An I2C device can also remove some part of the address match by unregister itself with a different mask.

An I2C transfer is initiated by a master I2C device. The I2C device responding to the transfer is called slave. The master starts a transfer by calling the start function with address as argument. The address is the 7-bit address plus a read/write bit (read/write = 0 → slave-receive, read/write = 1 → slave-transmit). The read/write bit is the least significant bit. This means that all odd values sent to start function initiates a transfer where the master is requesting data from the slave. The start function returns 0 on success and -1 on failure.

An I2C transfer should be terminated by a master I2C device when the bus is no longer needed. This is done by calling the stop function. This function always returns 0.

I2C devices implement the i2c_device interface. Both the i2c_device interface and the i2c_bus interface has identical read_data and write_data functions to transfer data over the bus. The i2c_device also has set_state function, which is used by the I2C bus to set the I2C device state. The states are I2C_idle, I2C_slave_transmit, and I2C_slave_receive. The default state is I2C_idle.

Here are the steps for a transfer:

1. The I2C master device calls start in the I2C bus with 7-bit address and 1-bit read/write flag.

2. The I2C bus calls the set_state in the I2C slave device with I2C_slave_transmit or I2C_slave_receive as argument depending on the 1-bit read/write flag. The I2C slave accepts the state change by returning 0.

3. I2C bus returns 0 to the I2C master if the start command in 1 was successful. The I2C bus can report failure for several reasons, there are another ongoing transfer, can not find any device with the address provided, I2C slave did not except state change etc.

4. The I2C master calls the I2C buses read_data or write_data depending if it wants to read from or write to the I2C slave. The I2C bus relays the call to the I2C slave read_data or write_data function. The I2C slave have no way to report errors, the I2C master expects the I2C slave to be able to handle all calls without any problem. The I2C bus can do step 4 several times before terminating the transfer.

5. The I2C master calls the stop function when it wants to terminate the transfer. This causes the I2C bus to call the set_state function in the I2C slave with I2C_idle as argument. The transfer is now completed.

Execution Context
Cell Context for all methods.

i2c_bridge i2c_device