SPI to multiple peripherals

I’m trying to use SPI to communicate with multiple peripherals.

Looking at per/spi.h I’m guessing that the idea is that ultimately you will be able to create multiple instances of SpiHandle for each peripheral that shares an SPI bus but have different CS pins. It looks like what’s currently there is hardcoded so that Init.NSS uses SPI_NSS_HARD_OUTPUT, which directs the CS output to libdaisy pin 7.

Looking at the code in per/spi.cpp I’m guessing that what I need to do is set Init.NSS to SPI_NSS_SOFT together with some other settings to specify the appropriate GPIO pin, but I’m not sure how to set that up. It’s getting rather deeper into all the STM32 settings than I’m comfortable with!

So as far as I can tell, the Hardware NSS output should only be used if you’re using a single device, I don’t think the SPI peripheral can handle multiple hardware chip-selects.

What can be done for multiple devices on a single bus is to use Software NSS, and then manage the CS lines outside of the calls to the SPI Rx/Tx commands.

If you do set the Init.NSS to SPI_NSS_SOFT you can use a dsy_gpio set to any pin you want to use for the chip select. Then before sending the read or write commands just pull that pin down, and then pull it back high after.

When we get to reworking the libdaisy SPI Peripheral we will be adding some level of internally managed software chip select, but I’m still undecided on how best to support multiple devices, but it will be possible.

If you have any other specific questions before I get to fixing up the libdaisy SPI stuff, I’ll be happy to help :grinning_face_with_smiling_eyes:

1 Like

That makes complete sense.

I’ve managed to get my setup working by setting Init.NSS to SPI_SOFT, specifying separate GPIO pins for CS for each peripheral, and passing the SPI SCK and the CS lines through AND gates before connecting to the clocks on the peripherals. Seems to work fine.

Nice!

FWIW provided your devices are actually SPI and not some other 3-wire serial control then you should be able to send the SCK/Data lines to all devices at once. The device-specific CS pin being pulled low is what tells a given device to start paying attention.

That said, if you’ve got it working then no need to mess with it! :slight_smile:

One of the devices I’m using only has serial data and clock inputs, so it’s really a synchronous serial device rather than SPI. Putting both devices on the SPI so that I can use the hardware rather than doing a software serial out seems to be working niceley.

I guess one other option might be to use an USART to do synchronous serial, but are the clocks for any of the USARTs currently available on gpio pins using libdaisy? All I can see is asynchronous serial using uart.h.