I2C is a type of synchronous communication protocol. It is also known as 2 wire communication protocol. It was invented by Philips. I2C stands for integrated circuits. It is a bus topology-based protocol mainly used for communication between various ICs connected on the same PCB, unlike communication between components which are placed several meters apart as we have seen in the RS232 UART communication. The 2 wires which are connecting the devices are SDA i.e. data line and SCL i.e. Control line/clock line.
The SDA line sends the data to other devices and SCL is responsible for synchronization. If we look at the analogy of synchronous communication a clock signal on the clock line works in the I2C communication protocol. It is a multi-master communication protocol. In an I2C bus more than one master can exist and Clock is controlled by a master. Only one master can access the bus at a time and there is bus arbitration in I2C communication protocol.
I2C is a half-duplex communication protocol, since there is only one line for communication between slave and master to transfer and receive data. This is how the devices are connected on I2C bus, which has one SDA line and another as SCL line, let’s imagine this is a master and all others are slaves of this Master. Every slave has its own unique name or we can say a slave address, when the master wants to talk to any slave 1st he will address the receiver that means it will call the receiver. There are different modes of I2C communication protocol which are:
- Standard up to 100 kbps
- Fast up to 400 kbps
- Fast + up to 1 Mbps
- High speed up to 3.4 Mbps
These modes show how fast we can transmit or receive the data over an I2C bus. Based upon these modes whichever is suitable for all slave devices, the programmer will configure I2C bus speed.
For example slave 1 supports 100kBPS, slave 2 supports 1Mbps, slave 3 supports 3.4 Mbps, bus will be configured for standard mode. Because all slave devices do support 100kbPS. Generally, select lines are available on the slave IC to configure slave speed. Every slave and master device has an open drain / open collector configuration pin. These are connected to the either SDA & SCL lines which are further connected to a 5V or 3.3V supply line depending upon the VDD of the devices through an external resistor. For now, we will consider 5V.
When both SDA & SCL lines are at 5V we can say the I2C bus is Idle and there is no data transmission. When the devices need to talk they pull these I2C bus lines to ground which is known as logic level low by turning on this internal FET, when this bus is pulled low by a certain device then every other device which is present on the bus understands the bus is pulled to ground, this is 0 for the devices and when internal MOSFETs are turned off, the I2C bus again goes to 5V or we can say logic level high and this is considered as 1. The resistors which are used here have high resistance, say in kohm, because of this it becomes possible to connect 2 or more open-drain devices to a single bus. These pull up resistors ensure the current is not flowing freely from VDD to ground so the power consumption in this bus is very low. The value of these resistors changes as per the I2C modes around 2k ohm resistors used for 400kbps speed and 10k ohm for lower speeds of around 100kbps. As we increase the speed of transmission the value of the resistor decreases, so there is a tradeoff between speed and power dissipation.
Frame structure of I2C transmission:
We will look into frame structure of I2C communication and how data is transferred or received from the bus. The bit frame is nothing but the sequence of bits which indicates the receiver about the starting point and ending of the data communication. This data frame is standard for each communication protocol, it helps each device to understand the pattern of talking. Bit frame of I2C consists of a start bit, after start bit the master addresses the receiver so there comes the slave address which is either 7 bit or 11 bit. Then the master sends a Read / write signal. After this sequence, the slave gives an acknowledgement. Once the ack is received, one more addressing bit sequence comes which addresses the internal registers of slaves from which the master wants to write or read. After this bit sequence, there comes the ack again and after that the actual 8 bit data is sent or received, following a final acknowledgement bit, and at the end there comes the stop bit to notify the slave device that the communication has ended. The data frame which is very popular where an I2C master is some microcontroller who has an I2C peripheral and I2C slave device as RTC (Real time clock) DS1307 IC. RTC is basically a clock which runs continuously even if the device is off. So if we buy an RTC from the market, 1st we need to configure it with the current day, date, month, year, and time. So, what we do is, initially we write its corresponding registers. Then we read all the inputs of time & dates later on. So, we will try to understand read and write frames of RTC.
Now 1st step, we are configuring the RTC IC, 1st is the start bit – Initially both SCL line & SDA lines are idle, when any device needs to talk it starts from the start bit. So, in the start bit the SDA line is pulled to logic level low keeping SCL line high, this high to low transition on SDA line generates an interrupt and slaves prepare for the communication. Now, Master sends the 7 bit slave address over the bus and after that it sends Read / write bit. The data line changes its status when the SCL line goes from logic high to logic low, check this if the transmitter wants to send 1 and the SDA line is low initially, then it will change SDA to 1 only when the SCL is low and the data is sampled at the receiver side when SCL line transits from low to high logic level. Master changes the state of the SDA line later when the SCL line goes low. Now comes the 8th clock pulse, where master decides the read or write operation, if the master wants to send some data to the slave it will pull SDA line to logic Low and if it is receiving any data then it will pull SDA line to logic High, this is kind of a tricky part but you will understand once you see full data steam.
If 2 or more masters are talking on a single bus at a time then the slaves will not be able to understand any of the information. So to avoid that bus arbitration is used in I2C communication. This Arbitration is achieved based on the slave address. In I2C communication, arbitration can be achieved by monitoring SDA lines after sending data on the bus. If there are two devices who want to transmit the data to various slave addresses of eg: Master 1 wants to send data to slave 1 which has slave address 0x04 and master 2 wants to send data to slave 2 which has slave address 0x06. Whichever slave has a lower address will get the early access to talk over the bus.
How does it work?
Check this diagram initially; the SDA line will be pulled to low for 4 consecutive clock cycles after the Start bit and after that it will change status to logic high, denoting 1 on the bus because of these both masters who are doing it. Simultaneously, now master 1 is addressing to 0x04 so he will pull SDA line to ‘0’ on the next clock pulse and at the same time Master 2 is addressing to 0x06 and it will try to maintain the SDA line to logic high. Well, both masters are monitoring this SDA line, the SDA line is connected to the open drain configuration of the devices. Now master 2 sends 1 on the SDA line but the SDA line is already pulled low by the internal transistor of the master 1 so all of the current will flow through this transistor and the devices on the bus will read 0 because the SDA line is pulled to ground. Now, Master 2 understands that even if I kept SDA line High it is showing low, that means some other device is accessing the bus at the same and that is how the slave who has a lower address gets higher priority. This is the bit arbitration in the I2C communication protocol.
When a master wants to transmit data but the slave is not ready to receive it, there needs to be some mechanism to handle this condition, right? Let’s take an example of EEPROM IC, when some data is written on the EEPROM IC by a master it will save this data and if the master issues a read command immediately after the write command, then The EEPROM IC can tell the master to wait while it is saving this data.
To deal with such cases the clock stretching technique is used in the I2C communication protocol. Where the SCL line is stretched by the slave which indicates the master that the slave is busy. This status of the clock is monitored by the transmitter. An I2C slave has every right to hold down the SCL line if it needs to reduce the bus speed. The master, on the other hand, has to read the clock signal after releasing the SCL line to high state and he should wait for the SCL line to go high again when it is pulled low by the slave for clock stretching, which will indicate to the master that the slave is not ready for the communication. After the slave releases the SCL line the data transmission resumes on the I2C bus and that is how the clock stretching helps the slave devices.
Advantages of I2C protocol:
Only two connecting wires are required for the number of masters and slave connected. I2C supports Multi-master configuration, more than one master can access I2C bus where they can read and write from slave devices connected.
Error handling – ACK/NACK functionality can be proved useful for error handling. If NACK is detected by a receiver which may indicate a transmitter to retransmit the data. This error can be detected by the receiver by using error detection mechanism; once error is detected the receiver may respond NACK, generally this error will be a bit flips from 0 to 1 or 1 to 0. I2C communication protocol adapts the requirements of various slave devices. For example if some slave is a little slower than other slaves connected on the bus, then it may stretch the clock line or the master will configure the compatible bus speed for the particular slave.
Disadvantages of I2C protocol:
7-bit addressing gives less flexibility to slave devices – Because the slave address is fixed for the particular device which is given by the manufacturer, so there are high chances of selecting the slaves who have the same slave addresses which will make it difficult for users who want to select these slaves for some applications. For example i want to use 2 accelerometers of the same manufacturer for motion sensing but this slave addressing doesn’t allow me to use the same device again. However, modern slaves have different addresses and they give leverage to choosing.
Complexity of firmware increases – Because the master device has to support features like bus arbitration and clock stretching,
Complexity of firmware increases Data overhead increases – For 8-bits of data, we need to send 1 start bit, 1 stop bit, ACK bits, R/W bit and 7-bit slave address. This increases data overhead for 8-bits to send the data which reduces data throughput.
In UART and SPI, we don’t see such addresses or ack/nack bit. Which increases data throughput (intended data transferred from master to slave in unit time). Since outputs are open drain, they need pull up resistors which add the limitations like Limiting clock speed and Power dissipation. Every Bus topology has one disadvantage which applies for I2C as well. If some slave device is hung or faulty, it can hold any of the lines or both lines low. This will not allow other slaves to transmit data on I2C bus successfully and the Bus synchronization may get disturbed.
Let’s look at following example, where two microcontrollers are connected which collects data and write to slave devices where it might need a high resolution 16-bit ADC with more than 8 channels where sensors are connected. An EEPROM to save data collected by masters connected on an I2C bus. An RTC which helps to save data with timestamps. That’s how a whole system can talk to each other using an I2C bus.
I2C communication Based Projects: