1
\$\begingroup\$

I'm designing a board using the ATtiny84A which uses a USI (Universal Serial Interface), and as such there is no dedicated I2C and SPI peripheral.

I have gotten I2C to work and tested it by communicating with a 24AA02UID EEPROM.

I have gotten Slave SPI to work and have tested it by returning requested data to a master.

My question is: if the ATtiny has no control over if/when the master decides to start an SPI transaction, is it possible to use these same USI pins to query the EEPROM over i2c?

enter image description here

I'm guessing that allowing the external SPI master to use the i2c pins that are attached to the EEPROM willy-nilly is going to cause strange data to appear on the EEPROM if/when the master happens to send a byte corresponding to the i2c address of the EEPROM chip, followed by other random data.

Or, am I worrying too much? I was hoping that the SPI signals would be disregarded by the EEPROM due to improper i2c protocol formatting.

The problem of the external SPI master taking control of the lines during a i2c communication sequence is troubling, however.

Is the best solution to use a tristate buffer that my ATtiny84a can toggle to cut off the external SPI master from the lines in question whenever it wants to read/write to the EEPROM?

EDIT:

It would seem that the cheapest and easiest and most awesomest solution is to simply use a different ATtiny chip. I think I will go with the ATtiny88 which has a dedicated TWI and SPI port (on separate pins):

enter image description here

\$\endgroup\$
1
\$\begingroup\$

You properly identified the biggest problem - SPI host might try driving clock/data line up while I2C master or slave pulling it down.

The second problem is timing, because SPI request can come in the middle of I2C packet. What happens next depends on particular I2C slave. It might either ignore the data, wait for next clock cycle, wait for stop condition or simply do something weird/unexpected.

The easiest solution would be already suggested separation of the channels and bit-banging I2C. However this is only possible if you have 2 pins and processor time available, and slower I2C speed is acceptable.

If the above does not work for you, some additional hardware is necessary. Specifically, you need two 3-state gates to disconnect SCK and MOSI lines coming from SPI master, and one more gate to disconnect SCL input of I2C slave (when SPI gates are open). This is the solution you already described in your question and it will work, to a point. The potential problem here is that SPI master not knowing that you are not listening will accept whatever state you have on MISO line as valid reply.

If CS line from master is available and you want to be more master-friendly you can try to use I2C clock stretching as a way to pause I2C transaction to handle SPI request. The idea is to put latches on I2C bus to "freeze" the signals coming from attiny at the moment CS line is activated. Several things will happen then:

  • the SCL and SDA coming from attiny will stop where they were;
  • the ISR in attiny will reprogram USI to SPI;
  • in the end it will open SCK and MOSI gates and handle incoming request.

When CS line is released the attiny will close SPI gates, generate "stop" condition for I2C slave, and reprogram USI back. This is very complicated scenario and some slave devices might not like it (master clock stretching was deprecated in recent specifications).

In short - if you can use bit-banging, use it. If not - be prepared for some extensive tinkering.

\$\endgroup\$
  • \$\begingroup\$ Thanks for confirming my suspicions. I think I'm simply going to use an ATtiny88 instead (with dedicated TWI and SPI peripherals on separate pins). \$\endgroup\$ – macdonaldtomw Jun 13 '18 at 14:11
  • \$\begingroup\$ That would be ideal and indeed "awesomest" solution. Good luck. \$\endgroup\$ – Maple Jun 13 '18 at 14:15
2
\$\begingroup\$

Is the best solution to use a tristate buffer that my ATtiny84a can toggle to cut off the external SPI master from the lines in question whenever it wants to read/write to the EEPROM?

There may be a simpler solution.

... ATtiny84A which uses a USI (Universal Serial Interface), and as such there is no dedicated I2C and SPI peripheral.

Well, USI is a dedicated I2C and SPI peripheral. But only one kind of bus in any given design.

Can I use an ATtiny84 as SPI slave and I2C master in the same application

Yes, that's possible.

  • Implement the I2C bus master using software bit-banging. This allows you to use any GPIO pins for the I2C bus.
    The I2C buses usually run a leisurely rate, and bit-banging an I2C master in firmware is a viable option.
  • Use the USI hardware for SPI slave.
    Implementing an SPI or I2C slave in firmware is impractical at any reasonable data rate.
\$\endgroup\$

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.