Using SPI - FrankBau/meta-marsboard-bsp GitHub Wiki

Device Tree

You must enable a SPI bus and route it to the MarS board headers in the device tree:

edit/check kernel config

(See also Configure the Linux Kernel.)

From a bitbake shell:

bitbake -c menuconfig virtual/kernel

in the kernel config menu enable (if not already enabled) check:

Device Drivers
    [*] SPI support
        <*>   Freescale i.MX SPI controllers
        ...
        <*>   User mode SPI device driver support

Device Tree

Edit the device tree source file imx6q-marsboard.dts in folder build/tmp/work/marsboard-poky-linux-gnueabi/linux-marsboard/4.1.15-r0/git/arch/arm/boot/dts as follows:

within iomuxc/imx6q-marsboard block add a new block:

	pinctrl_ecspi2: ecspi2grp {
		fsl,pins = <
			MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK		0x100b1
			MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI		0x100b1
			MX6QDL_PAD_EIM_OE__ECSPI2_MISO		0x100b1
			MX6QDL_PAD_EIM_LBA__GPIO2_IO26		0x000b1
		>;
	};

at global level.

The pin muxing corresponds to the following pins on header J10:

Pin Function
15 ECSPI2_SS0
17 ECSPI2_SCLK
19 ECSPI2_MOSI
21 ECSPI2_MISO

At the very end of the device tree source file add a block:

&ecspi2 {
    fsl,spi-num-chipselects = <1>;
    cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi2>;
    status = "okay";

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

The spidev@0x00 subblock loads the spidev driver which creates a /dev/spidev1.0 tree entry.

in a bitbake shell enter

cse3:build$ bitbake -c devshell virtual/kernel

This will open a new shell. In that shell you may build the linux kernel, kernel modules and .. the device tree binary. let's build that:

root:kernel-source$ make imx6q-marsboard.dtb

In case of errors, you get something like:

Error: .../kernel-source/arch/arm/boot/dts/imx6q-marsboard.dts:387.1-2 syntax error
FATAL ERROR: Unable to parse input tree

Which tells you the line number (387) and column number (between column 1 and 2) to check for errors.

On success, you get a device tree binary imx6q-marsboard.dtb in folder build/tmp/work/marsboard-poky-linux-gnueabi/linux-marsboard/4.1.15-r0/build/arch/arm/boot/dts.

Switch MarS Board off, remove SD card. Copy the .dtb file to the boot partition of your SD card (use exactly the same name as the .dtb file already on the SD card) After MarS Board boot you will see a brand new spi device:

root@marsboard:~# ls /dev/spi*
/dev/spidev1.0

Testing SPI

You may want to check your spi device from userland:

sample code in Linux kernel docs

https://github.com/boundarydevices/linux-imx6/blob/boundary-imx_4.1.15_2.0.0_ga/Documentation/spi/spidev_test.c

Copy spidev_test.cto the MarS Board, compile, and start it:

root@marsboard:~# gcc -o spidev spidev_test.c 
root@marsboard:~# ./spidev -D  /dev/spidev1.0 

output:

root@marsboard:~# ./spidev -D  /dev/spidev1.0 
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
RX | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  | ................................

The FF are form the open MISO pin.

Connect MISO pin (pin 21 on header J10) to GND (pin 2 on header J10) and repeat:

root@marsboard:~# ./spidev -D  /dev/spidev1.0 
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  | ................................

Connect MISO pin (pin 21 on header J10) to MOSI` (pin 2 on header J10) and enter:

root@marsboard:~# ./spidev_test -D /dev/spidev1.0 -p "Hello world"

reply:

spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
RX | 48 65 6C 6C 6F 20 77 6F 72 6C 64 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | Hello.world

spiloop

Writing your own SPI kernel module

Using the generic spidev driver is not the best way, because it is not hardware function specific, but we leave it that way. The driver may complain during boot:

[    1.256583] spidev spi1.0: buggy DT: spidev listed directly in DT
...

In order to write your own SPI kernel module, use kernel mode drivers like

⚠️ **GitHub.com Fallback** ⚠️