3
\$\begingroup\$

I am using a PIC18F25K80 with multiple slave devices. All of them uses I2C except one. What i want to know is that can i first use I2C with the devives that uses I2C and then close I2C, change clock speed and switch to SPI mode ? Is this poosible without causing a conflict ?

Note - When I am in the I2C mode the chip select is set so that the device using SPI mode is inactive. Only after finishing the I2C mode I am making the device active.

\$\endgroup\$
5
  • \$\begingroup\$ remotely related thread: electronics.stackexchange.com/questions/34585/… \$\endgroup\$ Jun 19, 2015 at 22:47
  • \$\begingroup\$ I think what you've described should be okay, as long as nothing on I2C tries to talk when you're using SPI, and vice versa. It's unfortunate that just one uses SPI. You're not able to find a replacement that uses I2C? \$\endgroup\$ Jun 19, 2015 at 23:42
  • \$\begingroup\$ the device that uses SPI is a SD card. I tried to use an I2C bridge but the communication was slow and moreover the buffer size of the bridge was not sufficient. \$\endgroup\$ Jun 20, 2015 at 0:17
  • \$\begingroup\$ Out of curiosity, what IC did you try to use as a bridge? Was it a microcontroller programmed as a bridge, or something more hard-wired? \$\endgroup\$ Jun 20, 2015 at 4:36
  • \$\begingroup\$ It was a SC18IS602B. This is the datasheet \$\endgroup\$ Jun 20, 2015 at 10:53

3 Answers 3

1
\$\begingroup\$

It is possible to share I2C and SPI pins if code which uses each interface can guarantee that devices using the other will never see any sequence of pulses that would cause them to take any action or output any data. To avoid having a sequence of pulses mistaken for an I2C addressing sequence, one should ensure that there are never eight consecutive low-high-low transitions on the I2C clock wire in which the state of the I2C data wire doesn't change. When using a typical SPI master and wiring CLK to SCK and MOSI or MISO to SDA, such a guarantee may not be met since clock and data would change roughly simultaneously, and how the I2C device interprets them would depend upon which signal it saw change first.

If hardware is sufficiently configurable that one could wire CLK to SDA and MOSI to SCK, however, then things could work safely on a typical SPI implementation provided that one avoids I2C addresses containing all zeroes or all ones, since it would be impossible for MOSI to go from low to high and then high to low more than once (much less eight times) without intervening transition on CLK.

One caveat is that some devices try to "auto-detect" the attached interface, and some auto-detection methods may regard signal sequences which would not be defined in one interface as indicating that they should use a different interface. It should be possible for devices to auto-select interfaces through strapping without such false detection if some interfaces which use a subset of the wires require other wires to be strapped together (e.g. for a device which supports SPI and I2C, wiring both /CS and CLK to SDA, and MOSI to SCK) but many devices use crude and unreliable detection methods which may wreak havoc even when they are used with other devices of the same type.

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

I believe the circuit shown below will accomplish what you need. One I2C device is shown, along with two SPI devices. The circuit can be easily expanded to any number of I2C or SPI devices. The additional logic gates required are shared between all devices; there are no logic gates needed per device thus keeping parts count down. Only one extra lead is needed above the maximum four (plus SPI chip selects) needed for the standard I2C/SPI interfaces.

enter image description here

On the PIC18F25K80, SCL (I2C clock) and SCLK (SPI clock) are on the same pin, and SDA (I2C data) and SDI (SPI data in) are on the same pin. SDO (SPI data out) is on a pin by itself.

There are two issues: one is to disable the I2C device(s) when an SPI device is selected (and conversely, to disable the output(s) line of the SPI device(s) when they are not selected); and secondly to deal with the issue of pull-ups on the I2C lines when the SPI SDO lead is driving the SDA/SDI line on the microcontroller.

To handle the first issue, all of the SPI chip selects are AND'ed together. I am showing a 74HCT21 four-input AND with two inputs unused; this could be expanded to any number of chip selects.

If any chip select is 0, then the output of the AND gate is 0, which disables the analog switch, so the SCL clock from the microcontroller is disabled from reaching the I2C device(s). If all chip selects are 1, then the output of the AND gate is 1, enabling the analog switch, so the SCL clock is passed bi-directionally between the microcontroller and the I2C device(s).

For the second issue, a pullup is provided on the SDA pins per the I2C spec. Of course this puts a pullup on the SDA/SDI pin of the microcontroller as well. Since SPI devices are not setup to drive against a pullup, I added a 74HCT07 open-collector buffer to take care of this issue.

The buffer is preceded by an OR gate, with one input from the same lead that enables/disables the I2C clock. So that when the I2C interface is enabled, the OR gate is always asserted, keeping the open-collector output of the buffer high.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This is a clever scheme, but it doesn't seem to allow for clock-stretching on the part of the I2C slave. \$\endgroup\$
    – Adam Haun
    Jun 24, 2015 at 21:46
  • \$\begingroup\$ @AdamHaun Good point, I hadn't thought of that. I replaced the AND gate with an analog switch which should allow the signal to pass both ways. \$\endgroup\$
    – tcrosley
    Jun 25, 2015 at 21:59
1
\$\begingroup\$

I don't think so. A simplistic sharing the clock and data lines between SPI and I2C devices doesn't look like a good idea. Such sharing can introduce a failure mode, that can corrupt the SPI communication.

Imagine that MOSI/SDA and SCLK/SCK are shared. We are communicating to the SPI device. The I2C slave devices “see” the clock and data as well. It's possible that some random combination of bits in the SPI data will look like a start condition and slave address to the I2C device. The I2C slave device will interpret this as a beginning of an I2C read transaction, start transmitting, pulls the MOSI/SDA low. This would corrupt the SPI communication.

So what can be done. You have one SPI device that requires high speed communication, and many I2C devices that can do with relatively slow communication. A situation like yours is not uncommon. Consider these:

  • Use the hardware peripheral (MSSP in the PIC) for SPI. Bit-bang I2C on a pair of separate digital I/O pins.
  • Use MSSP for SPI communication. Connect the I2C devices through an SPI-to-I2C bridge (SPI slave, I2C master).
  • Use the MSSP for both buses. Put the I2C devices on their own branch that has a switch, which can disconnect the I2C devices from the bus during SPI communication.
  • Look for a pic with 2x MSSP peripherals.

edit:
The subject of using the same MSSP for SPI and I2C has come up in the forums a few times over the years: CCS forum 2003, PicList 2005 (solid discussion), Microchip's own forum 2012, EE.SE 2012

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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