SPI bus interface

This article is a practical guide to use the SPI bus available on the Acme Systems boards

The Serial Peripheral Interface bus or SPI bus is a synchronous serial data link standard that operates in full duplex mode. Devices communicate in master/slave mode where the master device initiates the data frame. Multiple slave devices are allowed with individual slave select (chip select) lines.

The SPI signals available on the different Acme Systems boards are:

SPI Signal I/O Function FOX G20 Daisy-1 Aria G25 Terra Arietta Acqua
SPI0 MOSI O Master Output Slave Input J7.10 D7.2 S11 D15.2 J2.7
SPI0 MISO I Master Input Slave Output J7.9 D7.3 S12 D15.3 J2.8
SPI0 SCLK O Clock J7.7 D7.4 S10 D15.4 J2.6
SPI0 CS0 O Chip Select 0 J7.8 D7.5 S9 D15.5 J2.5
SPI0 CS1 O Chip Select 1 J7.19 D7.6 S16 D15.6 J2.10
SPI0 CS2 O Chip Select 2 D7.7 S22 D15.7 J2.9
SPI0 CS3 O Chip Select 3 J6.27 D7.8 J2.12
SPI1 MOSI O Master Output Slave Input J4.8 J3.22
SPI1 MISO I Master Input Slave Output J4.10 J3.24
SPI1 SCLK O Clock J4.7 J3.25
SPI1 CS0 O Chip Select 0 J4.25 J3.23
SPI1 CS1 O Chip Select 1 J4.23 J3.26
SPI1 CS2 O Chip Select 2 J4.12 J3.28
SPI1 CS3 O Chip Select 3 J4.14 J3.29

Not all the signales are available by default and not all SPI lines are listed on this table or muxed in this way.

Refer to the MCU datasheets to find other lines.

This tutorial illustrates how use the SPI bus under Linux Kernel >=3.11. If you are using a previous version please read: Working with SPI bus under Linux Kernel 2.6.x

Linux Kernel driver and device tree binding

To use the SPI bus be sure that the SPI driver module and the SPIDEV user space interface are enabled in the Linux Kernel configuration:

Device Drivers  --->
  [*] SPI support  ---> 
    <*>   Atmel SPI Controller 
    <*>   User mode SPI device driver support

Enable also the SPIDEV interface

DTS binding example for Aria G25

spi0: spi@f0000000 {
    status = "okay";
    interrupts = <13 4 5>;
    cs-gpios = <&pioA 14 0>, <&pioA 7 0>, <0>, <0>;

    device@0 {
        compatible = "spidev";
        spi-max-frequency = <5000000>;
        reg = <0>;
    };

    device@1 {
        compatible = "spidev";
        spi-max-frequency = <5000000>;
        reg = <1>;
    };
};

DTS binding example for Arietta G25

spi1: spi@f0004000 {
    status = "okay";
    cs-gpios = <&pioA 8 0>, <&pioA 0 0>, <&pioA 31 0>, <&pioA 30 0>;
    device@0 {
        compatible = "spidev";
        spi-max-frequency = <50000000>;     // 50 MHz
        reg = <0>;
    };
    device@1 {
        compatible = "spidev";
        spi-max-frequency = <5000000>;      // 5 MHz
        reg = <1>;
    };
    device@2 {
        compatible = "spidev";
        spi-max-frequency = <5000000>;      // 5 MHz
        reg = <2>;
    };
    device@3 {
        compatible = "spidev";
        spi-max-frequency = <5000000>;      // 5 MHz
        reg = <3>;
    };
};

DTS binding example for Acqua A5

spi0: spi@f0004000 {
    status = "okay";
    cs-gpios = <&pioD 13 0>, <&pioD 14 0>, <&pioD 15>, <&pioD 16>;

    device@0 {
        compatible = "spidev";
        spi-max-frequency = <50000000>;     // 50 MHz
        reg = <0>;
    };
    device@1 {
        compatible = "spidev";
        spi-max-frequency = <5000000>;      // 5 MHz
        reg = <1>;
    };
    device@2 {
        compatible = "spidev";
        spi-max-frequency = <5000000>;      // 5 MHz
        reg = <2>;
    };
    device@3 {
        compatible = "spidev";
        spi-max-frequency = <5000000>;      // 5 MHz
        reg = <3>;
    };
};

spi1: spi@f8008000 {
    status = "disabled";
    cs-gpios = <&pioC 25 0>, <&pioC 26 0>, <&pioC 27 0>, <&pioC 28 0>;
};

Code example

This basic example shows how to send two chars on spi bus 0 and receive in full duplex two chars:

It needs spi_ctypes.py and asm_generic_ioctl.py files available inside the same playground directory.

Related links

Author:
Sergio Tanzilli - tanzilli@acmesystems.it
http://www.tanzilli.com - https://github.com/tanzilli