SPI

  • Operation confirmed with our
    • ODROID-XU4 on 4.14.40 kernel.
    • ODROID-C1+ on 3.10.107 kernel.
    • ODROID-C2 on 3.14.79 kernel.
    • ODROID-N2 on 4.9.141 kernel.
    • ODROID-C4 on 4.9.113 kernel.

This guide lets you know that how to make the SPI feature ready and that how to test the SPI feature including loopback test.

The SPI feature can be simply enabled by loading a module.

ODROID-XU4

Load the modules with the following commands.

sudo modprobe spidev
sudo modprobe spi_s3c64xx

And you can check if the module loaded.

root@odroid:~# lsmod | grep spi
spidev                 20480  0
spi_s3c64xx            20480  0

And the device file /dev/spidev1.0 has been created as well.

root@odroid:~# ls /dev/spidev*
/dev/spidev1.0

ODROID-C1+

Load the modules with the following commands.

sudo modprobe spidev
sudo modprobe spicc

And you can check if the module loaded.

root@odroid:~# lsmod | grep spi
spicc                   8279  0
spidev                  5442  0

And the device file /dev/spidev0.0 has been created as well.

root@odroid:~# ls /dev/spidev*
/dev/spidev0.0

ODROID-C2

Load the modules with the following commands.

sudo modprobe spidev
sudo modprobe spi_gpio
sudo modprobe spi_bitbang

And you can check if the module loaded.

root@odroid64:~# lsmod | grep spi
spi_gpio                6778  0
spi_bitbang             4063  1 spi_gpio
spidev                  6475  0

And the device file /dev/spidev0.0 has been created as well.

root@odroid64:~# ls /dev/spidev*
/dev/spidev0.0

ODROID-N2

Enable the modules using device-tree-compiler.

sudo apt install device-tree-compiler

Change the status to okay of the SPI nodes on the device tree.

# SPICC0
sudo fdtput -t s /media/boot/meson64_odroidn2.dtb /soc/cbus@ffd00000/spi@13000 status "okay"
 
# SPIDEV0
sudo fdtput -t s /media/boot/meson64_odroidn2.dtb /soc/cbus@ffd00000/spi@13000/spidev@0 status "okay"

Check if it changed.

# SPICC0
root@odroid:~# fdtget /media/boot/meson64_odroidn2.dtb /soc/cbus@ffd00000/spi@13000 status
okay
 
# SPIDEV0
root@odroid:~# fdtget /media/boot/meson64_odroidn2.dtb /soc/cbus@ffd00000/spi@13000/spidev@0 status
okay

Then reboot to apply the changes.

Then you can check if the modules loaded.

root@odroid:~# lsmod | grep spi
spidev                 20480  0
spi_meson_spicc        20480  0

Check the /dev/spidev0.0 file out as the below.

root@odroid:~# ls /dev/spidev*
/dev/spidev0.0

ODROID-C4

Enable the modules using device-tree-compiler.

sudo apt install device-tree-compiler

Change the status to okay of the SPI nodes on the device tree.

# SPICC0
sudo fdtput -t s /media/boot/meson64_odroidc4.dtb /soc/cbus@ffd00000/spi@13000 status "okay"
 
# SPIDEV0
sudo fdtput -t s /media/boot/meson64_odroidc4.dtb /soc/cbus@ffd00000/spi@13000/spidev@0 status "okay"

Check if it changed.

# SPICC0
root@odroid:~# fdtget /media/boot/meson64_odroidc4.dtb /soc/cbus@ffd00000/spi@13000 status
okay
 
# SPIDEV0
root@odroid:~# fdtget /media/boot/meson64_odroidc4.dtb /soc/cbus@ffd00000/spi@13000/spidev@0 status
okay

Then reboot to apply the changes.

Then you can check if the modules loaded.

root@odroid:~# lsmod | grep spi
spidev                 20480  0
spi_meson_spicc        20480  0

Check the /dev/spidev0.0 file out as the below.

root@odroid:~# ls /dev/spidev*
/dev/spidev0.0
  • You can use the wild card character(*) when you select spidev file, but be careful with using that due to the unexpected situation on your board.
  • This guide uses the wild card to give you the unified simple instruction for those 3 boards.

Preparation

Download a source code and compile.

sudo wget http://dn.odroid.com/Accessory/examples/spidev_test.c
sudo gcc -o spidev_test spidev_test.c

The help of the test utility.

# There's no option to show the help on this file.
# It shows if you enter this command with invalid arguments.
# So the '--help' option will show the help.
root@odroid:~# ./spidev_test --help
./spidev_test: unrecognized option '--help'
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 
  -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

Loopback test

Even though you haven't any SPI hardware device, you can test if the SPI feature works with a jump cable.

Before testing, make sure that a jump cable is connected between SPI MOSI and MISO pin directly.

Connect between pin #19 and #21.

  • If you use XU4 without Shifter Shield, use pin #7 and #9 at CON10 pin header.

Please refer to each wiki page about expansion connectors.

ODROID-XU4

CON 10 - 2x15 pins

Default Pin State GPIO & Export No Net Name Pin Number Pin Number Net Name GPIO & Export No Default Pin State
- - 5V0 1 2 GND - -
I XADC0AIN_0 ADC_0.AIN0 3 4 UART_0.CTSN GPA0.2 (#173) I(PUDN)
I(PUDN) GPA0.3 (#174) UART_0.RTSN 5 6 UART_0.RXD GPA0.0 (#171) I(PUDN)
I(PUDN) GPA2.7 (#192) SPI_1.MOISI 7 8 UART_0.TXD GPA0.1 (#172) I(PUDN)
I(PUDN) GPA2.6 (#191) SPI_1.MISO 9 10 SPI_1.CLK GPA2.4 (#189) I(PUDN)
I(PUDN) GPA2.5 (#190) SPI_1.CSN 11 12 PWRON Input Range (1.8V ~ 5V) I
I(PUDN) GPX1.5 (#21) XE.INT13 13 14 I2C_1.SCL GPB3.3 (#210) I(PUDN)
I(PUDN) GPX1.2 (#18) XE.INT10 15 16 I2C_1.SDA GPB3.2 (#209) I(PUDN)
I(PUDN) GPX1.6 (#22) XE.INT14 17 18 XE.INT11 GPX1.3 (#19) I(PUDN)
I(PUDN) GPX2.6 (#30) XE.INT22 19 20 XE.INT20 GPX2.4 (#28) I(PUDN)
I(PUDN) GPX2.5 (#29) XE.INT21 21 22 XE.INT23 GPX2.7 (#31) I(PUDN)
I XADC0AIN_3 ADC_0.AIN3 23 24 XE.INT17 GPX2.1 (#25) I(PUDN)
I(PUDN) GPX1.7 (#23) XE.INT15 25 26 XE.INT16 GPX2.0 (#24) I(PUDN)
I(PUDN) GPX3.1 (#33) XE.INT25 27 28 GND - -
- - VDD_IO(1.8V) 29 30 GND - -

2017/07/24 17:40 · luke.go
ODROID-XU4 with Shifter Shield

GPIO Map for WiringPi Library (Shifter-Shield 40 Pin)

GPIO WiringPi Name Mode Initial Level Header Pin Header Pin Initial Level Mode Name WiringPi GPIO
3.3V 1 2 5v
209 8 I2C1.SDA ALT1 1 3 4 5v
210 9 I2C1.SCL ALT1 1 5 6 0v
18 7 GPIO. 18 IN 1 7 8 1 ALT1 UART0.TX 15 172
0v 9 10 1 ALT1 UART0.RX 16 171
174 0 GPIO.174 ALT1 1 11 12 1 ALT1 GPIO.173 1 173
21 2 GPIO. 21 IN 1 13 14 0v
22 3 GPIO. 22 IN 1 15 16 1 IN GPIO. 19 4 19
3.3v 17 18 1 IN GPIO. 23 5 23
192 12 MOSI ALT1 1 19 20 0v
191 13 MISO ALT1 1 21 22 1 IN GPIO. 24 6 24
189 SCLK ALT1 0 23 24 1 OUT CE0 10 190
0v 25 26 1 OUT GPIO. 25 11 25
187 30 I2C5.SDA ALT2 1 27 28 1 ALT2 I2C_5.SCL 31 188
28 21 GPIO. 28 IN 1 29 30 0v
30 22 GPIO. 30 IN 1 31 32 1 IN GPIO. 29 26 29
31 23 GPIO. 31 IN 1 33 34 0v
24 POWER ON 35 36 1 IN GPIO. 33 27 33
25 AIN.0 37 38 1v8 28
0v 39 40 AIN.3 29

The “gpio readall” shows the pin-map of 40-pin-Shifter-Shield not 30-Pin-header.

PCB Layout for pin map

2017/07/24 17:40 · luke.go
ODROID-C1

J2 - 2x20 PINS

GPIO wPi Name Alternative/
Driving Capability
Mode V PU/PD PIN PIN PU/PD V Mode Alternative/
Driving Capability
Name wPi GPIO
- - 3.3V - - - - 1 2 - - - - 5.0V - -
74 - I2CA_SDA - IN 1 - 3 4 - - - - 5.0V - -
75 - I2CA_SCL - IN 1 - 5 6 - - - - GND - -
83 7 GPIOY.3 -/2mA IN 0 P/U 7 8 P/U 1 ALT1 - GPIOX.16 - 113
- - GND - - - - 9 10 P/U 1 ALT1 - GPIOX.17 - 114
88 0 GPIOY.8 -/3mA IN 1 P/U 11 12 P/U 0 IN -/2mA GPIOY.7 1 87
116 2 GPIOX.19 -/2mA IN 1 P/U 13 14 - - - - GND - -
115 3 GPIOX.18 -/2mA IN 0 P/D 15 16 P/U 1 IN -/3mA GPIOX.7 4 104
- - 3.3V - - - - 17 18 P/U 1 IN -/3mA GPIOX.5 5 102
107 12 GPIOX.10 PWM1/2mA IN 1 P/U 19 20 - - - - GND - -
106 13 GPIOX.9 -/3mA IN 1 P/U 21 22 P/U 1 IN -/3mA GPIOX.6 6 103
105 14 GPIOX.8 -/4mA IN 1 P/U 23 24 P/D 0 IN -/2mA GPIOX.20 10 117
- - GND - - - - 25 26 P/U 1 IN - GPIOX.21 11 118
76 - I2CB_SDA - IN 1 - 27 28 - 1 IN - I2CB_SCL - 77
101 21 GPIOX.4 -/3mA IN 1 P/U 29 30 - - - - GND - -
100 22 GPIOX.3 -/3mA IN 1 P/U 31 32 P/U 1 IN -/3mA GPIOX.2 26 99
108 23 GPIOX.11 PWM0/3mA IN 0 P/D 33 34 - - - - GND - -
97 24 GPIOX.0 -/3mA IN 1 P/U 35 36 P/U 1 IN -/3mA GPIOX.1 27 98
- - ADC.AIN0 10bit ADC#1(0~1.8V) - - - 37 38 - - - Output! 1.8V REF - -
- - GND - - - - 39 40 - - - 10bit ADC#0 (0~1.8V) ADC.AIN1 - -

2017/09/27 17:47 · luke.go
ODROID-C2

J2 - 2x20 PINS

GPIO wPi Name Alternative Mode V PU/PD PIN PIN PU/PD V Mode Alternative Name wPi GPIO
- - 3.3V - - - - 1 2 - - - - 5.0V - -
205 - I2CA_SDA - IN 1 - 3 4 - - - - 5.0V - -
206 - I2CA_SCL - IN 1 - 5 6 - - - - GND - -
249 7 GPIOX.21 - IN 1 P/U 7 8 P/U 1 ALT2 /dev/ttyS1 TXD1 - 240
- - GND - - - - 9 10 P/U 1 ALT2 /dev/ttyS1 RXD1 - 241
247 0 GPIOX.19 - IN 1 P/U 11 12 P/D 0 IN - GPIOX.10 1 238
239 2 GPIOX.11 - IN 1 P/U 13 14 - - - - GND - -
237 3 GPIOX.9 - IN 1 P/U 15 16 P/U 1 IN - GPIOX.8 4 236
- - 3.3V - - - - 17 18 P/U 1 IN - GPIOX.5 5 233
235 12 GPIOX.7 PWM1 IN 1 P/U 19 20 - - - - GND - -
232 13 GPIOX.4 - IN 1 P/U 21 22 P/U 1 IN - GPIOX.3 6 231
230 14 GPIOX.2 - IN 1 P/U 23 24 P/U 1 IN - GPIOX.1 10 229
- - GND - - - - 25 26 P/D 0 IN - GPIOY.14 11 225
207 - I2CB_SDA - IN 1 - 27 28 - 1 IN - I2CB_SCL - 208
228 21 GPIOX.0 - IN 1 P/U 29 30 - - - - GND - -
219 22 GPIOY.8 - IN 1 P/U 31 32 P/U 1 IN - GPIOY.13 26 224
234 23 GPIOX.6 PWM0 IN 0 P/D 33 34 - - - - GND - -
214 24 GPIOY.3 - IN 1 P/U 35 36 P/U 1 IN - GPIOY.7 27 218
- - ADC.AIN1 10bit ADC (0~1.8V) - - - 37 38 - - - - 1.8V REF - -
- - GND - - - - 39 40 - - - 10bit ADC(00~1.8V) ADC.AIN0 - -

2017/06/16 17:01 · luke.go
ODROID-N2

J2 - 2x20 PINS

WE SHOULD CHECK THE PIN MAP!!!

Default Pin State GPIO & Export No Net Name Pin Number Pin Number Net Name GPIO & Export No Default Pin State
- - 3.3V 1 2 5.0V - -
I(P/D) GPIOX.17 (#493) I2C-2 SDA 3 4 5.0V - -
I(P/U) GPIOX.18 (#494) I2C-2 SCL 5 6 GND - -
I(P/D) GPIOA.13 (#473) 7 8 TXD1 GPIOX.12 (#488) I(P/U)
- - GND 9 10 RXD1 GPIOX.13 (#489) I(P/U)
I(P/U) GPIOX.3 (#479) 11 12 PWM_E GPIOX.16 (#492) I(P/U)
I(P/U) GPIOX.4 (#480) 13 14 GND - -
I(P/U) GPIOX.7 (#483) 15 16 GPIOX.0 (#476) I(P/U)
- - 3.3V 17 18 GPIOX.1 (#477) I(P/U)
I(P/U) GPIOX.8 (#484) SPI0_MOSI 19 20 GND - -
I(P/U) GPIOX.9 (#485) SPI0_MISO 21 22 GPIOX.2 (#478) I(P/U)
I(P/U) GPIOX.11 (#487) SPI0_CLK 23 24 SPI0_SS0 GPIOX.10 (#486) I(P/U)
- - GND 25 26 GPIOA.4 (#464) I(P/D)
I(P/U) GPIOA.14 (#474) I2C-3 SDA 27 28 I2C-3 SCL GPIOA.15 (#475) I(P/U)
I(P/U) GPIOX.14 (#490) 29 30 GND - -
I(P/U) GPIOX.15 (#491) 31 32 GPIOA.12 (#472) I(P/D)
I(P/U) GPIOX.5 (#481) 33 34 GND - -
I(P/D) GPIOX.6 (#482) 35 36 GPIOX.19 (#495) -
ADC.AIN3 37 38 REF 1.8V
- - GND 39 40 ADC.AIN2

2018/12/17 12:20 · luke.go
ODROID-C4

J2 - 2x20 PINS

WE SHOULD CHECK THE PIN MAP!!!

Default Pin State GPIO & Export No Net Name Pin Number Pin Number Net Name GPIO & Export No Default Pin State
- - 3.3V 1 2 5.0V - -
I(P/D) GPIOX.17 (#493) I2C1_SDA 3 4 5.0V - -
I(P/U) GPIOX.18 (#494) I2C1_SCL 5 6 GND - -
I(P/D) GPIOX.5 (#481) 7 8 TXD1 GPIOX.12 (#488) I(P/U)
- - GND 9 10 RXD1 GPIOX.13 (#489) I(P/U)
I(P/U) GPIOX.3 (#479) 11 12 PWM_E GPIOX.16 (#492) I(P/U)
I(P/U) GPIOX.4 (#480) 13 14 GND - -
I(P/U) GPIOX.7 (#483) PWM_F 15 16 GPIOX.0 (#476) I(P/U)
- - 3.3V 17 18 GPIOX.1 (#477) I(P/U)
I(P/U) GPIOX.8 (#484) SPI0_MOSI 19 20 GND - -
I(P/U) GPIOX.9 (#485) SPI0_MISO 21 22 GPIOX.2 (#478) I(P/U)
I(P/U) GPIOX.11 (#487) SPI0_SCLK 23 24 SPI0_CS0 GPIOX.10 (#486) I(P/U)
- - GND 25 26 GPIOH.6 (#433) I(P/D)
I(P/U) GPIOA.14 (#474) I2C-2 SDA 27 28 I2C-2 SCL GPIOA.15 (#475) I(P/U)
I(P/U) GPIOX.14 (#490) 29 30 GND - -
I(P/U) GPIOX.15 (#491) 31 32 GPIOH.7 (#434) I(P/D)
I(P/U) GPIOX.6 (#482) PWM_C 33 34 GND - -
I(P/D) GPIOX.19 (#495) PWM_D 35 36 GPIOH.5 (#432) -
ADC.AIN2 37 38 REF 1.8V
- - GND 39 40 ADC.AIN0

2019/10/29 16:27 · luke.go

Run to test.
The spidev number is different by which board you use.

  • XU4: /dev/spidev1.0
  • C1+/C2: /dev/spidev0.0
  • N2/C4: /dev/spidev0.0
ODROID-XU4
root@odroid:~# ./spidev_test -D /dev/spidev1.0
ODROID-C1+
root@odroid:~# ./spidev_test -D /dev/spidev0.0
ODROID-C2
root@odroid64:~# ./spidev_test -D /dev/spidev0.0
ODROID-N2
root@odroid:~# ./spidev_test -D /dev/spidev0.0
ODROID-C4
root@odroid:~# ./spidev_test -D /dev/spidev0.0

These results should be the same.

root@odroid:~# ./spidev_test -D /dev/spidev*
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
 
01 02 03 04 


If the module isn't loaded and/or spidev file isn't created, it results like the below.

root@odroid:~# ./spidev_test -D /dev/spidev*
can't open device: No such file or directory
Aborted

If the jump cable isn't connected well, it results like the below.

root@odroid:~# ./spidev_test -D /dev/spidev*
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
 
FF FF FF FF 

Various tests

Bits per word

8 bits

1MHz max speed and 8 bits per word.

root@odroid:~# ./spidev_test -D /dev/spidev* -s 1000000 -b 8
spi mode: 0
bits per word: 8
max speed: 1000000 Hz (1000 KHz)

SPIDEV-8bits-1Mhz

16 bits

1MHz max speed and 16 bits per word.

root@odroid:~# ./spidev_test -D /dev/spidev* -s 1000000 -b 16
spi mode: 0
bits per word: 16
max speed: 1000000 Hz (1000 KHz)

SPIDEV-16bits-1Mhz

32 bits

1MHz max speed and 32 bits per word.

root@odroid:~# ./spidev_test -D /dev/spidev* -s 1000000 -b 32
spi mode: 0
bits per word: 32
max speed: 1000000 Hz (1000 KHz)

SPIDEV-32bits-1Mhz

SPI mode

Mode 0

1MHz max speed, 32 bits per word and SPI mode 0.

root@odroid:~# ./spidev_test -D /dev/spidev* -s 1000000 -b 32
spi mode: 0
bits per word: 32
max speed: 1000000 Hz (1000 KHz)

SPIDEV-32bits-mode-0

Mode 1

1MHz max speed, 32 bits per word and SPI mode 1.

root@odroid:~# ./spidev_test -D /dev/spidev* -s 1000000 -b 32 -H
spi mode: 1
bits per word: 32
max speed: 1000000 Hz (1000 KHz)

SPIDEV-32bits-mode-1

Mode 2

1MHz max speed, 32 bits per word and SPI mode 2.

root@odroid:~# ./spidev_test -D /dev/spidev* -s 1000000 -b 32 -O
spi mode: 2
bits per word: 32
max speed: 1000000 Hz (1000 KHz)

SPIDEV-32bits-mode-2

Mode 3

1MHz max speed, 32 bits per word and SPI mode 3.

root@odroid:~# ./spidev_test -D /dev/spidev* -s 1000000 -b 32 -H -O
spi mode: 3
bits per word: 32
max speed: 1000000 Hz (1000 KHz)

SPIDEV-32bits-mode-3