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 a sequential read.
EEPROM Byte Write Procedure
- Check for bus idle
- Send start condition, wait for it to complete
- Write control byte (with device address)
- Check for bus idle
- Write high byte of memory address
- Check for bus idle
- Write low byte of memory address
- Check for bus idle
- Send restart condition - wait for it to complete
- Write control byte
- Check for bus idle
- Read one byte
- Send NACK condition - wait for ACK sequence to complete
- Send stop condition, wait for it to complete
- 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.