SPI (Linux)
Introductionβ
This article aims to provide a guide to help you navigate through the complexities of using SPI (Serial Peripheral Interface) on Toradex SoMs and the Embedded Linux Reference Images we provide, including both downstream and upstream configurations. Additionally, it will provide clear instructions on how to enable and/or bind the SPI bus, allowing you to effectively communicate with peripheral devices using this communication protocol.
Why Use SPIβ
Serial Peripheral Interface (SPI) is a popular communication protocol used to connect peripheral devices, such as sensors and displays, to a microcontroller in embedded systems. SPI enables synchronous serial communication between a master device and multiple slave devices. In SPI communication, data is transmitted in a full-duplex manner, with the master device generating a clock signal to synchronize the data transfer.
SPI communication involves four signal lines: MOSI, MISO, SCLK, and SS. MOSI and MISO lines transmit and receive data, respectively, while the SCLK line generates the clock signal. The SS line selects a specific slave device with which the master device communicates. Multiple slave devices can be connected to the same bus, and each slave device has its own SS line. SPI communication provides high data rates, simple hardware requirements, and flexible configuration.
SPI on Toradex Computer on Modulesβ
Colibriβ
The Colibri standard provides one SPI interface compatible with all modules of the Colibri family which historically is called Synchronous Serial Port (SSP).
SODIMM Pin | Colibri Signal Name | SSP Description | SPI Description |
---|---|---|---|
86 | SSPFRM | Synchronous Serial Port Frame | SPI Chip Select; SPI Enable Signal; SPI Slave Select |
88 | SSPSCLK | Synchronous Serial Port Clock | SPI Serial Clock; (SCK) |
90 | SSPRXD | Synchronous Serial Port Receive | SPI Master Input / Slave Output (MISO); SPI DATA In (DIN) |
92 | SSPTXD | Synchronous Serial Port Transmit | SPI Master Output / Slave Input (MOSI); SPI Data Out (DOUT) |
The Colibri module standard features one generic SPI interface:
SoM Interface | Device nodes names | Note |
---|---|---|
SPI1 | /dev/colibri-spi-cs0 | General Purpose |
To obtain the device nodes names for the Colibri module family:
# ls -l /dev/colibri-spi*
It will display the available Colibri pin-compatible SPIs and display the corresponding names used by the BSP. Those corresponding names are important because the Linux kernel logs will print the real device names (e.g. /dev/spidev3.0
), not the Colibri symlinks (e.g. /dev/colibri-spi-cs0
).
For non-standard interfaces, consult the specific SoM datasheet.
Apalisβ
The Apalis standard provides two SPI interfaces compatible with all modules of the Apalis family.
MXM3 Pin | Apalis Signal Name | Description |
---|---|---|
225 | SPI1_MOSI | SPI Master Output, Slave Input; SPI Data Out (DOUT) |
223 | SPI1_MISO | SPI Master Input, Slave Output; SPI DATA In (DIN) |
227 | SPI1_CS | SPI Chip Select; SPI Enable Signal; SPI Slave Select |
221 | SPI1_CLK | SPI Serial Clock; (SCK) |
231 | SPI2_MOSI | SPI Master Output, Slave Input; SPI Data Out (DOUT) |
229 | SPI2_MISO | SPI Master Input, Slave Output; SPI DATA In (DIN) |
233 | SPI2_CS | SPI Chip Select; SPI Enable Signal; SPI Slave Select |
235 | SPI2_CLK | SPI Serial Clock; (SCK) |
The Apalis module standard features two generic SPI interface:
SoM Interface | Device nodes names | Note |
---|---|---|
SPI1 | /dev/apalis-spi1-cs0 | General Purpose |
SPI2 | /dev/apalis-spi2-cs0 | General Purpose |
To obtain the device nodes names for the Apalis module family:
# ls -l /dev/apalis-spi*
It will display the available Apalis pin-compatible SPIs and display the corresponding names used by the BSP. Those corresponding names are important because the Linux kernel logs will print the real device names (e.g. /dev/spidev3.0
), not the Apalis symlinks (e.g. /dev/apalis-spi1-cs0
).
For non-standard interfaces, consult the specific SoM datasheet.
Verdinβ
The Verdin Family Specification provides one SPI interface in the category Always Compatible, available on all modules of the Verdin family. The interface features a single chip select pin.
SODIMM Pin | Apalis Signal Name | Description |
---|---|---|
196 | SPI_1_CLK | SPI Serial Clock; (SCK) |
198 | SPI_1_MISO | SPI Master Input, Slave Output; SPI DATA In (DIN) |
200 | SPI_1_MOSI | SPI Master Output, Slave Input; SPI Data Out (DOUT) |
202 | SPI_1_CS | SPI Chip Select; SPI Enable Signal; SPI Slave Select |
The Verdin module standard features only one generic SPI interface:
SoM Interface | Device nodes names | Note |
---|---|---|
SPI1 | /dev/verdin-spi-cs0 | General Purpose |
To obtain the device nodes names for the Verdin module family:
# ls -l /dev/verdin-spi*
It will display the available Verdin pin-compatible SPIs and display the corresponding names used by the BSP. Those corresponding names are important because the Linux kernel logs will print the real device names (e.g. /dev/spidev3.0
), not the Verdin symlinks (e.g. /dev/verdin-spi-cs0
).
For non-standard interfaces, consult the specific SoM datasheet.
Verdin iMX8M Mini modules do not have a native CAN Controller. So, for using CAN, it requires the usage of an external CAN Controller through SPI port. You can read more about this at CAN (Linux)
How to Enable SPI and Bind SPIDEVβ
The approach described on this section is the most generic approach to enable SPIDEV on Toradex Embedded Linux reference images, i.e. it's valid for all use cases. However, for the eMMC-based modules, Toradex provides pre-built Device Tree overlays to enable SPIDEV. You can find the steps at the article Device Tree Overlays (Linux) to enable the SPIDEV overlays for your specific SoM.
- Check that there are no pre-enabled SPI devices.
# ls /dev/colibri-spi*
- Check the SPI devices under
/sys/bus
.
# ls /sys/bus/spi/devices
spi2.0
- Unbind the device from the mcp251x driver.
# echo spi2.0 > /sys/bus/spi/drivers/mcp251x/unbind
- Allow the device to take spidev driver.
# echo spidev > /sys/bus/spi/devices/spi2.0/driver_override
- Bind it to the spidev driver.
# echo spi2.0 > /sys/bus/spi/drivers/spidev/bind
- Check if the process worked by listing the
/dev
directory
# ls -la /dev/colibri-spi
lrwxrwxrwx 1 root root 9 Nov 26 17:12 /dev/colibri-spi-cs0 -> spidev2.0
User-space accessβ
SPI access from user-space is provided through the spidev driver which exports device files under /dev
. See Documentation/spi/spidev in the kernel sources for more information.
The following shows a read using the sample code in the kernel sources (tools/spi/spidev_test.c) using spidev interface. Make sure to replace the device with the one available in your SoM.
# spidev_test -D /dev/colibri-spi-cs0
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
Kernel-space driversβ
The Linux kernel already provides drivers for various SPI devices, hence before writing your own driver checking your Linux kernels configuration options and/or searching through the kernel mailing list is best practice.