SPI with two SW NSS signals

Sharing experience and thoughts:
Use Case:
I want to have one SPI bus, with two NSS signals (to select two different SPI slave devices on same bus).
I use SPI in DMA mode.

There is option to use SPI with a HW generated NSS (negative slave select signal, N for low active) or with SW NSS (a GPIO pin driven by SW).
HW NSS works fine, but can generate just one NSS signal (not two).

So, I want to use GPIO pins to generate the NSS, via SW.

The problem "kicks in" as:
The SPI peripheral pins (SCLK, MOSI) are floating (high impedance, not driven) when the SPI device is not active. Sure, reasonable (it can be a shared SPI for several masters).

But when I generate the NSS signal via SW - it is set way before the SPI device starts the DMA transfer. And due to fact that SPI is enabled just when the DMA was kicked off:

  • the SW SPI NSS signal is low, active, way before the SPI device is activated
  • so, NSS is active low but the SPI signals (SCLK, MOSI) are still floating

This can result in trouble: there can be a clock edge, when changing from floating to driven, during the phase where NSS is already active.
It depends a bit if you have pull-up or pull-down on these floating signals (to avoid floating):

  • if you use SPI mode 0 and you have pull-ups (tied to 1) - it goes wrong!
  • SPI mode 0 means: the clock as default is low, the first edge is a low-to-high edge
  • but the pull-up ties it from floating to high, so the default level is high
  • but when the DMA enables the SPI device, the SCLK signal toggles from high to low, just to bring it to the default SCLK state, before the SCLK really starts

This is a clock edge, a first clock pulse on SPI bus. A slave can be confused when it sees such a "wrong" clock edge, because NSS is already active but SCLK toggles just between floating and driven.

I had the idea to modify the HAL drivers:
I do my SW NSS GPIO out after the DMA was enabled: so, it NSS is just valid when also the SPI device is active (not floating anymore)
But how to release NSS? When the DMA finishes it deactivates the SPI device and signals become floating again. My SW NSS GPIO would be too late. So, I have the issue now at the end of the SPI transaction: one additional clock edge at the end.

And modifying the HAL drivers is not a good idea: every update of the drivers will kill my changes done in the driver code.

So, in my case the only working solution:

  • use pull-ups OR pull-down
  • but which type to use depends on the SPI mode (mode 0 vs. mode 3)
    And check with a scope if the SPI transaction is clean (the right SCLK transitions when NSS is active, low).

On some chips it was fine to have this "additional SCLK edge" but other chips do not like it (they fail to talk via SPI).

So, SW NSS is needed for a multi-slave SPI bus config, but there are not hooks in SPI driver to make it correct.
(e.g. a Callback when SPI DMA has enabled SPI or will disable DMA and SPI would be helpful, to place my SW NSS GPIO toggle there)