I'm designing my own data protocol for communication between PICs, ICs, etc. and in the specification I'd like to compare it to the existing I2C protocol.

There are two types of operation on the I2C bus:

  • Write operation: master writes START, address, data (the slave sends ACKs only)
  • Read operation: master writes START, address. Slave sends data, master sends ACK / NACK.

Just to get this clear for me: is there any way to use these operations, according to the protocol specification, to read and write data within one operation? You would win speed because you don't have to send the address twice. So is this possible?

  • 2
    \$\begingroup\$ What about something like SPI? I believe you can do bi-directional communication since there are separate in/out data lines. \$\endgroup\$ – dext0rb Jan 9 '13 at 21:17
  • \$\begingroup\$ Yes, but that's not my question. \$\endgroup\$ – user17592 Jan 9 '13 at 21:41
  • \$\begingroup\$ it is pretty obvious that one data wire cannot be use for a simultaneous read and write! \$\endgroup\$ – Chetan Bhargava Jan 10 '13 at 7:24
  • \$\begingroup\$ That's why I changed the question to `read and write data within one operation', so that it doesn't have to be at the exact same time. \$\endgroup\$ – user17592 Jan 10 '13 at 7:25
  • 1
    \$\begingroup\$ Do we really need another protocol for inter-IC communication? \$\endgroup\$ – Nick Johnson Jan 10 '13 at 10:00

There is no way to do what you want and still follow the I2C protocol. The closest you can get is the "Repeated Start" condition. Even with a repeated start, you must send the address a second time to read.

"Repeated start" is used in the case of a multi-master system, and it allows a master to lock the bus and prevent it from being taken over by another master. Instead of issuing a stop bit, the master sends another start bit, and retains control of the bus until the stop bit is sent. In this way, you could call the repeated start a single "operation", even though multiple reads/writes can be performed.

In your theoretical protocol, how much speed do you think you'll gain by not issuing the address a second time? Is that time savings needed for your design?

  • \$\begingroup\$ There are some realistic scenarios where being able to alternate reads and writes in a single transaction could make a greater-than 2:1 speed difference. Potentially much greater with some DMA subsystems. \$\endgroup\$ – supercat Mar 20 '15 at 6:21

Not at all possible. Since there is a single data in and out pin, you can't read and write simultaneously.

  • \$\begingroup\$ It does not have to happen simultaneously. It could be something like: Master writes START, address, data, sends a NOW YOU WRITE and then slaves writes, end transmission. But that isn't possible in I2C? (I edited my question: is it possible to read and write in one operation?) \$\endgroup\$ – user17592 Jan 9 '13 at 21:42
  • 3
    \$\begingroup\$ @CamilStaps - But you did ask about "read and write data at the same time". What about that does not specify happening simultaneously? \$\endgroup\$ – Michael Karas Jan 9 '13 at 21:46
  • \$\begingroup\$ Yes, that was not well asked. What I meant was in the same operation. Sorry for the confusion. \$\endgroup\$ – user17592 Jan 10 '13 at 6:39

I2C uses the least significant bit of the address byte to control whether or not the operation is a read or write. No matter what, the address is always sent at the beginning of a transaction, and is sent if there's a restart, so your statement about not having to send the address twice doesn't make sense to me.

In a "combined" write/read, there's still address overhead:

  • Master sends Start, then slave address + write; slave acks
  • Master sends data, slave acks
  • Master sends Restart, then slave address + read; slave acks
  • Slave sends data, master ACKs/NACKs
  • Master sends Stop

If you want truly simultaneous communication, you need multiple independent I2C busses (and obviously multiple masters and slaves).


You want to save speed by not writing an extra 8 bits at 100/400/1000khz? You would only be saving yourself (at 100khz speed) 8/100000 seconds (0.08 milliseconds/80 microseconds). It's a trivial amount of data.

But, It can't be done in the i2c or SMBUS standard. But if you are writing your own data protocol, go right ahead, it's your protocol, you decide if you can combine read/right. Design it so that a repeated start means only the same slave that was addressed with the initial start goes into read mode without addressing.

Start - Write Address - Data - Data - Restart - Read - Read

It won't be compliant with the i2c standard though.

  • \$\begingroup\$ I wonder why neither the I2C standard nor typical slave implementations provide any means for switching direction mid-transaction [e.g. alternating reads and writes] nor allow slaves to participate in arbitration? If every slave had a unique 32-bit ID, such abilities would make it possible to have a command to, e.g. "read out the ID of all attached slaves" without requiring slaves to have unique pre-assigned addresses. \$\endgroup\$ – supercat Dec 6 '14 at 23:19
  • \$\begingroup\$ @supercat 1-wire, your thinking of 1-wire. \$\endgroup\$ – Passerby Dec 7 '14 at 0:47
  • 1
    \$\begingroup\$ I wasn't thinking of one-wire (whose searching method I have used, btw), but rather of a situation where I would have liked to have multiple slaves on a two-wire bus and have them auto-report their IDs simply and cleanly. If I2C slave hardware could handle loss of arbitration in a manner similar to masters, such a thing could have been implemented very elegantly. \$\endgroup\$ – supercat Dec 10 '14 at 4:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy