The 4-wire SPI bus has a considerable speed advantage over I²C, but unfortunately so far as I know has no standard way to perform handshaking without using extra wires beyond the four (and four wires is already annoying enough as it is).

For a recent project where the slave was a CPLD, I implemented a nice approach to provide handshaking in one direction (slave can make master wait) and also incidentally eliminate the need for the /FS line. The signals are Clock, MOSI (master-out/slave-in) and MISO (master-in slave-out).

Clock idles low; both MISO and MOSI output on the rising edge of Clock and are sampled on the falling edge. Two or more consecutive rising edges on MOSI wire while Clock is low will reset communication.

When Clock is low and MOSI is high, MISO will indicate whether the slave is ready. When clock and MOSI are both low, MISO will indicate whether the slave wants attention.

While this approach works very nicely when communicating between my CPLD and my controller, it would be nice if the same approach could be used when communicating between two standard microcontrollers. The biggest features that would be necessary to make this work nicely would be:

  1. the ability of the slave controller to reset itself upon receiving some number (probably 2 or 3) of rising edges on MOSI while clock is idle;
  2. the ability of the slave to control the clock-idle state of MISO, and preferably load separate values for use when MOSI is high or when it is low;
  3. preferably, the ability for the master to control the state of MOSI that will be output when the clock is idle between bytes (in my protocol, the commands which need handshaking have the LSB set, but that's a bit of a nuisance);
  4. for buffered SPI ports, the ability for the master to wait on the slave's data line.

Do any common controllers or slave devices offer such features, or work in such a way?


"An introduction to asynchronous circuit design" by Davis and Nowick (in particular, Figure 1 and Figure 2 and the nearby text) describes two handshaking protocols as "pervasive". The 4-cycle protocol, aka RZ (return to zero), 4-phase protocol, and level-signaling. And the similar but more complicated to implement 2-cycle protocol, aka transition, 2-phase, or NRZ (non-return to zero) signaling -- which is very similar to the "data strobe encoding" used by SpaceWire and FireWire. Either one sounds like it has most of the features you requested -- it's SPI-like in that there are exactly 4 signals, all 4 signals are one-way (no passive pull-ups), the master can pause the slave indefinitely until it is ready for the next bit from the slave, etc. It also has a feature supercat requested that SPI doesn't have: the slave can pause the master indefinitely until it is ready for the next bit from the master.

I don't know of any chips that have the 4-cycle protocol built in, but it looks like it would be easy to bit-bang on a microcontroller or a CPLD. In fact, it looks like it would be easier to bit-bang than SPI, since (like SPI) the master has no timing requirements, and (unlike SPI) the slave has no timing requirement either.

Is it possible to use the 4-phase protocol for synchronous bit transfers, and somehow build a higher-level protocol on top of that to get the other things supercat wants -- byte alignment, start-of-command frame alignment, attention/busy/idle states, etc?

  • \$\begingroup\$ For a protocol to support bit-banging a slave with no timing requirements would require both master and slave to have two outputs (two wires that were open-collector at both ends would probably suffice in practice, though speed would not be wonderful and I'm not sure one could arrange a protocol that wouldn't have trouble if master+slave timing lined up precisely 'wrong', though one could use a random retry pattern to minimize the harm therefrom). \$\endgroup\$ – supercat Feb 28 '11 at 16:11
  • \$\begingroup\$ One of the things I'd like in a handshaked SPI slave, though, would be the ability to work with a normal SPI master; ehnahced SPI master hardware could offer improved capabilities (e.g. DMA with handshake) but even a normal device could be useful. Further, it would be desirable to have a slave MCU that could share the bus with other peripherals (e.g. if a slave receives a certain command, it would enable some other device and ignore the bus until it receives the next start sequence). \$\endgroup\$ – supercat Feb 28 '11 at 16:14
  • \$\begingroup\$ @supercat: I'm quite sure that people have implemented a protocol that can handle any master or slave timing -- the 4-cycle protocol. See Davis and Nowick for details. These people did it, therefore it must be possible. \$\endgroup\$ – davidcary Mar 7 '11 at 3:45
  • \$\begingroup\$ @davidcary: For a protocol to be timing-independent with general-purpose I/O, the party sending data must have two wires over which it can transmit (a 'ready' signal as well as a signal for the data itself). A small amount of hardware can eliminate software timing requirements, but in general slave software is hard. \$\endgroup\$ – supercat Mar 7 '11 at 16:40
  • \$\begingroup\$ @supercat: I expected a response something like either "Yes, the 4-cycle protocol sounds like it meets my requirements", or "Sorry, I absolutely need backwards compatibility with off-the-shelf SPI hardware, so the 4-cycle protocol won't work for me, no matter how 'pervasive' or 'superior' it may be", or else "Sorry, that won't work for me because (something)". The SPI-like protocol the original question describes sounds very clever, and I wish you great success using and tweaking it. \$\endgroup\$ – davidcary Mar 8 '11 at 3:58

The closest thing I know for what you're asking is UART/RS-232 with RTS/CTS handshaking (4 wires total).

National Semiconductor's LMX9838 (it's a Bluetooth module) uses that communication protocol as a slave device. And you can implement it with 2 extra GPIOs in any microcontroller.

Ultimately you can implement any type of handshaking with any pair of Master-Slave devices, as long as you have control over a couple of extra GPIOs in both (i.e.: Using uC, FPGA, CPLD...).

  • \$\begingroup\$ Certainly one can add handshaking by adding I/O's, but normal SPI devices already require a somewhat excessive number of pins (4), when three wires are plenty to produce a master-slave bus with handshaking. I would have rather used a microcontroller than a CPLD for my SPI slave, but the device has to consume minimal power when idle, and I wanted to use three wires rather than five. Thus my desire for a microcontroller with features that would allow nice handshaking. \$\endgroup\$ – supercat Feb 26 '11 at 0:20
  • \$\begingroup\$ I'm not sure if a hardcoded handshaking in a bus would lead to less power consumption. After all, that extra feature requires Driving or Sinking a signal, no matter where that extra control comes from (your own or hardcoded) or goes into (as in: it may go into an extra line, or into an existing line as in your example). I think the Handshaking's algorithm itself would mean more in terms of time and power optimization. \$\endgroup\$ – Arturo Gurrola Feb 26 '11 at 0:44
  • \$\begingroup\$ In my application, when clock and MOSI are both low, the CPLD will drive MISO high if it has something it wants to say, and low otherwise. Since there are no passive pull-ups, there is no static current drain. There are a variety of approaches that can be used to trade off half- vs full duplex, stateless idle behavior (when MOSI and CLK are both low, MISO will be high when the CPLD requires attention, regardless of what state the CPLD is in), in-line receipt of data without having to send anything, etc. \$\endgroup\$ – supercat Feb 26 '11 at 21:29
  • 1
    \$\begingroup\$ If nothing like what I describe already exists, I'd be more than happy to write up a specific proposal if anyone would be interested. If such a thing does already exist, however, why reinvent the wheel? \$\endgroup\$ – supercat Feb 26 '11 at 21:34

If you're looking for something compatible with off-the-shelf SPI systems, and yet somehow uses fewer wires, you might like the Roman Black Shift1 system for 1-wire shift registers.

  • 1
    \$\begingroup\$ That's cute, though the speed would be somewhat limited. \$\endgroup\$ – supercat May 5 '11 at 19:40
  • \$\begingroup\$ @supercat Forget the speed, this is really cute. ;p \$\endgroup\$ – jpc Sep 8 '11 at 13:23
  • \$\begingroup\$ @jpc: I just re-looked at the link; for the LCD-driving with the addition of a Schmidt-trigger chip, one could probably improve the speed immensely by tying the 74HC595's register-clock to the shift-clock, and driving E with a delayed version of the CPU signal. Drive the pin high for a long time to cause the display to latch the shifted data (note that the output pins would reflect the shift register state before the last bit gets shifted). The Schmidt-trigger driver would be used because driving E with a slowly-changing signal could make the system unduly sensitive to noise. \$\endgroup\$ – supercat Sep 8 '11 at 15:58

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.