I'm still trying to wrap my head around I2C as well as the ATTiny. I've found plenty of tutorials on how to use the tiny as an I2C slave as well as master, but is it possible to use it as both at the same time?

I basically want to create a device similar to the BlinkM smart LED but that also had a connected EEPROM for some extra storage. Maybe there's another way to connect the EEPROM but I didn't figure I'd have enough pins (only talking about the 8 pin ATTiny variety)....

Any thoughts of how to do this?

Clarification: Note, that ONLY the ATTiny needs to access the external EEPROM or should access it. I definitely want it to be on a separate bus. So I realize that I will need two pins for ATMega -> ATTiny and 2 more for ATTiny to EEPROM (hopefully leaving me 2). My major concern here is if only 2 pins on the ATTiny can be used for i2c or if you can configure ANY 2 pins for that?

  • \$\begingroup\$ your question is not clear - why do you need I2C in slave and in master mode symultaneously? You want to connect to external eeprom chip via I2C? \$\endgroup\$ – miceuz Oct 1 '12 at 8:11
  • \$\begingroup\$ Yes... I want to ATTiny to be an I2C slave to larger ATMega chip (again, like with the BlinkM) but then have the EEPROM be an I2C slave to the ATTiny NOT the ATMega. The ATTiny / EEPROM combination would end up being their own discrete drop-in part (again, like the BlinkM... but with it's own large EEPROM). \$\endgroup\$ – Adam Haile Oct 1 '12 at 12:27
  • \$\begingroup\$ If you want it not to appear on the same bus to the ATMega, then it needs to have its own bus. That will require a couple of extra pins. I take it the problem is not enough pins on the ATTiny? \$\endgroup\$ – pjc50 Oct 1 '12 at 14:06
  • \$\begingroup\$ If there is no need for both masters to use the EEPROM, if only the ATTiny needs to use it, then it has its own internal EEPROM that it can use instead in sizes of 128/256/512 bytes. Is that large enough? \$\endgroup\$ – Jon L Oct 1 '12 at 16:04
  • \$\begingroup\$ Correct, the EEPROM needs to be on it's own bus that the ATMega cannot access. And, no, the built in EEPROM on the ATTiny is not large enough. I'm planning on using a 32KB EEPROM. \$\endgroup\$ – Adam Haile Oct 1 '12 at 20:44

Toby says you'll need two I2C buses, but that's not necessarily so. In this answer I point at the information in the LPC930 datasheet how to switch between the two modes on the same bus.

I guess by "at the same time" you mean in one and the same application, and that's not so hard. If you want to write or read on the bus as master you wait until the bus is free, switch to master mode and start clocking. After the message is sent/received switch back to slave mode and listen for messages from other masters.

Electrically collisions are not a problem, since the bus is a wired-OR. Protocol-wise you may have a problem when two masters would claim the bus simultaneously, but then the message will be so messed up that you won't get an acknowledge, so you know you have to send it again. Most protocols will retry after a random time, which should be different for each master, so that the collisions don't keep repeating.

Alternatively, you can make a token-passing protocol of it, where the controller which has the token is master, and after doing its business, can pass the token to the other master. It then switches to slave mode, and waits until it receives the token back. Only then it can switch to master mode again.

  • \$\begingroup\$ Please see clarification... \$\endgroup\$ – Adam Haile Oct 1 '12 at 20:53

This should be possible. The configuration that you want is called "multi-master"


Your device can be a slave for most of the time, but when you want it to talk to the EEPROM, you can programmatically switch it to be a master. So long as you follow bus arbitration rules, then this should be fine. A snippet from the above link on what both your I2C masters must do:

a) Being able to follow arbitration logic. If two devices start to communicate at the same time the one writing more zeros to the bus (or the slower device) wins the arbitration and the other device immediately discontinues any operation on the bus.

b) Bus busy detection. Each device must detect an ongoing bus communication and must not interrupt it. This is achieved by recognizing traffic and waiting for a stop condition to appear before starting to talk on the bus.

If you plan to use a multimaster device on a bus it is essential that all masters are multimasters. A single-master is simply a device, which does not understand the above mechanisms. If a singlemaster and a multimaster are connected, the singlemaster may well interrupt the multimaster causing unpredictable results.

Going over the datasheet for the ATtiny, it looks like there is some support for this. Take a look at the USISR – USI Status Register in the datasheet and namely these two bits:

• Bit 5 – USIPF: Stop Condition Flag When two-wire mode is selected, the USIPF Flag is set (one) when a stop condition has been detected. The flag is cleared by writing a one to this bit. Note that this is not an interrupt flag. This signal is useful when implementing two-wire bus master arbitration.

• Bit 4 – USIDC: Data Output Collision This bit is logical one when bit 7 in the USI Data Register differs from the physical pin value. The flag is only valid when two-wire mode is used. This signal is useful when implementing Two-wire bus master arbitration

So it looks there is enough support to do it, you just have to handle it in software, which will unfortunately make your software more complicated, but I suppose that is the tradeoff expected here. As mentioned, you have to make sure that both your masters adhere to the bus arbitration rules, and I imagine the other chip you're using will have a similar register like the one found in the ATtiny, but make sure it indeed does otherwise this won't be possible.


I left a comment earlier about this too, but here is an alternate suggestion to all of this:

If there is no need for both masters to use the EEPROM, if only the ATTiny needs to use it, then it has its own internal on-chip EEPROM that it can use instead in sizes of 128/256/512 bytes. Is that large enough?

  • \$\begingroup\$ Please see clarification... \$\endgroup\$ – Adam Haile Oct 1 '12 at 20:57

An I2C bus usually has one master and one or more slaves. The bus is shared between all slaves, each with their own unique address. Each message on the bus is addressed to one device at a time.

In order for your microcontroller to be slave to an external master while simultaneously being master to the eeprom, it can have two i2c buses. An i2c bus is only 2 wires (plus a common ground), so you may have enough pins.

  • \$\begingroup\$ while this is by far the most common way people tend to use I2C, multiple masters are allowed by the standard using a well defined arbitration protocol that is supported by most microcontroller hardware interfaces. The issue of address collision is the bigger problem in the context of this question really. \$\endgroup\$ – vicatcu Oct 1 '12 at 19:25

I2C natively supports multiple masters with arbitration. The problem I think you will run into is that the BlinkM library (or more formally the Arduino Wire library) I don't think implements the handling of arbitration states in the I2C interrupt vector so even if you implement the I2C drivers to do it correctly on the ATtiny, the "real" I2C master won't deal with it unless you modify Wire or use an alternative I2C library that does handle multi-master arbitration. Furthermore, you'll have to somehow guarantee that you'll have to use I2C EEPROMs that have hardware selectable address bits so they can be made to not conflict on the bus as well. Basically, I think you'll find this is more complicated than its worth to get working in a useful generalized way.

In response to the clarification, you can always "bit-bang" I2C using any two GPIO pins. That just means you implement the I2C behavior entirely in software (in case that wasn't clear). Speed isn't really an issue when you are acting as a master (i.e. controlling the EEPROM) since you control the bus clock that the slave uses. You should however, use your hardware I2C pins for the slave function of your microcontroller since that will require you to be as quick as possible in servicing events from the master. Hope that helps.

  • \$\begingroup\$ Please see clarification... \$\endgroup\$ – Adam Haile Oct 1 '12 at 20:54
  • \$\begingroup\$ @AdamHaile see response to clarification \$\endgroup\$ – vicatcu Oct 3 '12 at 3:24
  • \$\begingroup\$ Cool... I will probably give that a try. Thanks :) \$\endgroup\$ – Adam Haile Oct 3 '12 at 4:44

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.