I²C Random Read

I want something very specific…

An I²C random read can be used to read a single byte of data from a specific address, or it can be used to move the address pointer for use in asequential read.

i2c-random-read.png

EEPROM Byte Write Procedure

  1. Check for bus idle
  2. Send start condition, wait for it to complete
  3. Write control byte (with device address)
  4. Check for bus idle
  5. Write high byte of memory address
  6. Check for bus idle
  7. Write low byte of memory address
  8. Check for bus idle
  9. Send restart condition - wait for it to complete
  10. Write control byte
  11. Check for bus idle
  12. Read one byte
  13. Send NACK condition - wait for ACK sequence to complete
  14. Send stop condition, wait for it to complete
  15. Wait for write cycle to complete (ACK from EEPROM)

Example Code (PIC18)

Specific I²C function names and parameters may differ depending on your target device, compiler, and/or peripheral library.

The first half is the same as for a byte write while the second half is like a current address read, but with a "Repeated Start" so the bus doesn't go idle.

IdleI2C();// Ensure module is idle
StartI2C();
while (SSPCON2bits.SEN);
// Initiate START condition
// Wait until START condition is over
WriteI2C(0xA0);// Write 1 byte - R/W bit should be 0
IdleI2C();// Ensure module is idle
WriteI2C(HighAddress);// Write high address byte to EEPROM
IdleI2C();// Ensure module is idle
WriteI2C(LowAddress);// Write low address byte to EEPROM
IdleI2C();// Ensure module is idle
RetartI2C();
while (SSPCON2bits.RSEN);
// Initiate RESTART condition
// Wait until RESTART condition is over
WriteI2C(0xA1);// Write 1 byte - R/W bit should be 1 for read
IdleI2C();// Ensure module is idle
getsI2C(&dataOut, 1);// Read in one byte
NotAckI2C();
while (SSPCON2bits.ACKEN);
// Send NACK condition
// Wait until ACK sequence is over
StopI2C();
while (SSPCON2bits.PEN);
// Send STOP condition
// Wait until STOP condition is over

A "repeated start" or "restart" doesn't return the bus to an idle state, which prevents another Master or Slave from grabbing the bus in the middle of the random read sequence.