@Nominal Animal: I thought about distributing the signals through other means as well e.g. some form of (differential) PWM. I like the Toslink approach but it seems to me that I would have a huge cable mess on my hands. Assuming I have 18 cabinet that would mean I need 36 Toslink cables.
True. They are easily sleeved or even taped together – being plastic throughout – so it's mostly just a connector issue, but still.
How about a mixed approach: use plain ol' UDP for data –– over Ethernet, or WiFi using something like ESP32 ––, but a common distributed clock to sync to? For example using one of the free wireless bands, sending a clock bitstream, perhaps even just a 96 kbits/s 0b10 pattern per sample – i.e., one pulse per sample?
Hmm.. too many moving parts for my taste.
How about using Cat5e SF/UTP cables (four twisted pairs in a common foil shield) in a star configuration, using one twisted pair for clock, the other for data (so still unidirectional SPI), with NRZ and say ±12V drivers (and non-magjack RJ45 connectors); and magjacks on the receiving end? The overall data rate from the host PC to 18 cabinets at 48kHz 24bit 8-channels/cabinet is 18×48000×8×24 bits per second = 165,888,000 bits/sec, or 20,736,000 bytes per sec. Again, using 12,288,000 Hz clock rate, for nominally 32 bits per sample. You could even use a third pair for a /SS signal, enabled for 24 to 31 clocks out of every 32, to ensure exact sync.
A
trivial example program on Teensy 4.0 can achieve 200+ Mbits/s, or 25.7 Mbytes/sec, in one direction (high-speed USB 2.0, 480 Mbit/s). Having 18 SPI in parallel, using the same master clock at 12.288 MHz, is a bit tricky, though. Moreso, because although the per-cabinet bandwidth needed is just 9.216 Mbits/s, is not really achievable with full-speed 12 Mbit/s USBs most microcontrollers have, in my experience (i.e., 18 separate full-speed USB MCUs would not work, due to USB overheads et cetera, even if it might look like it should, because 9.216 < 12). Isochronous USB transfers? Perhaps, but it is very, very close, especially considering using 18 of them in parallel.
If you had a small FPGA (say iCE40) that could interface to a Teensy Micromod, you could use a parallel 8-bit 8080-style bus with separate clock/write strobe. One sample to 8 channels in 18 cabinets is 24×8×18/8=432 bytes, so the minimum transfer rate would be 20.736 Mbytes/sec. If one used exactly twice the per-cabinet SPI clock, 24,576,000 Hz, say from a crystal, halving it for the SPI buses, then the SPI-driving FPGA simplifies to a multiplexer with 32-bit parallel-to-serial shift registers and counters. Say 64 to 128 bits per SPI bus, to allow for jitter in the DMA setup (as the bus duty cycle is 432/512≃85%). The FPGA would create the 18 unidirectional SPI channels and 24-31 out of 32 cycles /SS signals, and you'd use a separate power board for the ±12V signal drivers and cable connectors. Note that that would be 18 data output pins, 1 /SS pin (shared across cabinets), 1 clock pin (shared across cabinets), 8 data input pins and and its read/write strobe pin and a select pin, for around 30 I/O pins.
For experimentation, taking an
Olimex iCE40HX1K-EVB, and replacing the 100 MHz oscillator with a 98.304 MHz one (8× SPI bus clock, 4× the parallel Teensy bus clock, bus master in all cases), to find out if this is actually doable, would be interesting, and not too expensive. While the FPGA would need to generate all 18 SPI data outputs, only one driver-cable-receiver would be needed for testing.
This would be my DIY approach, anyway. But I'm just a hobbyist (who obviously likes his Teensy microcontrollers, interfacing them to sensors and stuff), and more of a software than hardware person. Hopefully my musings above are at least amusing, if not informative/useful!