... | ... | @@ -7,19 +7,21 @@ Inter-Integrated Circuit (IIC or, better, I2C) is a synchronous serial communica |
|
|
However this protocol have also some disadvantages as we will see. One of them is the low speed of the protocol, reaching 100 kHz of clock signal for the standard mode (Sm) and 400 kHz for the fast mode (Fm). Other disadvantages are that the protocol is a master/slave half duplex, meaning that the communication is always initiated by a device (master) that manages the communication generating the clock signal; the slave can only send data after a communication is intiated with him and the master communicates that he wants to read data from him.
|
|
|
|
|
|
## The protocol
|
|
|
In this section the general functioning of the I2C protocol is described, focusing on our parcticular usecase: we will use the I2C bus with a single master (the microcontroller) and multiple slaves (the sensors). Also, the microcontroller will never actively use his slave features.
|
|
|
|
|
|
In this section the general functioning of the I2C protocol is described, focusing on our parcticular usecase: we will use the I2C bus with a single master (the microcontroller) and multiple slaves (the sensors). Also, the microcontroller will never actively use his slave features.
|
|
|
|
|
|
The master is the only device that can drive the communication generating the clock on the SCL line.
|
|
|
|
|
|
Both SCL and SDA lines have pull-ups in order to drive the signal up by default.
|
|
|
|
|
|
When the master wants to do an operation (a read or a write) on a parcticular slave, it:
|
|
|
|
|
|
1. generates a START condition, that means to drive to the low level the SDA while the SCL is still high;
|
|
|
2. Communicate the address and the operation the master wants to perform. So, in _7-bit addressing_ the address is sent along with the operation bit, 0 for write and 1 for read. In 10-bit addressing there is also a header involved; for further informations see the reference manual.
|
|
|
3. If a slave recognizes his address, the slave pulls the SDA line down in order to send a slave ACK (S-ACK).
|
|
|
So, in total, this prologue would be 7bits (slave address) + 1bit (R/W operation to perform) + 1bit (slave responds with an ACK or the line returns high, so a NACK is received).
|
|
|
3. If a slave recognizes his address, the slave pulls the SDA line down in order to send a slave ACK (S-ACK). So, in total, this prologue would be 7bits (slave address) + 1bit (R/W operation to perform) + 1bit (slave responds with an ACK or the line returns high, so a NACK is received).
|
|
|
|
|
|
After this phase, if a slave responds with an ACK, the operation will be performed:
|
|
|
|
|
|
- Read (R/W bit is high): The slave sends a byte and if the master sends an ACK the slave will send another byte, the communication is stopped otherwise;
|
|
|
- Write (R/W bit is low): The slave receives a byte and responds with an ACK. After the ACK the master could continue sending bytes or stopping the communication.
|
|
|
|
... | ... | @@ -28,18 +30,19 @@ After the data transfer a STOP condition is sent (consisting in driving the SDA |
|
|

|
|
|
|
|
|
# Electronic setup
|
|
|
|
|
|
In order to use properly the I2C bus a pull-up circuit should be implemented. The SCL and SDA GPIOs should be setted with the mode `ALTERNATE_OD` (alternate function with open-drain). This is because master and slaves should only be able to pull down the line and, when they release the line, the signal should be pulled up. If the `ALTERNATE_OD` mode is setted but no pull-up circuit is implemented the driver could hang forever. A lot of sensors implement on their own the pull-up circuit, so it could be enough; however, if no sensor is attached the hanging of the system could be caused anyway.
|
|
|
|
|
|
# _Deadlocks are a feature, not a bug!_
|
|
|
|
|
|
Kidding, they are not. Unluckly the I2C bus can get in a locked state in particular conditions. If we are in the situation where the slave is pulling down the SDA but is no longer receiving clock signals, the slave won't ever stop pulling SDA down, causing all the other devices to see the bus as busy. This means that no device can become a master, so on the SCL line nobody will issue the clock cycles the slave is expecting.
|
|
|
This could happen when the state machine inside the slave is messed up due to lost clock cycles; in real life this could happen for:
|
|
|
Kidding, they are not. Unluckly the I2C bus can get in a locked state in particular conditions. If we are in the situation where the slave is pulling down the SDA but is no longer receiving clock signals, the slave won't ever stop pulling SDA down, causing all the other devices to see the bus as busy. This means that no device can become a master, so on the SCL line nobody will issue the clock cycles the slave is expecting. This could happen when the state machine inside the slave is messed up due to lost clock cycles; in real life this could happen for:
|
|
|
|
|
|
- A reset of the master without a power-cycle;
|
|
|
- A glitch on the SCL line, causing a loss of at least one clock cycle;
|
|
|
- The breaking/disconnection of the SCL line;
|
|
|
|
|
|
The locked state manifests as in the following image, so with the SCL line released (high state) and the SDA line pulled down (low state).
|
|
|
The locked state manifests as in the following image, so with the SCL line released (high state) and the SDA line pulled down (low state). The first row represents the clock signal generated by the Master (the microcontroller); the second row is the clock signal received by the Slave (the sensor); the third row, instead, represents the data line.
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
The recovery of the locked state is performed doing the CPR to the slave, so literally forcing a set of clock cycles on the SCL line (changing the SCL pin to the OUTPUT mode and forcing high/low the line at the right frequency). This injects to the slave the necessary clock cycles in order to end the current transaction and restore to idle mode. |
|
|
\ No newline at end of file |
|
|
The recovery of the locked state is performed doing bit-banging of the clock from the master to the slave (literally is like doing CPR to the locked slave), so we force a set of clock cycles on the SCL line (changing the SCL pin to the OUTPUT mode and forcing high/low the line at the right frequency). This injects to the slave the necessary clock cycles in order to end the current transaction and restore to idle mode. |
|
|
\ No newline at end of file |