Open RF Prototyping

Using Linux SPI on the Red Pitaya Board

Configuring the SPI Hardware

Pavel Demin's red-pitaya-notes configuration and build infrastructure is used to build the Zynq FPGA bitstream and associated Linux kernel. The required SPI hardware is already configured as part of this.

The Zynq contains two independent SPI controllers (SPI devices 0 and 1). Only SPI 1 is available for use on the Red Pitaya board with MOSI, MISO, SCK, and CS mapped to the Zynq MIO 10 to MIO 13 signal lines. These in turn are routed to the Red Pitaya board E2 expansion connector:

Table 1: Red Pitaya board SPI signal lines

SPI Signal

E2 Pin

MOSI

3

MISO

4

SCK

5

CS

6

Vivado will generate the following device tree entry for the SPI hardware:

spi1: spi@e0007000 {
    compatible = "xlnx,zynq-spi-r1p6";
    reg = <0xe0007000 0x1000>;
    status = "disabled";
    interrupt-parent = <&intc>;
    interrupts = <0 49 4>;
    clocks = <&clkc 26>, <&clkc 35>;
    clock-names = "ref_clk", "pclk";
    #address-cells = <1>;
    #size-cells = <0>;
};

Note that this uses the Cadence SPI driver and the following kernel config. options are set in arch/arm/configs/xilinx_zynq_defconfig:

CONFIG_SPI=y
CONFIG_SPI_CADENCE=y
CONFIG_SPI_XILINX=y
CONFIG_SPI_SPIDEV=m

This builds the SPI kernel driver as a module which loads at boot time. The SPI module creates the /dev/spidev1.0 device.

The Running System

The SPI device is available as /dev/spidev1.0. The ownership and permissions should be changed appropriately in order to allow access from the application.

chgrp dyadic /dev/spidev1.0
chmod g+rw /dev/spidev1.0
# ls -l /dev/spidev1.0
crw-rw---- 1 root dyadic 153, 0 Oct 13 21:17 /dev/spidev1.0
RP board top

Red Pitaya board top showing SPI pins in expansion connector E2

Accessing the SPI device

We make use of the Python periphery module to access the SPI device.

$ python
Python 3.9.7 (default, Sep 19 2021, 17:26:23)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from periphery import SPI
>>>
>>> spi = SPI("/dev/spidev1.0", 0, 4000000)
>>> data_out = [0xaa, 0xbb, 0xcc, 0xdd]
>>> data_in = spi.transfer(data_out)
>>>
>>> print("shifted out [0x{:02x}, 0x{:02x}, 0x{:02x}, 0x{:02x}]".format(*data_out))
shifted out [0xaa, 0xbb, 0xcc, 0xdd]
>>> print("shifted in  [0x{:02x}, 0x{:02x}, 0x{:02x}, 0x{:02x}]".format(*data_in))
shifted in  [0x00, 0x00, 0x00, 0x00]
>>>
>>> spi.close()

Useful tools

The spi-tools package contains some tools which are useful when dealing with Linux SPI devices.

sudo apt-get install spi-tools

Manpages for spi-tools in Debian bullseye