Noggin01
Posts: 63
Joined: Tue Jan 07, 2014 1:38 pm

SPI w/ WiringPi

Tue Jan 14, 2014 7:09 pm

I just received my RPi yesterday evening and I'm hoping to write a C program which will use WiringPi to communicate over the SPI bus. I've used SPI countless number of times on Atmel and Microchip PIC MCUs and they're always significantly more complex to set up than what appears to be available with WiringPi. With an MCU, you typically have the following constraints:
  • Must specify the idle clock level, high or low
  • Must specify if the SPI output changes when the clock transitions from high to low or from low to high
  • Must specify if the SPI input is read when the clock transitions for high to low, when it transitions from low to high, or at the middle of the output time
  • Must specify the clock rate
  • Must manually control the chip select line
With WiringPi, you just tell it which channel (which I suppose determines if CE0 vs CE1 is used?) and specify a clock rate. This looks very limited to me. Am I missing something?

User avatar
Richard-TX
Posts: 1549
Joined: Tue May 28, 2013 3:24 pm
Location: North Texas

Re: SPI w/ WiringPi

Tue Jan 14, 2014 7:52 pm

You are looking at the SPI bus from far too low a level. All the low level stuff is taken care of by the OS.

Wiring Pi or the native library will work and yes, it is all just a matter of selecting speed and device.
example:

spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz=(16000000)

http://raspberrypi.stackexchange.com/qu ... spberry-pi

So really the only thing you have to worry about is the data you are going to send/receive.

Here is a recent discussion with some demo code.

http://www.raspberrypi.org/phpBB3/viewt ... pi#p483142
Another example
http://www.raspberry-projects.com/pi/pr ... -interface
Richard
Doing Unix since 1985.
The 9-25-2013 image of Wheezy can be found at:
http://downloads.raspberrypi.org/raspbian/images/raspbian-2013-09-27/2013-09-25-wheezy-raspbian.zip

Noggin01
Posts: 63
Joined: Tue Jan 07, 2014 1:38 pm

Re: SPI w/ WiringPi

Tue Jan 14, 2014 9:01 pm

But how does the OS know what clock polarity is needed, and when to change the output data, and when to clock data in? Does the OS work some magic to figure out that out at run time, or is there some way to wiggle the SPI lines which I'm not familiar with that is universally acceptable, or is the RPi only compatible with certain SPI devices?

Yes, I'm thinking of this at a very low level, but this is a concern of mine. Part of me doing this particular home project I'm actually doing is that I'm evaluating the RPi (and to a lesser extent the BeagleBone Black) as a potential hardware platform to develop additional products and services.

I'll take a look at the discussions you linked, thanks.

User avatar
Richard-TX
Posts: 1549
Joined: Tue May 28, 2013 3:24 pm
Location: North Texas

Re: SPI w/ WiringPi

Wed Jan 15, 2014 2:51 am

When it comes to things like what you just described, I leave all that up to the gurus.

This is sort of like the Ethernet collision detection algorithm. I know it is there, I know it mostly works, and since it is done in silicone, I ignore it. I just write my application. Remember the OSI 7 layer model? Each layer acts as a go between for the next layer down so I don't have to worry about lower layers. Tcp has 4 layers if I recall correctly. I think SPI has 3.

My advice is to enable the SPI bus on your Rpi, get a few MCP23s17 chips, some leds and resistors and go nuts! What will really frost your cookies is realizing that 8 MCP23S17 chips can all share a single CS line. :D
Richard
Doing Unix since 1985.
The 9-25-2013 image of Wheezy can be found at:
http://downloads.raspberrypi.org/raspbian/images/raspbian-2013-09-27/2013-09-25-wheezy-raspbian.zip

lack
Posts: 1
Joined: Tue Jun 17, 2014 12:14 am

Re: SPI w/ WiringPi

Tue Jun 17, 2014 1:10 am

Hi,

I came across this post while searching for the same thing (how to set SPI data mode in WiringPi) so I'm leaving a comment for future readers.
Wiring Pi or the native library will work and yes, it is all just a matter of selecting speed and device.
... This is sort of like the Ethernet collision detection algorithm.
This is not true. Ethernet is a far more developed and complex standard than SPI. In fact, SPI is not a standard. Every manufacturer does it differently. The letters "SPI" tell you little more than "there are these four wires." As in Noggin01's initial post, voltages, clock rate, polarity, etc. are all up to the specific device. There are no "layers" as SPI says nothing about what actual bits of information are transferred over the wires; so there can be no auto-negotiation.
With WiringPi, you just tell it which channel (which I suppose determines if CE0 vs CE1 is used?) and specify a clock rate. This looks very limited to me. Am I missing something?
So, it turns out wiringPi is missing something. Currently there is

Code: Select all

static uint8_t spiMode   = 0;
in wiringPiSPI.c. You can edit that and rebuild the library.. but I would just roll my own; the library doesn't do that much. If you want to stick with wiringPi but prefer not to use a custom-built dependency, you can make a system call after calling wiringPiSPISetup:

Code: Select all

#include <sys/ioctl.h>
...
int spiMode = 1;
int fd = wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED);
ioctl(fd, SPI_IOC_WR_MODE, &spiMode);
The mode numbers correspond to CPOL and CPHA as listed on Wikipedia (and match Arduino's SPI library). Your device's datasheet will list either this number or the CPOL and CPHA to use. It just happens that mode 0 is the most common, which is why wiringPi can get away with pretending different modes don't exist. For example, MCP23S17 looks to be OK with either 0,0 (mode 0) or 1,1 (mode 3).

Return to “Interfacing (DSI, CSI, I2C, etc.)”