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:
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.
(Picture Source: http://www.ti.com/lit/ds/symlink/sn75c1168.pdf)