Electronic – Multiple SPI devices using single select line


I wish to send data back-and-forth between a Master and one of a few dozen slaves within a mesh-network style arrangement.

Assume that all units are (identical) microcontrollers within my control, i.e., can be programmed. In the interest of maximizing data throughput to several hundred kb/s, I am considering SPI.

Are there any strategies or existing implementations to achieve such a topology while using only 1 or 2 pins/signal-lines in total, aside from MOSI, MISO, and CLOCK?

These 1 or 2 pins could be for a custom handshaking or slave-selection method, however what I don't want to do is spend one pin per EACH slave (or use multiplexing) due to some constraints, including the wiring arrangement and limited physical space on the hardware of each master and slave.

I see I2C raising its hand here, but would like to maintain the advantages of SPI (e.g., simplicity and much faster data transfer). I expect throughput would decrease somewhat in this kind of bus implementation especially if I use software-addressing/polling, but perhaps there is some smarter solution to not drag it down too much?

Best Answer

The solution here is to use SPI in an intelligent manner with embedded addressing. Each of the slave devices would be deployed with some type of device selection code using one of the following techniques:

  1. Have a small 6 or 8 position "dip switch" that can be set to the address in binary format.
  2. Use small rotary selector switches that encode a 4-bit value based upon the 0 -> 9 setting of the selector. Two of these can select addresses from 00 to 99.
  3. Have a setup mode in the slave where you interactively set the address and save it into non-volatile memory such as EEPROM or FLASH in the slave device.

When you devise your SPI protocol set it up so every slave device is connected in parallel so all receive the SPI_SEL, SCLK and MOSI signals. They are all also connected to MISO but keep their output driver tristated until they are addressed.

You utilize the SPI_SEL as a framing control so that all the slaves are alerted to the start of a SPI frame when the SPI_SEL signal goes to its active level. The first byte of the SPI data clocked out from the master on the MOSI is the address value for the desired slave device. All the slave devices compare the address received against their specified address. Upon a match the addressed slave will enable its output onto the MISO line and remain actively connected until the SPI_SEL goes to its inactive level.

This scheme adds very little overhead to the overall SPI bandwidth and makes the connection wiring easy to implement. Since it seems that each of the many slaves are all on separate boards it may become necessary to buffer the interface lines so that the fanout to all the slaves has enough drive to properly operate the interface. One way to do this if longer distances are possible is to deploy the usage of differential drivers and receivers on the signal lines such as in a common chip like as an RS422 type transceiver. A chip that would work well to create the differential interface would be the TI SN75C1168. Two of these at each slave would provide the receivers for SPI_SEL, SCLK and MOSI. The one of the drivers can support the MISO signal with its tri-state control. The same two chips can be used at the master side to provide for the needed three drivers and one receiver on that end of your differential SPI bus.

enter image description here

(Picture Source: http://www.ti.com/lit/ds/symlink/sn75c1168.pdf)