====== 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.