Difference between revisions of "SPI"

From ArmadeusWiki
Jump to: navigation, search
m (Linux user space C code)
 
(38 intermediate revisions by 3 users not shown)
Line 1: Line 1:
This page will summarize the informations to use the SPI bus on our boards.
+
 
 +
This page will summarize the informations to use the SPI bus on APF boards.
  
 
== Overview ==
 
== Overview ==
  
[http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus SPI] ('''S'''erial '''P'''eripheral '''I'''nterface) is a 3-wire full-duplex serial bus.
+
[http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus SPI] ('''S'''erial '''P'''eripheral '''I'''nterface) is a 4-wire full-duplex serial bus.
Wires used in SPI are :
+
Wires used in SPI are:
 
* '''MOSI''', '''M'''aster '''O'''utput '''S'''lave '''I'''nput : send data to slave.
 
* '''MOSI''', '''M'''aster '''O'''utput '''S'''lave '''I'''nput : send data to slave.
 
* '''MISO''', '''M'''aster '''I'''nput '''S'''lave '''O'''utput : receive data from slave.
 
* '''MISO''', '''M'''aster '''I'''nput '''S'''lave '''O'''utput : receive data from slave.
Line 10: Line 11:
 
* '''SSx''', '''S'''lave '''S'''elect : used to select the slave for communication with master.
 
* '''SSx''', '''S'''lave '''S'''elect : used to select the slave for communication with master.
  
On APF27, the imx27 contains 3 SPI devices that can be configured in master or slave. APF9328 (imxL) contains 2 SPI.
+
On [[APF27]], the i.MX27 contains 3 SPI devices that can be configured in master (slave mode is not supported by Linux). [[APF9328]] (i.MXL) contains 2 SPI.
  
 
== Linux configuration ==
 
== Linux configuration ==
 +
===APF27Dev with 2.6.29 kernel===
 +
SPI is used by some kernel drivers; when selecting them it will naturally activate the corresponding SPI bus. To use the SPI from user space you have first to be sure that the corresponding SPI bus is activated:
 +
<pre class="host">
 +
$ make linux-menuconfig
 +
</pre>
 +
 +
<pre class="config">
 +
    Device Drivers  --->
 +
        [*] SPI support  --->
 +
            ...
 +
            <*>  Freescale iMX SPI controller
 +
            [*]    CSPI1
 +
            [*]    CSPI2
 +
            [*]    CSPI3
 +
            ...
 +
</pre>
 +
 +
And user SPI device interface (spidev) option must be selected too (here as a module):
 +
 +
<pre class="config">
 +
    Device Drivers  --->
 +
        [*] SPI support  --->
 +
            ...
 +
            *** SPI Protocol Masters ***
 +
            <M>  User mode SPI device driver support
 +
            ...
 +
</pre>
 +
 +
With 2.6.29 kernels, on [[APF27Dev]], ''spidev device'' uses the bus number 2 and PortB17 as chip select (J22 connector, muxed with USB signals). So ''/dev/spidev1.2'' has to be used to access your device from userspace. To change this (for expert), the structure ''spi_board_info'' must be modified in platform file apf27-dev.c (in directory ''buildroot/output/build/linux-2.6.29.6/arch/arm/mach-mx2/'') :
 +
 +
<source lang="C">
 +
#ifdef CONFIG_SPI_SPIDEV
 +
{
 +
.modalias = "spidev",
 +
.controller_data = &spidev_hw, /* for chip select */
 +
.max_speed_hz = 8000000, /* 8MHz */
 +
.bus_num = 1, /* SPI2 */
 +
.mode = SPI_MODE_1,
 +
.chip_select = 2,
 +
.platform_data = &apf27_spidev_config,
 +
},
 +
#endif /* CONFIG_SPI_SPIDEV */
 +
...
 +
#ifdef CONFIG_SPI_SPIDEV
 +
#define SPIDEV_CS (GPIO_PORTB | 17)
 +
...
 +
</source>
 +
 +
===APF27Dev with 3.19+ kernels===
 +
* SPI3 bus (CS0), available on J8 connector, has been configured for spidev. ''/dev/spidev2.0'' is the device to use with these kernels. You'll need an up-to-date ''apf27.dtb''
 +
* to change it you will have to edit ''arch/arm/boot/dts/imx27-apf27dev.dts'' in Linux sources and then recompile kernel (make linux) and update dtb from U-Boot (run update_dtb).
 +
 +
===APF6Dev with 4.1+-legacy kernels===
 +
* SPI1 bus (CS0), available on J5 connector, has been configured for spidev. ''/dev/spidev0.0'' is the device to use with these kernels.
 +
 +
For more details on spidev usage, see [http://www.mjmwired.net/kernel/Documentation/spi kernel documentation].
 +
 +
==Usage==
 +
When loaded, this driver will create a ''/dev/spidevN.0'' node to read/write on SPI bus from userspace (N depends on your platform).
 +
<pre class="apf">
 +
# modprobe spidev
 +
# ls /dev/spidev*
 +
</pre>
  
 
== Linux user space C code ==
 
== Linux user space C code ==
 +
 +
To write/read on SPI via spidev driver from your program, use ioctl as described in [http://www.mjmwired.net/kernel/Documentation/spi/spidev spidev documentation].
 +
 +
Linux kernel provides a test tool, to compile and use it:
 +
<pre class="host">
 +
$ mkdir spitest
 +
$ cd spitest
 +
$ cp ../buildroot/output/build/linux-x.x.x/Documentation/spi/spidev_test.c .
 +
or
 +
$ cp ./buildroot/output/build/linux-4.x.x/tools/spi/spidev_test.c .    (on recent kernels)
 +
$ ../buildroot/output/host/usr/bin/arm-linux-xxx-gcc -o spidev_test spidev_test.c
 +
$ scp spidev_test root@192.168.1.22:/root/
 +
</pre>
 +
<pre class="apf">
 +
# ./spidev_test -D /dev/spidev2.0 -s 8000000
 +
</pre>
 +
 +
A module named [[AsDevices#SPI | as_spi]] has also been written in AsDevices to ease spidev usage from userspace.
  
 
== Tested SPI chips ==
 
== Tested SPI chips ==
  
* ADC : [[Max1027]]
+
* ADC : [[ADC max1027 | Max1027]]
 
* EEPROM : [[93LCXX]]
 
* EEPROM : [[93LCXX]]
 +
* [[FLIR_Lepton_module_usage_on_APF_%26_OPOS|FLIR Lepton]]
  
 
== Links ==
 
== Links ==
  
* SPI description on wikipedia.
+
* [http://fr.wikipedia.org/wiki/Serial_Peripheral_Interface  SPI description on wikipedia.]
 +
* [http://lxr.linux.no/#linux+v2.6.31/Documentation/spi/ Linux spidev documentation]

Latest revision as of 15:40, 31 January 2018

This page will summarize the informations to use the SPI bus on APF boards.

Overview

SPI (Serial Peripheral Interface) is a 4-wire full-duplex serial bus. Wires used in SPI are:

  • MOSI, Master Output Slave Input : send data to slave.
  • MISO, Master Input Slave Output : receive data from slave.
  • SCLK, : Serial Clock signal used to synchronise the transmission. (In imx27 (apf27) maximum frequency of SCLK is 22.167MHz in master mode and 16.625 in slave mode.
  • SSx, Slave Select : used to select the slave for communication with master.

On APF27, the i.MX27 contains 3 SPI devices that can be configured in master (slave mode is not supported by Linux). APF9328 (i.MXL) contains 2 SPI.

Linux configuration

APF27Dev with 2.6.29 kernel

SPI is used by some kernel drivers; when selecting them it will naturally activate the corresponding SPI bus. To use the SPI from user space you have first to be sure that the corresponding SPI bus is activated:

$ make linux-menuconfig
    Device Drivers  --->
        [*] SPI support  --->
            ...
            <*>   Freescale iMX SPI controller 
            [*]     CSPI1
            [*]     CSPI2
            [*]     CSPI3
            ...

And user SPI device interface (spidev) option must be selected too (here as a module):

    Device Drivers  --->
        [*] SPI support  --->
            ...
            *** SPI Protocol Masters ***
            <M>   User mode SPI device driver support
            ...

With 2.6.29 kernels, on APF27Dev, spidev device uses the bus number 2 and PortB17 as chip select (J22 connector, muxed with USB signals). So /dev/spidev1.2 has to be used to access your device from userspace. To change this (for expert), the structure spi_board_info must be modified in platform file apf27-dev.c (in directory buildroot/output/build/linux-2.6.29.6/arch/arm/mach-mx2/) :

#ifdef CONFIG_SPI_SPIDEV
	{
		.modalias		= "spidev",
		.controller_data	= &spidev_hw, /* for chip select */
		.max_speed_hz		= 8000000, /* 8MHz */
		.bus_num		= 1, /* SPI2 */
		.mode			= SPI_MODE_1,
		.chip_select		= 2,
		.platform_data		= &apf27_spidev_config,
	},
#endif /* CONFIG_SPI_SPIDEV */
...
#ifdef CONFIG_SPI_SPIDEV
#define SPIDEV_CS (GPIO_PORTB | 17)
...

APF27Dev with 3.19+ kernels

  • SPI3 bus (CS0), available on J8 connector, has been configured for spidev. /dev/spidev2.0 is the device to use with these kernels. You'll need an up-to-date apf27.dtb
  • to change it you will have to edit arch/arm/boot/dts/imx27-apf27dev.dts in Linux sources and then recompile kernel (make linux) and update dtb from U-Boot (run update_dtb).

APF6Dev with 4.1+-legacy kernels

  • SPI1 bus (CS0), available on J5 connector, has been configured for spidev. /dev/spidev0.0 is the device to use with these kernels.

For more details on spidev usage, see kernel documentation.

Usage

When loaded, this driver will create a /dev/spidevN.0 node to read/write on SPI bus from userspace (N depends on your platform).

# modprobe spidev
# ls /dev/spidev*

Linux user space C code

To write/read on SPI via spidev driver from your program, use ioctl as described in spidev documentation.

Linux kernel provides a test tool, to compile and use it:

$ mkdir spitest
$ cd spitest
$ cp ../buildroot/output/build/linux-x.x.x/Documentation/spi/spidev_test.c .
 or
$ cp ./buildroot/output/build/linux-4.x.x/tools/spi/spidev_test.c .    (on recent kernels)
$ ../buildroot/output/host/usr/bin/arm-linux-xxx-gcc -o spidev_test spidev_test.c
$ scp spidev_test root@192.168.1.22:/root/
# ./spidev_test -D /dev/spidev2.0 -s 8000000

A module named as_spi has also been written in AsDevices to ease spidev usage from userspace.

Tested SPI chips

Links