Are there SPI multiplexer ICs? - Page 1
Forum section: electronics / projects

author: zapta
author_rank: Super Contributor
timestamp: November 21, 2023, 06:19:36 pm
content: I have a working design with a timer that generates period CS pulses and DMA channel that access the devices synchronized with the timer. Now I want to access a few SPI devices from the same SPI/DMA channel. Are there off the shelf ICs that allows to multiplex SPI, without having to set GPIOs pins to select the devices?For example,1. A single multiplexer that sits between the MCU and the SPI devices and the MCU sends first a device number byte, causing the multiplexer to enable the corresponding CS?2. Each SPI devices has a selector chip before it that looks at the device number sent by the MCU and enables the CS only if the address matches?If not, how practical/reasonable is to implement it myself, e.g. using a CPLD?

author: eleguy
author_rank: Regular Contributor
timestamp: November 21, 2023, 06:59:05 pm
content: Maybe I did not get what you are after. Usually devices are selected with their CS. It certainly does consume one GPIO for device and is sometimes a challenge when working in the GPIO limited world. One option to inspect could be ADGS1408 for example. Not the cheapest but has little bit this and that.

author: peter-h
author_rank: Super Contributor
timestamp: November 21, 2023, 07:05:41 pm
content: One SPI channel can handle multiple SPI slaves. I do this a lot. They all use the same clock din dout and you just deal with the /cs signals.However I found that it is highly desirable to use all the slaves in the same SPI mode e.g. 0,0. This should not be needed but in reality it is; for mysterious reasons some devices do seem to care where the clock is parked when /CS goes to 0, or whatever...Most SPI devices do not have an address byte, do they? That is more an I2C thing, I think.

author: Siwastaja
author_rank: Super Contributor
timestamp: November 21, 2023, 07:14:40 pm
content: I think I got what you mean, but am not aware of any. It would be a specialty thing. What is wrong with sharing the bus and using IO pin for each nCS? Another option would be to pick a microcontroller with enough SPI buses, or utilize the built-in connection matrix to share a single peripheral between multiple SPI buses (for example, in STM32, each SPI peripheral can be routed to different pins using Alternative Function configuration; you can change that quickly in software).

author: peter-h
author_rank: Super Contributor
timestamp: November 21, 2023, 07:59:51 pm
content: If I was doing this and didn't have enough GPIO for all the /CS signals I would use 3 x GPIO and say a 74HC138 or similar to get 8 x /CS.Remember that different SPI slaves are very likely to need a different SPI config. Especially if you want to optimise performance you will want to max out the clock speeds, and sometimes you may have a different bit order etc. You have to store the current config and re-config as needed, and then the whole thing is thread-safe, with a mutex. I do this a lot.

author: ajb
author_rank: Super Contributor
timestamp: November 21, 2023, 08:37:33 pm
content: If you're already using a timer to trigger the DMA, perhaps it would be possible to use multiple timer compare channels to generate the CS signals? Lots of different possible solutions depending on the access pattern and capabilities of your particular MCU's peripherals.You could probably do what you want using a 74x595 or similar and a bit of glue logic. Use the MCU's CS line to select the '595 directly, and use its parallel outputs to drive the other CS pins. Use the serial out from the '595 plus some glue logic to latch its outputs and disable its CS on the last bit, and you should be able to send an "address" byte to select the desired CS line before your main payload. Might take an extra clock cycle or two though. If you need more than 7-8 CS lines, you could expand with an additional shift register and/or demuxes.

author: zapta
author_rank: Super Contributor
timestamp: November 21, 2023, 09:09:32 pm
content: Quote from: eleguy on November 21, 2023, 06:59:05 pmThe access to the SPI devices is done using continuous double buffering DMA, so there is no simple way to switch the next GPS after each SPI transaction.As for the ADGS1408, what do you have in mind, connecting the MOSI of the devices to the SDO of the ADGS1408 and using the switch to route the CS?

author: zapta
author_rank: Super Contributor
timestamp: November 21, 2023, 09:12:18 pm
content: Quote from: ajb on November 21, 2023, 08:37:33 pmEven a round robin over let's say 4 devices should be good. If I understand corectly, you suggest to use an external CS counter that will also route the CS to one of 4 outputs. I just need to make sure the firmware/DMA is in sync with the counter.

author: PCB.Wiz
author_rank: Super Contributor
timestamp: November 21, 2023, 09:41:50 pm
content: Quote from: zapta on November 21, 2023, 09:12:18 pmYes, if you already have time-slot and DMA working, you can simply advance a counter on the CS edge, and mux the CS, and maybe MISO and MOSI and CLK, if the parts do not allow parallel connect.You need to either reset the counter to start at a known phase, or read a terminal count to know where the counter is up to.There are decoders like HCS137/ 237 with inbuilt latches, that could allow you to share some pins ?(I've not seen decoders with counters. The HC4017 has counter to one of 10, but they are active high outputs )

author: dobsonr741
author_rank: Frequent Contributor
timestamp: November 21, 2023, 10:06:05 pm
content: Why not let the MCU operate all the CS lines, directly or by a HC138? Or perhaps you have a different, external to the MCU timer, if I read it right?

author: langwadt
author_rank: Super Contributor
timestamp: November 21, 2023, 10:11:33 pm
content: what devices? some SPI devices can be daisy chained

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 21, 2023, 10:18:36 pm
content: I'm not completely sure I understand the rationale - from what I got, you're accessing GPS devices? Those do not spit out data at a high rate. You can still use DMA for transfers but pause for a few cycles between each, select the next with GPIOs, and restart the DMA? So not quite sure what you're trying to optimize, although there may be missing info here, so just a thought.Relying on a strict sequence that always stays in sync is IMO a recipe for unreliability. Or at least provide a means of "resetting" the sequence on a regular basis, but if you can do that, I'm not sure why you couldn't do what I suggest above as well. Again just wondering, maybe stuff we are missing here.

author: Scrts
author_rank: Frequent Contributor
timestamp: November 21, 2023, 11:21:48 pm
content: Use 74HC595 shift register and tie last output bit to the data input bit of your SPI device. Assuming your SPI devices are 8 bit, you'll have to clock out 16 bits.Although, it should work, but please simulate beforehand

author: zapta
author_rank: Super Contributor
timestamp: November 22, 2023, 03:07:35 am
content: Quote from: SiliconWizard on November 21, 2023, 10:18:36 pmHere is some background information. I have a STM32H7 design that reads an ADS1261 ADC at 2KHZ over SPI, with round robin over 4 ADC inputs. The reading is done in DMA continuous mode (double buffering) with interrupts at the completion of a buffer (which holds a few hundreds of ADC readings). Timer 12 of the mCU generates the continuous 2KHz CS pulses and the DMA transfers on each CS the next 13 bytes from the TX buffer and saves the next 13 bytes in the RX bytes, among them the next ADC read value. Each group of 13 TX bytes reads the old value, selects next ADC input, and starts the next conversion. All work reliably with minimum load and interrupts on the CPU.Now, let's say that instead of reading of 4 channels of the same ADS1261, I want to read a single channel from each of 4 ADS1261 devices and using a single SPI channel. I need to somehow select the next ADS1261 in a round robin fashion and route the CS only to that device.(ideally I would like to have a general solution of accessing continuously N different heterogeneous SPI devices, making SPI devices addressable, similar to I2C, but I think that the requirement of reading four ADS1261 capture the essence of the technical challenge).Some links:1. Setting the burst byte count (13) per CS.https://github.com/zapta/daq/blob/main/controller/platformio/lib/adc_card/adc_card.cpp#L2352. Populating the continuous DMA TX buffer with the 13 bytes groups that are sent continiously.https://github.com/zapta/daq/blob/main/controller/platformio/lib/adc_card/adc_card.cpp#L383

author: PCB.Wiz
author_rank: Super Contributor
timestamp: November 22, 2023, 04:45:58 am
content: Quote from: zapta on November 22, 2023, 03:07:35 amIf you wanted to prepend an address, that would need a CPLD to extract and delay the output CS's but it could be done.If you are ok with some timing rules, you could use a cheaper small MCU to receive the first SPI byte, then drive a select pin low, which can also gate the CLK to that remote.It would take a handful of MCU cycles to respond to SPIF, and output the byte to a chip selects port.A useful, simpler logic candidate looks to be the SN74HCS264, an inverting version of the 164. This does not need a payload overhead.a low on /CLR sets all Qn pins high, and then you can clock thru a single low to select 8 slaves.With schmitt pins, you can drive all of that from one pin, using pulse width rules.a) Wide pulse = /CLR has time to go low and all pin SET HI, trailing _/= is ignored as /CLR is still low.b) Medium pulse AB has time to go low and loads /Q0 = Hi.c) Narrow pulse loads a HI, so /Q0 = LowOperation would be a) then c) then b),b),b),b),...

author: Peabody
author_rank: Super Contributor
timestamp: November 22, 2023, 04:47:06 am
content: I think the 74HC138 suggestion is a good option. You would need to allocate up to three GPIO pins to select one of eight outputs. Then connect the CS line to one of the active-low output-enable strobes, and the selected output will follow the CS line.

author: ajb
author_rank: Super Contributor
timestamp: November 22, 2023, 05:08:31 am
content: Quote from: zapta on November 21, 2023, 09:12:18 pmno, but that’s also an interesting idea. I was suggesting that you put a serial-to-parallel shift register on the bus with its outputs driving the CS lines of the other devices. The MCU’s CS output is used to select the shift register, and some glue logic attached to the SR’s serial output loads the output register to assert the desired CS line automatically after the first byte is loaded. So you’d just need to tack a byte onto the front of the message to select the right device and it’s otherwise completely transparent to the MCU. Admittedly i have not thought through the details, it might take too much external logic to be sensible.But leveraging multiple compare channels on the timer that triggers the DMA transactions, or another linked timer, could be helpful in a lot of ways. You could use the compare outputs pins to directly drive different CS pins in sequence or sequence other external logic, trigger another DMA transaction to a GPIO register containing a bunch of CS output pins…

author: zapta
author_rank: Super Contributor
timestamp: November 22, 2023, 06:47:48 am
content: Quote from: ajb on November 22, 2023, 05:08:31 amMy goal is to have this capability as abstracted as possible to the MCU, without requiring design changes other than prepending an address byte to the SPI transaction.I asked in the FPGA forum here about small FPGAs and the once below seems to be a good fit. It is a stand alone IC, reasonably priced, and should support the minimal complexity of this design. If it listen to the first byte (after CS low) on the MOSI line, without forcing any value on the MISO line, and then asserts one of let's say 8 CS outputs, it can then be used either centrally, sitting near the MCU, or distributed, having one near each device, forming an addressable SPI buss. The extra input can also be used to select address range, so a lot of flexibility.https://www.digikey.com/en/products/detail/lattice-semiconductor-corporation/LCMXO2-256HC-4SG32C/3232671https://www.eevblog.com/forum/fpga/help-finding-a-small-and-low-cost-programable-logic-ic/new/#new

author: Siwastaja
author_rank: Super Contributor
timestamp: November 22, 2023, 08:52:55 am
content: Sounds like you have come up with arbitrary constraint of "absolute minimization of CPU time" without clear rationale forwhy, and then overengineered everything around it to suit this premise, to the point of needing to add specialized extra processors or hardware which probably consumes all those resources (energy, transistors) you tried to save; or actually spend orders of magnitude more. Not to talk about design effort.Microcontrollers have small interrupt latency and simple to configure peripheralsby design. There is nothing wrong configuring an SPI transfer 1 MILLION times a second on STM32H7, much less 2000 times.Instead, just do it normally; for small packets, don't bother with DMA and consider using SPI FIFOs. For longer packets, configure DMA in the ISR. Problem solved; no specialized hardware, no specialized software.Please help us help you better and explain what exactly is the reason you think about minimization of CPU time and avoidance of frequent interrupts?

author: peter-h
author_rank: Super Contributor
timestamp: November 22, 2023, 09:07:04 am
content: Exactly. No need for DMA at all.Also think about the future. While it is easy to configure a "CPU" project which can be retrieved in years to come (e.g. set up a VMWARE VM) try doing it with an FPGA. I used to do FPGA/ASIC design consultancy (until about 1999, mostly Xilinx X3K/X4K) the tools were absolute shit, they were licensed with dongles (nowadays online license checking!!), and they changed all the time. Plus, production life? The X3K went for many years but they were "classics" and with not many other players in the market. Today?? It is IMHO really dumb to use an FPGA anywhere unless absolutely necessary and dictated by extreme performance requirements which absolutely cannot be met in software.

author: zapta
author_rank: Super Contributor
timestamp: November 22, 2023, 04:07:24 pm
content: Quote from: Siwastaja on November 22, 2023, 08:52:55 amThe design I am working on is open ended. Basically a card with a STM32H7 whose free pins got to a bus and cards and functionalities that will be added over time. That's why I prefer to not commit CPU resources at an early stage.As for design effort, my hobby time is free.

author: Siwastaja
author_rank: Super Contributor
timestamp: November 22, 2023, 05:07:06 pm
content: Quote from: zapta on November 22, 2023, 04:07:24 pmYes but did you calculate the amount of these "CPU resources", in any way, even hand-wave? Why would you buy a high-end CPU and then not want to use 1% of it to do the task you need it to do, and what it's intended to do? I would understand this desire to leave "room" for future processing needs if it was a significant CPU time in question*, but it's not. It's really really hard tocompletelyavoid interrupts even though DMA exists for that purpose. I think your design principle has hit the wall when you need an external co-processor to assist you not use the CPU.This SPI interrupt does not even need to be of highest possible priority, so it would not mess with the realtime performance of future functionalities.*) I have felt filthy writing a handler which is triggered to do non-trivial amount of bitshifting and calculations at 500kHz and spends significant part of CPU time, like 20-30%, but even that is something I found desirable over added external hardware

author: zapta
author_rank: Super Contributor
timestamp: November 22, 2023, 05:30:04 pm
content: I do use interrupts, e.g. for I2C, which doesn't sit well with continuous DMA.As for external hardware, this system is full of external hardware, since the cards are self sufficient. For example, this is an ADC card, with support for load cell and temperature sensors.https://github.com/zapta/daq/blob/main/adc/kicad/adc.pdfModularity and open ended were key design goal. Compactness and minimalist designs were not. The design would be very different if it would be a set functionality and a single board design.Anyway, the idea of addressable SPI bus using a generic IC that adds the address functionality is very interesting for me.

author: zapta
author_rank: Super Contributor
timestamp: November 22, 2023, 05:33:07 pm
content: Quote from: peter-h on November 22, 2023, 09:07:04 amAren't they cool, and programming them makes the hobby even more exciting?

author: Siwastaja
author_rank: Super Contributor
timestamp: November 23, 2023, 03:57:57 pm
content: Well then, it appears you have made up your mind. FPGA would give you most room for flexibility and future feature creep. Once you do that, get rid of the STM32 and just use a softcore on the FPGA. Use the biggest FPGA you can afford so that you don't run out of resources. They are pretty expensive, but very capable.

author: zapta
author_rank: Super Contributor
timestamp: November 23, 2023, 06:12:51 pm
content: >> Use the biggest FPGA you can afford so that you don't run out of resources.Thanks a great idea. Can you recommend me one?

author: Siwastaja
author_rank: Super Contributor
timestamp: November 23, 2023, 07:58:24 pm
content: Quote from: zapta on November 23, 2023, 06:12:51 pmI worked with FPGAs over 10 years ago but did not find much use for them in projects I now choose to do. Altera Stratix II was a cool thing, and I played with some of the largest models with catalogue price of $10000 or so, per chip. Altera is now Intel and a lot has changed, probably, but one thing remains: the higher the cost, the bigger and better it is.

author: zapta
author_rank: Super Contributor
timestamp: November 23, 2023, 08:29:15 pm
content: Currently this programmable device is at the top of my list. Trying to fit a minimalist design. It's small, inexpensive, stand alone, and can even be program in circuit via I2C.https://www.mouser.com/ProductDetail/Renesas-Dialog/SLG46826G?qs=%252B6g0mu59x7Lz4SMy5idICg%3D%3D

author: zapta
author_rank: Super Contributor
timestamp: November 24, 2023, 06:10:44 am
content: I was able to map a proof of concept design to a $1.5 SLG46826G SPLID. With this design, the address IC sits near each SPI device on the bus, providing it an stripped down CS/SCLK/MOSI, after detecting the correct address in the first byte. This design supports for different addresses but more can be added. Also, polarity control for the clk and data can be added.The SLG46826G can be programmed in circuit via the I2C port or one time before assembling it.Am I missing something?

author: dietert1
author_rank: Super Contributor
timestamp: November 24, 2023, 09:32:21 am
content: In order to send the device selection as the first byte in a SPI transaction, this would require a shift register that drives a decoder. The decoder outputs select one of the devices after receiving the first byte. This needs one output port as CS for the shift register (shift enable, decoder output disable) and likely another output port to delimit the SPI transaction. I don't think one needs to manipulate the three SPI bus signals, as SPI devices include logic to remain inactive without CS.If there are less than eight devices, one can use just a shifter with sparse code. Maybe a 74hc164 serves the purpose.Regards, Dieter

author: zapta
author_rank: Super Contributor
timestamp: November 24, 2023, 05:35:35 pm
content: >> I don't think one needs to manipulate the three SPI bus signals, as SPI devices include logic to remain inactive without CS.That's correct. I added it because there was free pins and logic but it's optional.It's also provides buffering which allows to build trees of addressable SPI devices, similar to the diagram below.

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 24, 2023, 08:39:37 pm
content: I am a hobbyist with no FPGA experience at all, but I would look at Lattice ICE40LP384-SG32, which Mouser sells for 2€ in singles, and has plenty in stock; Ibelievebut am not certain that it is supported by the open sourceIceStormtools too.I would use five pins between the microcontroller and the FPGA: SCLK, MISO, MOSI, /CS (optional), and a separate pin to reset the FPGA multiplexer if a SPI transfer is interrupted.Each transfer would begin with a 32-bit routing word. The first 8 bits would control eight separate /CS pins, optionally connected to a TI TXU0304 voltage level shifter enable pins (allowing one to electrically disconnect a SPI sub-bus). The next two bits would control the SPI mode, next four bits the word size (4-16), and the last 18 bits the transfer size in words. (Maximum single transfer would then be 262,144 words. Alternatively, use the 22 last bits for the transfer size in bits.)The following bits would be copied over the FPGA, then all /CS pins disabled and input word size reset (to 8 or 16 bits, doesn't matter); and if possible, the bus-side SCLK, MISO, and MOSI tri-stated. For synchronization purposes, a routing word with all zeros should be a no-operation.On the bus side, there would be 11 pins: SCLK, MISO, MOSI, and eight /CS pins. Passing the clock and data signals through the FPGA ensures the /CS pin stays in sync. Internally, the FPGA can implement an up to 32 SPI clock cycle FIFO (meaning the output is 32 bits later than the input), synchronized to the input SCLK, as long as either the microcontroller appends 32 extra SPI clock cycles after the last transfer, or the FPGA can synthesize the extra 32 clock cycles at the same frequency as the input SCLK. (The zero routing word is not needed in the middle of a DMA transfer, only at the end.)So, it really should not be a complicated state machine at all.I did wonder whether one could use one of the cheap (<$1) ARM Cortex-M0/M0+ MCUs for this instead. Both HK32F030M and CW32F003 have only one SPI, butSTM32G030F6(0.44€ in singles at LCSC, 1€ at Mouser) has two. The trick with this approach is that the bus SPI SCLK frequency must be equal or higher than the SCLK frequency from the main microcontroller; perhaps by tying its clock to the main microcontrollers oscillator, or gating the main microcontroller SCLK as the bus SCLK somehow. Otherwise, the data starts piling up in the bus multiplexer. Unlike I²C, SPI has no clock stretching to throttle the data.

author: zapta
author_rank: Super Contributor
timestamp: November 24, 2023, 09:55:24 pm
content: The ICE40LP384-SG32 looks as a good choice and it may be supported by open source toolchain (?)https://f4pga.org/.In a 3.3v system, does it require an external LDO for the Vcc or other voltage rails? Any other external components other than decoupling capacitors?

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 25, 2023, 12:14:53 am
content: Again, I'm a total newbie with FPGAs, and know nothing but theory/theoretical stuff, so hopefully others will pipe up about this.Quote from: zapta on November 24, 2023, 09:55:24 pm3.3V for the I/O (LVCMOS33), and 1.2V for the core (about 8mA at startup) and for Vpp_2v5 (about 4mA). They do need to be provided in the correct sequence at start-up.Quote from: zapta on November 24, 2023, 09:55:24 pmSeeiCE40 Hardware Checklist. You'll probably want some external pull-up resistors and a SPI SS pull-down resistor.You do need to provide a reference clock to iCE40LP320-SG32, so you do need to provide an oscillator for SYSCLK pin; probably connecting it to GBIN6 pin. The OlimexiCE40HX1K-EVBuses a 100 MHz one, and LP384 and HX1K are in the same family (some details differ, but they're described in the same datasheet), so perhaps take a look at the KiCAD files for ideas?

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 25, 2023, 01:01:39 am
content: You can have a look at this project (and you could buy one board while you're designing your own, it's pretty cheap, and this way you'll have something working to start with):https://github.com/wuxx/icesugar-nanoIt's a very barebones board around a iCE40LP with no excess fat, so easy to figure out.

author: zapta
author_rank: Super Contributor
timestamp: November 25, 2023, 03:01:13 am
content: Is this FPGA more standalone than the ICE40? That is, just bypass capacitors on the 3.3V rail?EDIT: Adding the missing linkhttps://www.digikey.com/en/products/detail/lattice-semiconductor-corporation/LCMXO2-256HC-4SG32C/3232671

author: Nominal Animal
author_rank: Super Contributor
timestamp: November 25, 2023, 12:44:15 pm
content: The icesugar-nano uses a PWM pin from the microcontroller as the clock input.So, with iCE40LP's and iCE40HX's you need 3.3V and 1.2V, a bunch of bypass capacitors, and a couple of resistors.

author: zapta
author_rank: Super Contributor
timestamp: November 25, 2023, 05:16:21 pm
content: Is this one standalone? That is only 3.3V with bypass capacitors and everything else, including LDOs and clock sources are internal.https://www.digikey.com/en/products/detail/lattice-semiconductor-corporation/LCMXO2-256HC-4SG32C/3232671

author: dietert1
author_rank: Super Contributor
timestamp: November 25, 2023, 07:50:08 pm
content: Yes, there are two versions: ZE with 1.2 V core supply and HC with no special core voltage. Anyway for a 256 device the difference in static power consumption will be about 1 mA - in case it matters. I remember using a MachXO2 evaluation board some years ago and found it pretty straightforward to get results.Regards, Dieter

author: zapta
author_rank: Super Contributor
timestamp: December 05, 2023, 06:14:35 pm
content: I ended up designing the SPI address selector using Renesas SLG46826G SPLD. It passes the simulation and I am waiting for the parts to arrive to test it in a real circuit.It uses the 4 LSB bits of the first byte to select 1 of 16 SPI devices and in case of an address match, passes the CS, CLK, and MOSI, to the device. The addressing can be cascaded such that the number of devices is unlimited as long as propagation delays are observed.The gating of CLK and MOSI is optional and was done mainly as buffering, to reduce the per-device load on those signals.SCLK and SDA are used to program the device using I2C and A0, A1, A2, A3 inputs should be hard wired to a unique device address.https://github.com/zapta/GreenPAKs/tree/main/addressable_spi