Using SPI - FrankBau/meta-marsboard-bsp GitHub Wiki
You must enable a SPI bus and route it to the MarS board headers in the device tree:
(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
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
You may want to check your spi device from userland:
Copy spidev_test.c
to 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
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