davlovsky
davlovsky

Reputation: 73

SPI interface with FPGA running LINUX

I have a DE1-SoC FPGA running Ubuntu 16.04 via the microSD card. I'm somewhat new to the device-tree, but have managed to figure out somewhat how to enable the various peripherals on the board by decompiling the .dtb file into a .dts file using dtc. I did that and edited the .dts file in nano to change the SPI ports from "disabled" to "okay". I then recompiled the .dtb file from the modified .dts file (I also erased the .dts file and re-decompiled a second .dts file to see if the changed took affect, and they did).

At this point, I reboot the system, and go to cd/dev/ but there is not spidev or spi* or spidev* listed. When I go to cd/proc/device-tree, I have the following listed:

ubuntu@DE1_SoC:/proc/device-tree$ dir
3-3-v-regulator      chosen          leds               name
#address-cells       compatible      __local_fixups__   #size-cells
aliases              cpus            memory             soc
bridge@0xff200000    intc@fffed000   model              __symbols__

And when I navigate to the /soc/ folder, I have the following, which is consistent with the .dts file I have:

ubuntu@DE1_SoC:/proc/device-tree/soc$ dir
#address-cells        gpio@ff70a000       #size-cells
amba                  i2c@ffc04000        snoop-control-unit@fffec000
base-fpga-region      i2c@ffc05000        spi@ff705000
can@ffc00000          i2c@ffc06000        spi@fff00000
can@ffc01000          i2c@ffc07000        spi@fff01000
clkmgr@ffd04000       interrupt-parent    sram@ffff0000
compatible            l2-cache@fffef000   sysmgr@ffd08000
device_type           l2edac@xffd08140    timer0@ffc08000
dwmmc0@ff704000       l3regs@0xff800000   timer1@ffc09000
ethernet@ff700000     name                timer2@ffd00000
ethernet@ff702000     nand@ff900000       timer3@ffd01000
fpga2sdram-bridge     ocramedac@ffd08144  timer@fffec600
fpga-bridge@ff400000  ranges              usb@ffb00000
fpga-bridge@ff500000  rstmgr@ffd05000     usb@ffb40000
fpga-bridge@ff600000  sdramedac           usbphy@0
fpga-mgr@ff706000     sdr@ffc25000        watchdog@ffd02000
gpio@ff708000         serial0@ffc02000    watchdog@ffd03000
gpio@ff709000         serial1@ffc03000

So, I'm not sure what I'm doing wrong that my serial peripheral interfaces are not working. The end goal: the SPI on the FPGA connects to an onboard ADC (AD7928), which I would like to access via Linux using a program written in C. The i2C work fine, but for some reason the SPI is not responding.

I think I might be missing a step, but at this point I am kinda lost so any help would be great.

EDIT: Forgot to add the .dts entry for the SPI:

spi@fff00000 {
    compatible = "snps,dw-apb-ssi";
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    reg = <0xfff00000 0x1000>;
    interrupts = <0x0 0x9a 0x4>;
    num-cs = <0x4>;
    tx-dma-channel = <0x2c 0x10>;
    rx-dma-channel = <0x2c 0x11>;
    clocks = <0x11>;
    status = "okay";
    linux,phandle = <0x59>;
    phandle = <0x59>;
};

spi@fff01000 {
    compatible = "snps,dw-apb-ssi";
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    reg = <0xfff01000 0x1000>;
    interrupts = <0x0 0x9b 0x4>;
    num-cs = <0x4>;
    tx-dma-channel = <0x2c 0x14>;
    rx-dma-channel = <0x2c 0x15>;
    clocks = <0x11>;
    status = "okay";
    linux,phandle = <0x5a>;
    phandle = <0x5a>;
};

And the addresses are consistent with the board's datasheet for the SPIM.

Made a little leeway by adding editing the .dts some more:

spi@fff00000 {
    compatible = "snps,dw-apb-ssi";
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    reg = <0xfff00000 0x1000>;
    interrupts = <0x0 0x9a 0x4>;
    num-cs = <0x4>;
    tx-dma-channel = <0x2c 0x10>;
    rx-dma-channel = <0x2c 0x11>;
    clocks = <0x11>;
    status = "okay";
    linux,phandle = <0x59>;
    phandle = <0x59>;

    spidev@0 {
        compatible = "spidev";
        reg = <0x0>;
        spi-max-frequency = <0xb71b00>;
        enable-dma = <0x0>;
    }

Now spidev32766.0 is showing up in my /dev/ folder.

Upvotes: 0

Views: 1717

Answers (1)

Dražen Grašovec
Dražen Grašovec

Reputation: 802

spidev32766.0 is device node you got after you added device tree nodespidev@0 for SPI device on first SPI bus (controller) spi@fff00000 with chip select 0.

Frequency property spi-max-frequency = <0xb71b00> by convention should be put in decimal format 12000000, instead of hex, and in new versions of spidev.c, driver will complain about compatible = "spidev" property, as this property should describe real HW not some SW abstraction.

This 32766 bus(controller) number is dynamically allocated by the Kernel and is completely legal. In older Kernels, before device tree files, bus number had to be defined in board file platform data e.g.: .bus_num = 0,

As previously said there are no SPI bus(controller) device nodes spiX under/dev filesystem, only clients(chip) device nodes spidevX.Y.

spidev.c is a special kind of driver which is registered for generic SPI client(chip) devices, and it's main goal is to export Kernel low level SPI API to userspace, by creating character device nodes under /dev interface.

But if your goal is SPI driver for ADC, maybe it is better to use a existing Linux SPI driver for that chip, like e.g. for AD7791, or to write your own. Linux provides support for Industrial I/O Subsystem (iio) devices like analog to digital converters.

Linux Kernel Configuration
Device Drivers  --->
    ...
    <*>     Industrial I/O support --->
        --- Industrial I/O support
        ...
        Analog to digital converters  ---> 
            ...
            <*>  Analog Devices ADXYZ* ADC driver

In that case Linux will export your ADC device functionality to userspace in /sys filesystem:

/sys/bus/iio/devices/iio:deviceX

with device attributes accessible as files:

-r--r--r--    1 root     root          4096 Jan  1 04:18 name
drwxr-xr-x    2 root     root             0 Jan  1 04:18 power
-rw-r--r--    1 root     root          4096 Jan  1 04:18 sampling_frequency
-r--r--r--    1 root     root          4096 Jan  1 04:18 sampling_frequency_available

Upvotes: 1

Related Questions