Using GPIO's as SPI

I am trying to run multiple SPI modules (more than the two available on the BBB) to try and read data from a bunch of accelerometers (LSM303D).

I was therefore wondering if it would be possible to implement the SPI module using code (preferably C/C++) on the abundant GPIO pins. I have been scanning through a lot of documentation but I cant seem to find anything that fits the bill.

Please help — getting desperate…

It sounds as though you need to read more concerning what SPI actually is.

Devices communicate in master/slave mode where the master device initiates the data frame. Multiple slave devices are allowed with individual slave select lines. Sometimes SPI is called a four-wire serial bus, contrasting with three-, two-, and one-wire serial buses. SPI is often referred to as SSI (Synchronous Serial Interface).

http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus

What does this mean ? Multiple devices can share the same data bus, and only CS( chip select ) needs be different for each device. CS only needs to go high, or low, which hey remarkably is exactly what GPIO pins do ! :slight_smile:

You could bit-bang SPI Master using some GPIO pins, but you can’t run the clock much faster than 1 KHz using a user-space program under Linux. With a custom driver, you could run faster but it would still be limited by the interrupt latency caused by other ISRs. You could do it using a PRU to bit-bang some GPIO pins, and it could run much faster. (Probably as fast as your SPI slave devices can run.) That kind of “bit-banging a communications protocol” is why the PRUs are in the chip.

Each of the existing SPI modules have some provision for generating different SPI_CSN[n] signals, but as I recall you can only select four devices and maybe not all four SPI_CSN[n] signals are routed to a P8 or P9 pin? If you need to talk to more SPI slave devices, then you could add a little bit of external hardware so you can use a few GPIO outputs to steer your SPI_CSN signal to one of many SPI slave devices. Like a little 1=>16 mux controlled by 4 GPIOs. Then you could just set the device address in your application before calling the standard SPI device API.

Hey William…

I do know that the Chip Select line can be used to toggle between different SPI units… But I need data to be collected simultaneously from multiple sensors… As of now I have 32 sensors - I have clubbed them into groups of 4 and so I have 8 sets of SPI units that I want to communicate with “simultaneously”…

Thanks “Guy Grotke”… could you help me out with resources I can use to implement “bit-banging”… Also I have not worked on PRU’s, will try reading up and get back to you… btw I dont think the MUXing will work, because I want all data to be collected simultaneously (at run-time)…

Sounds like fun. Good luck :slight_smile:

but you can’t run the clock much faster than 1 KHz using a user-space program under Linux.

Not true at all! You can get over 3MHz just fine with mmap to the gpio registers. If you try to open and close a file each gpio toggle, like the insanely inefficient sysfs interface, then yeah…you’ll be severely limited, but still much faster than 1kHz.

Did you google? Properly bit-banging an SPI port using the PRU - Processors forum - Processors - TI E2E support forums

Yes, I was talking about trying to do hard real-time data collection in a user-space program. If you look at the maximum interrupt latencies from other stuff running on the system, then you see just why PRUs are necessary to always meet your deadlines. Most of the time, a user-space program running mmap to access gpios will run up at Mhz speeds but every now and then one of your data samples might be 100 msec late because something else was running. That kind of irregular sampling makes an FFT worthless. (But there certainly are some slower speed control applications where that kind of latency is perfectly okay.)

I have a program that runs the SPI0 port as a slave, and it can be clocked by the master SPI device at 12-16 MHz because my protocol never overflows the SPI FIFOs. I had to use mmap, so I could set SPI control registers in ways no Linux drivers support.

Hi Guy, is the source available for your SPI0 slave implementation on the BBB? I am running BBB Master <-> BBB Slave and am finding no examples for running the AM3359 in slave mode.

Thanks

Hi swapan … I am trying to achieve something similar using 4 arduino pro mini’s. But as of now I am only able to communicate with one using the tutorial in the link below.
http://www.ulasdikme.com/projects/arduino/BBB_Arduino_SPI.php

I need to share data between the arduino and BBB as fast as possible.

I understand that I need to use GPIO’s to be used as slave select for this purpose. But this tutorial doesnt seem to use interrupts insted of slave select pins.

Could you suggest me on how to set up the communication protocol.