So far we have seen the operation of the bus from the master's point of view and using only one master on the bus.
The I2C bus was originally developed as a multi-master bus. This means that more than one device initiating transfers can be active in the system.
When using only one master on the bus there is no real risk of corrupted data, except if a slave device is malfunctioning or if there is a fault condition involving the SDA / SCL bus lines.
This situation changes with 2 MCU's:
When MCU 1 issues a start condition and sends an address, all slaves will listen (including MCU 2 which at that time is considered a slave as well). If the address does not match the address of CPU 2, this device has to hold back any activity until the bus becomes idle again after a stop condition.
As long as the two MCU's monitor what is going on on the bus (start and stop) and as long as they are aware that a transaction is going on because the last issued command was not a STOP, there is no problem.
Let's assume one of the MCU's missed the START condition and still thinks the bus is idle, or it just came out of reset and wants to start talking on the bus which could very well happen in a real-life scenario. This could lead to problems.
How can you know if some other device is transmitting on the bus ?
Fortunately, the physical bus setup helps us out. Since the bus structure is a wired AND (if one device pulls a line low it stays low), you can test if the bus is idle or occupied.
When a master changes the state of a line to HIGH, it MUST always check that the line really has gone to HIGH. If it stays low then this is an indication that the bus is occupied and some other device is pulling the line low.
Therefore the general rule of thumb is: If a master can't get a certain line to go high, it lost arbitration and needs to back off and wait until a stop condition is seen before making another attempt to start transmitting.
What about the risk of data corruption ?
Since the previous rule says that a master loses arbitration when it cannot get either SCL or SDA to go high when needed, this problem does not exist. It is the device that is sending the '0' that rules the bus. One master cannot disturb the other master's transmission because if it can't detect one of the lines to go high, it backs off, and if it is the other master that can't do so, it will behave the same.
This kind of back-off condition will only occur if the two levels transmitted by the two masters are not the same. Therefore, let's have a look at the following figure, where two MCUs start transmitting at the same time:
The two MCU's are accessing a slave in write mode at address 1111001. The slave acknowledges this. So far, both masters are under the impression that they "own" the bus.
Now MCU1 wants to transmit 01010101 to the slave, while MCU 2 wants to transmit 01100110 to the slave. The moment the data bits do not match anymore (because what the MCU sends is different than what is present on the bus) one of them loses arbitration and backs off. Obviously, this is the MCU which did not get its data on the bus. For as long as there has been no STOP present on the bus, it won't touch the bus and leave the SDA and SCL lines alone (yellow zone).
The moment a STOP was detected, MCU2 can attempt to transmit again.
From the example above we can conclude that is the master that is pulling the line LOW in an arbitration situation that always wins the arbitration. The master which wanted the line to be HIGH when it is being pulled low by the other master loses the bus. We call this a loss of arbitration or a back-off condition.
When a MCU loses arbitration, it has to wait for a STOP condition to appear on the bus. Then it knows that the previous transmission has been completed.