Adding a missing SPI chip select signal / decoding a single device without CS

Hi everyone!

I’ve got a trace of an SPI bus with transfers with 3 different slaves.

For two of them, I got a recording of the chip select signals (D1: an SPI flash, D2: an SPI 3-Wire device – hence no activity on D5/MISO).

For the third slave, I do not have a recording of the CS signal. Obviously, there’s still traffic on MOSI (D4) and MISO (D5) and the SCLK (D3). I’d still like to decode this slave’s data transfers.

Here’s my ideas to approach this:

  1. Create an additional virtual channel (there were no measurements on D6-D15 and D0). Can this be done? I’d then need to re-create the CS signal… which should be possible by using the other two CS signals… and can even be improved having an additional look at the SCLK signal because I currently cannot tell if CS is asserted and de-asserted multiple times.
    Not sure if there’s an API to make this happen.
  2. Use an SPI analyzer instance without specifying “Enable” (keeping it at “Select Channel”) - which gives me the decoded bytes for all three devices simultaneously… and I could throw away the duplicates by looking at the other two devices. This could be done on exported data in some external post-processing script.

My wish is to use another SPI HLA on top… which makes me think that only my first approach would work. I really enjoy scrolling through the annotated, decoded data using the Saleae UI.

Any ideas are welcome! Maybe you can think of different approaches!

I have one specific follow-up question about approach 1): can a custom HLA which uses SPI input frames also emit SPI output frames as I want to plug-in another HLA on top of what I filter?

I came up with a new approach 3): As it seems, the built-in SPI analyzer is open-source: GitHub - saleae/spi-analyzer: Saleae Serial Peripheral Interface (SPI) Analyzer · GitHub – so it might be feasible to “fork” it and apply some changes to realize what I want. This would require the use of C++ instead of Python.

Edit: as of now, approach 1) would be my favorite one. As I can add logic for the device-specific SPI communication to assume CS assertions/de-assertions dependent on the data being transferred (i.e. detecting the start and end of transfers – instead of assuming everything is a single transfer when no other SPI device communicates).

Virtual channels are not implemented yet, so you don’t have any native support for option 1. Using the SPI analyzer without chip select is the only simple way to see decoded data ‘live’ in the existing GUI. You could add a parallel analyzer to the two (of three) chip select lines, then see either {3, 2, 1} value to indicate which chip select was asserted (0 would occur if both chip selects asserted simultanously).

The more complex solution is either your option 3 (refactor the SPI analyzer in C++ to support your chip select scheme), or possibly a clever HLA that inputs your option 2, and can auto-detect the device based on SPI data characteristics (payload contents, SCLK frequency, frame lengths, bit-level contiguous run lengths, etc.), assuming they can be separated.

Finally, there might be a clever hack that could combine frame data from multiple LLAs (e.g., two HLA python scripts that ‘share’ frame info between each other via shared memory/global variables?), but not sure if it would work. The normal development path expects only 1:1 between LLAs and HLAs (no official support for one HLA to input from two LLAs).

Otherwise, can you just recapture the data with the 3rd chip select included?

Thanks. Yeah, I’ll try it with a sophisticated/“smart” HLA and I’ll let yous know in case anyone here’s interested in the outcome.