Using GPIO for SPI Slave Selects

Hi all,

I plan to interface with 8 SPI slave devices using the BBBlue along with the RoboticsCape libraries.

I plan to use a 3-to-8 line decoder (CD74AC138E) so that I will only need three GPIO pins to access the slave select of each device.

Has anyone done anything similar to this before? I presume some form of bit-banging will be necessary, though I’m not yet certain what code I need to modify to make this possible.

It looks like modifying rc_spi.c might be my best bet. In particular, it looks like i would need to modify the switch statements in rc_manual_select_spi_slave() and rc_manual_deselect_spi_slave(), as well as the gpio_ss array initialization in rc_spi_init().

The gpio_ss array currently uses BLUE_SPI_PIN_6_SS1 and BLUE_SPI_PIN_6_SS2 GPIOs for slave selects. Will I also be able to use the pins on the GPIO headers to control slave selections?

Thanks,
Robert

You will also probably need some kind of “enable” line.
You can’t guarantee that all three lines are going to transition between states at exactly the same time, so it is possible that you can get a transient invalid select while they are changing.
This may or may not be long enough to confuse what you are controlling.
Most 3 to 8 line decoders have some kind of auxiliary enable input.

— Graham

Good point.
I will make use of the enable lines to avoid such glitches. So, I will actually be using 4 GPIOs instead of 3.

In order to select individual slaves, I’ll do the following:

  1. decoder enable pin will be driven low (all SS outputs high)
  2. slave is selected by 3-bit decoder select pattern
  3. decoder enable pin will be driven high after all decoder select bits are set

Thanks,

Robert

Hi Robert

I am facing a problem simiar to yours. My project involvs connecting 4 arduino pro mini’s as slaves to a Beaglebone black. I am able to share data between one arduino and the beaglbone by following the link below
:http://www.ulasdikme.com/projects/arduino/BBB_Arduino_SPI.php

I Understand that I need to Use GPIO’s as CS pins to active the corresponding arduino,

However whenever I try the same for more than one slave devices , I receive data from one arduino only… I am using SPI 0
Are there any limitations as to the number of slave devices that can be attached to SPI 0.

I need the data from the arduino’s as quickly as possible preferably without any delay. Could you suggest a method of doing the same.

Were u able to achieve the same for yorr project… If yes, could you let me know how.

Hi Aniket,

The main limitation for the number of SPI slave devices allowed in an independent slave configuration is the number of CS lines available to you and the ability for data and clock lines to meet threshold high and low logic levels.

In the Arduino code provided in the tutorial you followed, I’m not sure how the interrupt was set up for operating the Pro Mini in SPI slave mode, since I haven’t used Interrupts on the Arduino before.
Two things I would recommend checking in the Arduino code:

  1. Ensure that a low-going CS signal is the only thing that makes the Arduino enter the SPI interrupt service routine. I don’t explicitly see in the tutorial code how pin 10 of the Pro Mini triggers the interrupt.
  2. Ensure that the Pro Mini slaves are not going to cause bus contention on the MISO line. Unselected slaves should not be driving the MISO line high or low. Not sure how you can make sure of this. maybe temporarily set the MISO pin of unselected slaves as inputs, rather than outputs?

For your BBBlack, I don’t easily see in the tutorial code how the CS line is being controlled.

You likely need to manually control the slave select lines using GPIO. For example: select one slave by driving its CS line low, send/receive serial data, then deselect the slave by driving its CS line high.

Only one slave CS line may be driven low at a time when reading data from individual slaves.

Since I used the BBBlue (which is basically a BBBlack with the Robotics Cape integrated into it), I modified the Robotics Cape API functions, rather than directly using ioctl and spidev. I’ve attached my modified SPI functions here.

I’ve tested the functions rc_spi_init_mod, rc_manual_select_mod, and rc_manual_deselect_mod with a 3-to-8 line decoder and a Bus Pirate for sniffing the SPI bus.

You probably won’t need a line decoder for only 4 SPI slaves, so you can just directly drive the CS lines using GPIO.

It’ll be another couple of weeks before I receive my prototype slave devices, so I haven’t had the chance to fully test my functions just yet.

I would dig around in the Robotics Cape library code. The SPI functions in the library are more readable and better documented than the tutorial code, to be honest.

https://github.com/StrawsonDesign/Robotics_Cape_Installer/blob/master/libraries/serial_ports/rc_spi.c

The simplest solution I can think of would be to try installing the Robotics Cape API on your BBBlack and see if you can use their API functions without the Robotics Cape hardware.

Hopefully this helps.

Regards,

Robert

rc_spi_mod.h (246 Bytes)

rc_spi_mod.c (16.4 KB)