-
Notifications
You must be signed in to change notification settings - Fork 9
SPI
SPI = serial peripheral interface
The SoC has three SPI master peripherals: SPI0, SPI1, and SPI2. SPI0 is the most powerful one; SPI1, SPI2 and UART1 are combined as grouped together as Auxiliary peripherals. For details, see hardware docs.
expansion header pins
With dtoverlay=spi0-hw-cs.dtbo
in config.txt SPI0 is available on the expansion header at the following pins:
GPIO pin | expansion header pin | SPI0 signal | comment |
---|---|---|---|
GPIO11 | 23 | SCLK | serial clock |
GPIO9 | 21 | MISO | master in, slave out |
GPIO10 | 19 | MOSI | master out, slave in |
GPIO8 | 24 | CE0 | chip enable for device 0 |
GPIO7 | 26 | CE1 | chip enable for device 1 |
25 | GND | ground |
pi@raspberrypi:~ $ ls -l /dev/spi*
crw-rw---- 1 root spi 153, 0 Mar 20 20:26 /dev/spidev0.0
crw-rw---- 1 root spi 153, 1 Mar 20 20:26 /dev/spidev0.1
pi@raspberrypi:~ $ ls -l /sys/class/spidev/spidev*
lrwxrwxrwx 1 root root 0 Mar 20 20:29 /sys/class/spidev/spidev0.0 -> ../../devices/platform/soc/3f204000.spi/spi_master/spi0/spi0.0/spidev/spidev0.0
lrwxrwxrwx 1 root root 0 Mar 20 20:29 /sys/class/spidev/spidev0.1 -> ../../devices/platform/soc/3f204000.spi/spi_master/spi0/spi0.1/spidev/spidev0.1
spiloop is a tool in the meta-rpi
layer. If not already included in your image,
you can build it by executing on the build host in a bitbake shell
bitbake spiloop
and using a package server or network login and scp
to copy it to your RasPi.
On a running RasPi execute command
spiloop -d /dev/spidev0.0 -i 16 -v
with all header pins unconnected. You will see a pattern like:
tx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 rx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 tx: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 rx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 tx: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
...
i.e. a 0x00
byte is always received on MISO
pin regardless of what was sent from MOSI
pin.
Connect a wire between MOSI
and MISO
pins (see above) on the expansion header and repeat the test.
Now, the output is like:
tx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 rx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 tx: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 rx: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 tx: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 rx: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
...
The wire created a loopback and the output on MOSI
is read as input on MISO
.
spidev_test is a similar tool distributed with the Linux kernel sources. It is easy to download, compile and use. On a running RasPi enter:
wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-4.4.y/Documentation/spi/spidev_test.c
gcc -o spi_test spi_test.c
./spidev_test -h
Note that /dev/spidev0.0
denotes SPI bus 0 device 0 (which toggles CE0) and
/dev/spidev0.1
is SPI bus 0 device 1 (which toggles CE1).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
int main()
{
int rc;
int fd = open("/dev/spidev0.0", O_RDWR);
if(fd < 0 ) {
perror("open spi device");
return -1;
}
static struct spi_ioc_transfer tr;
uint8_t rx[5];
uint8_t tx[5];
tr.tx_buf = (unsigned long)tx;
tr.rx_buf = (unsigned long)rx;
tr.len = 5;
tr.speed_hz = 1000000;
tr.bits_per_word = 8;
memset( tx, 0xF0, 5 );
for(;;) {
rc = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if(rc < 0 ) {
perror("send message");
return -1;
}
sleep(1);
}
close(fd);
}
- simple schematics (need review?) https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=141052
- kernel module source code: https://github.com/raspberrypi/linux/blob/rpi-4.9.y/drivers/net/can/spi/mcp251x.c
- Sparkfun tutorial on SPI bus: https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi