====== SPI - Serial Peripheral Interface ======
{{:github-mark-32px.png?nolink |}}
Example available on [[https://github.com/grinn-pub/examples|GitHub]].
Check [[https://github.com/grinn-pub/examples/blob/master/configs/grinn_liteboard_spi_defconfig|liteboard SPI]] example.
SPI is a full-duplex, master - slave, synchronous serial interface used mainly used in embedded systems.
ditaa
/--------------\ /---------------\
| SPI master | | SPI slave 1 |
| | | |
| SCLK +-----------*------>+ SCLK |
| MOSI +---------*-|------>+ MOSI |
| MISO +<------*-|-|-------+ MISO |
| SS1 +-------|-|-|------>+ SS |
| cGRE SS2 +-----\ | | | | cYEL |
| | | | | | \---------------/
\--------------/ | | | |
| | | | /---------------\
| | | | | SPI slave 2 |
| | | | | |
| | | \------>+ SCLK |
| | \-------->+ MOSI |
| \-----------+ MISO |
\------------>+ SS |
| cYEL |
\---------------/
===== Interface =====
* SCLK - Serial Clock,
* MOSI - Master Output Slave Input,
* MISO - Master Input Slave Output,
* SS - Slave Select
===== SPI configuration =====
To configure SPI interface following parameters must be defined:
* clock frequency,
* clock polarity (CPOL):
* CPOL=0 - 0 is idle state, 1 is active state,
* CPOL=1 - 0 is active state, 1 is idle state,
* clock phase (CPHA):
* CPHA=0 - data sampling on the first clock edge,
* CPHA=1 - data sampling on the second clock edge.
===== liteSOM and SPI =====
{{ :litesom:ecspi_block_diagram.png?nolink&400 |ECSPI block diagram}}
;#;
//ECSPI block diagram
(source: i.MX 6UltraLite Applications Processor Reference Manual)//
;#;
''i.MX6UL'' supports up to four Enhanced Configurable Serial Peripheral Interfaces (''ECSPI'').
Each ''ECSPI'' contains a 64 x 32 receive buffer and a 64 x 32 transmit buffer. With data FIFOs, the ''ECSPI'' allows rapid data communication with fewer software interrupts.
Key features of the ''ECSPI'' include:
* Full-duplex synchronous serial interface,
* Master/Slave configurable,
* Four Chip Select (SS) signals to support multiple peripherals,
* Transfer continuation function allows unlimited length data transfers,
* 32-bit wide by 64-entry FIFO for both transmit and receive data,
* Polarity and phase of the Chip Select (SS) and SPI Clock (SCLK) are configurable,
* Direct Memory Access (DMA) support,
* Max operation frequency up to the reference clock frequency.
===== Device Tree =====
ecspi1: ecspi@02008000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
reg = <0x02008000 0x4000>;
interrupts = ;
clocks = <&clks IMX6UL_CLK_ECSPI1>,
<&clks IMX6UL_CLK_ECSPI1>;
clock-names = "ipg", "per";
status = "disabled";
};
ecspi2: ecspi@0200c000 {
[...]
};
ecspi3: ecspi@02010000 {
[...]
};
ecspi4: ecspi@02014000 {
[...]
};
Generic configuration for all four ''ECSPI'' peripherals you can find in [[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/imx6ul.dtsi|imx6ul.dtsi]] file.
Documentation for all SPI related items configured in this file you can find in [[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt|fsl-imx-cspi.txt]] file in the kernel documentation.
&iomuxc {
pinctrl_ecspi1: ecspi1grp {
fsl,pins = <
MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK 0x1b0b0
MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x1b0b0
MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x1b0b0
MX6UL_PAD_CSI_DATA07__ECSPI1_MISO 0x1b0b0
>;
};
};
{{ :litesom:devicetree:spi_litesom.png?nolink |SPI @ liteboard pinout}}
;#;
//SPI @ liteboard pinout//
;#;
To enable SPI on [[litesom:liteboard|liteboard]] we have to configure [[litesom:devicetree##iomux_configuration|IOMUX Controller]] to enable SPI pins for this board:
* ''CSI_DATA04'' as Serial Clock,
* ''CSI_DATA05'' as Slave Select,
* ''CSI_DATA06'' as Master Output Slave Input,
* ''CSI_DATA07'' as Master Input Slave Output.
&ecspi1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
cs-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
status = "okay";
spidev0: spi@0 {
compatible = "spidev";
reg = <0>;
spi-max-frequency = <5000000>;
};
};
As a ''Slave Select'' pin we can use any of ''i.MX6UL'' pin therefore it must be defined by the user. Here as Slave Select we are using ''GPIO4[26]''.
In this example we will allow userspace application to communicate directly with //SPI slave// device therefore //device tree// contains one SPI child node ''spidev0''. During boot kernel driver ''SPI_SPIDEV'' will register ''/dev/spidev0.0'' device which can be accessed by any userspace application.
In addition ''spidev0'' node defines maximal frequency for defined SPI interface - here 500kHz.
To compile ''spidev'' driver please select kernel option ''CONFIG_SPI_SPIDEV'' located in
-> Device Drivers
-> SPI support
-> User mode SPI device driver support
Please check [[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/spi/spi-bus.txt|spi-bus.txt]] file to check how to configure - via //device tree// - other SPI parameters.
===== Test tools =====
[[https://buildroot.org|Buildroot]] allows you build two SPI test tools:
* [[#spidev_test]],
* [[#spi-tools]].
==== spidev_test ====
=== Buildroot tree location ===
-> Target packages
-> Debugging, profiling and benchmark
-> spidev_test
=== Source code ===
Application source code is available [[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/spi/spidev_test.c|here]].
=== Loopback test ===
Please connect ''MISO'' and ''MOSI'' pins together and request ''spidev_test'' application to send and then receive default data package via SPI interface.
# spidev_test -D /dev/spidev0.0 -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D | ......@....�..................�.
RX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D | ......@....�..................�.
=== Other options ===
Please check application help to see available options.
Usage: spidev_test [-DsbdlHOLC3]
-D --device device to use (default /dev/spidev1.1)
-s --speed max speed (Hz)
-d --delay delay (usec)
-b --bpw bits per word
-i --input input data from a file (e.g. "test.bin")
-o --output output data to a file (e.g. "results.bin")
-l --loop loopback
-H --cpha clock phase
-O --cpol clock polarity
-L --lsb least significant bit first
-C --cs-high chip select active high
-3 --3wire SI/SO signals shared
-v --verbose Verbose (show tx buffer)
-p Send data (e.g. "1234\xde\xad")
-N --no-cs no chip select
-R --ready slave pulls low to pause
-2 --dual dual transfer
-4 --quad quad transfer
==== spi-tools ====
=== Buildroot tree location ===
-> Target packages
-> Hardware handling
-> spi-tools
=== Source code ===
See ''spi-tools'' on [[https://github.com/cpb-/spi-tools|GitHub]].
=== spi-config ===
This application can be used to read/set current ''spidev'' configuration.
== Read current SPI configuration ==
# spi-config -q -d /dev/spidev0.0
/dev/spidev0.0: mode=0, lsb=0, bits=8, speed=5000000
== Set SPI configuration ==
To configure SPI to use mode = 2 (CPOL=1, CPAH=0) please use following command.
# spi-config -m 2 -d /dev/spidev0.0
Please read application help to see other options.
# spi-config --help
usage: spi-config options...
options:
-d --device= use the given spi-dev character device.
-q --query print the current configuration.
-m --mode=[0-3] use the selected spi mode:
0: low iddle level, sample on leading edge,
1: low iddle level, sample on trailing edge,
2: high iddle level, sample on leading edge,
3: high iddle level, sample on trailing edge.
-l --lsb={0,1} LSB first (1) or MSB first (0).
-b --bits=[7...] bits per word.
-s --speed= set the speed in Hz.
-h --help this screen.
-v --version display the version number.
=== spi-pipe ===
''spi-pipe'' allows you to send and receive data simultaneously.
== Send data via SPI interface ==
To send string ''foo'' via SPI interface you can use following command
# echo "foo" | spi-pipe -d /dev/spidev0.0
== Read data via SPI interface ==
To read data received via SPI interface plse use following command
# spi-pipe -d /dev/spidev0.0 < /dev/zero | cat
== More options ==
To see other use cases please check ''spi-tools'' [[https://github.com/cpb-/spi-tools/blob/master/README.md|README]] file.