I have 2 MCUs and I want to connect them together over I2C bus. MCU1 will be Master while MCU2 will be Slave. Only these 2 MCUs are on the bus. This configuration is fixed and I cannot change it.

There are 2 scenarios. In first scenario only MCU1 and MCU2 are on the bus. While in a second scenario there are some additional I2C devices also connected on this shared bus.

My main purpose to connect them as above is to send data from MCU2 (Slave) to MCU1 (Master).

So far what i understand about I2C is that it is a command-response protocol. The master gives command to slaves, and then the slaves respond to this command and send their data to the master. The slaves cannot send their data on their own without receiving the command first.

If the master wants to receive 32 bytes of data from the slave then what command will it send to the slave and then how will the slave assert that it has received the valid command for data send? I think this is called 'block-mode' data transfer.

My slave address is fixed as 0x08.

  • 1
    \$\begingroup\$ If you want to communicate from the MCU2 to MCU1, the MCU2 must be in master mode and the MCU1 in slave mode. In your case, you must put MCU1 and MCU2 in slave mode. When the MCU1 or MCU2 need to communicate on the bus, it status must be changed to MASTER and then it will ask on the bus. \$\endgroup\$
    – Foxrider83
    Nov 12, 2019 at 9:27
  • \$\begingroup\$ Its a little confusing above about the change of mode for MCU2. Why do I need to change the modes? Can I do the data transfer with fixed modes for MCU1 and MCU2? \$\endgroup\$
    – alt-rose
    Nov 12, 2019 at 12:42

1 Answer 1


Fortunately or unfortunately, it's up to you to come up with a protocol for this scenario as you control both sides. Like you say, the slave can only respond to transfers initiated by the master. Your master then needs to poll the slave (ask for data on a recurring schedule), unless you have another way for the slave to communicate when data is ready. (The latter is commonly solved with a separate interrupt line.) The master and slave need to both agree on a special response when the slave doesn't yet have data available. The slave also needs to reset its response to this "no data" value after being queried by the master, to avoid sending the same data twice.

The easier way would be to switch the roles of master and slave, so it's the master that initiates sending data to the slave.

If you need to also communicate with other slaves on the same I2C bus, you will however be limited in which device can be the master, unless you use the multi-master mode of I2C.

The particular I2C API calls required depends on what device and HAL you are using. On a physical level, it will be a "I2C read" initiated by the master, where the master reads 32 bytes after sending the slave address.

  • \$\begingroup\$ The library function that I am using has option to select I2C address as 7-bit or 10-bit. How should i decide about it? \$\endgroup\$
    – alt-rose
    Nov 12, 2019 at 10:47
  • 1
    \$\begingroup\$ Doesn't really matter as long as you use the same setting on both sides. As you don't need 10-bit, I suggest 7-bit. \$\endgroup\$ Nov 12, 2019 at 10:54
  • \$\begingroup\$ It means that 7-bit address means that 7-bits for address and additional 3 bits for S, R/W, ACK bits. Similarly 10-bit address means 10-bits for address and additional 3 bits as above AND not as 7+3 bits = 10 bits? \$\endgroup\$
    – alt-rose
    Nov 12, 2019 at 11:45
  • 1
    \$\begingroup\$ Yes. I don't think "single word-mode" is a term used. I2C works on a byte level. Your master could query the slave with a single byte to check if data is available, but it will be more complex to get two different transmission lengths to work. I2C can be complex enough to debug as it is. \$\endgroup\$ Nov 12, 2019 at 11:54
  • 1
    \$\begingroup\$ It is common to use a concept of "registers" on top of the basic I2C, where one byte is used as address among a range of custom-defined value slots (for lack of better word) within the addressed slave. Not all chips use registers and indeed you have no use of this since you only report one 32-byte parameter. To use registers you would need to implement it in the slave. Linux i2cset only works with registers. i2cget might not use registers when not specifying one -- I don't know. \$\endgroup\$ Nov 12, 2019 at 13:46

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.