Resetting the I2C bus

An EEPROM

The I2C bus (also known as a “two-wire bus”) is used by many serial EEPROMs. For example, a network card may include a small (256-byte) I2C serial EEPROM such as an Atmel AT24C02 that contains the card's MAC address. The driver must read from the EEPROM to find the correct MAC address for the card.

The I2C bus consists of two wires: SCL (serial clock) and SDA (serial data). The SDA line is bidirectional: it is used to transfer data into the EEPROM (such as the address from which to read) and also to read data out of the EEPROM. This uses “open-drain” electronics: either end of the SDA wire is able to pull the SDA line low (i.e. generate a logic “0”), and if neither end actively pulls the SDA line low then it will float high (i.e. will be a logic “1”). This allows data to be transferred in either direction.

I2C devices are usually physically very small, and so have a minimal number of pins. They do not normally have a separate reset pin. This means that a normal system reset will not reset the I2C device. This can cause problems if the system is reset in the middle of a read from the serial EEPROM. The serial EEPROM can be left in a state where it is expecting to continue sending data on the SDA line. The driver must find a way to reset the serial EEPROM back to its idle state.

The code in iPXE which performs this reset can be found in the function i2c_reset().

We expect that everyone will need to ask for help in understanding this code, and we want to see how you interact with potential mentors, so please ask as many questions as you like. We certainly don't expect you to be able to understand and explain this code on your own!