odroid-c2:application_note:gpio:spi

'ODROID-N2' on this page refers to the ODROID-N2 series (N2, N2+, N2L).

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.
    • ODROID-M1 on 4.19.219 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.

Load the modules with the following commands.

target
sudo modprobe spidev
sudo modprobe spi_s3c64xx

And you can check if the module loaded.

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

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

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

Load the modules with the following commands.

target
sudo modprobe spidev
sudo modprobe spicc

And you can check if the module loaded.

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

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

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

Load the modules with the following commands.

target
sudo modprobe spidev
sudo modprobe spi_gpio
sudo modprobe spi_bitbang

And you can check if the module loaded.

target
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.

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

Enable the modules using device-tree-compiler.

target
sudo apt install device-tree-compiler

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

target
# 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.

target
# 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.

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

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

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

Enable the modules using device-tree-compiler.

target
sudo apt install device-tree-compiler

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

target
# 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.

target
# 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.

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

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

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

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

target
sudo fdtput -t s /boot/dtbs/4.19.219-odroid-arm64/rockchip/rk3568-odroid-m1.dtb spi0 status "okay"

Check if it changed.

target
root@odroid:~# fdtget -t s /boot/dtbs/4.19.219-odroid-arm64/rockchip/rk3568-odroid-m1.dtb spi0 status
okay

Then reboot to apply the changes.

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

target
$ 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.

Download a source code and compile.

target
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.

target
# 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

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

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) I2C0_SDA 3 4 5.0V - -
I(P/U) GPIOX.18 (#494) I2C0_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) 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_CLK 23 24 SPI0_SS0 GPIOX.10 (#486) I(P/U)
- - GND 25 26 SPI0_SS1 GPIOA.4 (#464) I(P/D)
I(P/U) GPIOA.14 (#474) I2C1_SDA 27 28 I2C1_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) PWM_C 33 34 GND - -
I(P/D) GPIOX.6 (#482) PWM_D 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

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) I2C0_SDA 3 4 5.0V - -
I(P/U) GPIOX.18 (#494) I2C0_SCL 5 6 GND - -
I(P/D) GPIOX.5 (#481) PWM_C 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) PWM_D 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 SPI0_CS1 GPIOH.6 (#433) I(P/D)
I(P/U) GPIOA.14 (#474) I2C1_SDA 27 28 I2C1_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_A 33 34 GND - -
I(P/D) GPIOX.19 (#495) PWM_B 35 36 GPIOH.5 (#432) -
ADC.AIN2 37 38 REF 1.8V
- - GND 39 40 ADC.AIN0

2019/10/29 16:27 · luke.go
ODROID-M1

J1 - 2x20 PINS

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) GPIO3B.6 (#110) I2C0_SDA 3 4 5.0V - -
I(P/U) GPIO3B.5 (#109) I2C0_SCL 5 6 GND - -
I(P/D) GPIO0B.6 (#14) 7 8 UART1_TX GPIO3D.6 (#126) I(P/U)
- - GND 9 10 UART1_RX GPIO3D.7 (#127) I(P/U)
I(P/U) GPIO0C.0 (#16) UART0_RX 11 12 GPIO3D.0 (#120) I(P/U)
I(P/U) GPIO0C.1 (#17) UART0_TX 13 14 GND - -
I(P/U) GPIO3B.2 (#106) 15 16 GPIO3C.6 (#118) I(P/U)
- - 3.3V 17 18 GPIO3C.7 (#119) I(P/U)
I(P/U) GPIO2D.1 (#89) SPI0_MOSI 19 20 GND - -
I(P/U) GPIO2D.0 (#88) SPI0_MISO 21 22 GPIO3D.1 (#121) I(P/U)
I(P/U) GPIO2D.3 (#91) SPI0_SCLK 23 24 SPI0_CS0 GPIO2D.2 (#90) I(P/U)
- - GND 25 26 GPIO3D.2 (#122) I(P/D)
I(P/U) GPIO0B.4 (#12) I2C1_SDA 27 28 I2C1_SCL GPIO0B.3 (#11) I(P/U)
I(P/U) GPIO4C.1 (#145) UART1_CTS 29 30 GND - -
I(P/U) GPIO4B.6 (#142) UART1_RTS 31 32 GPIO3D.3 (#123) I(P/D)
I(P/U) GPIO0B.5 (#13) 33 34 GND - -
I(P/D) GPIO3D.5 (#125) 35 36 GPIO3D.4 (#124) -
ADC.AIN1 37 38 REF 1.8V
- - GND 39 40 ADC.AIN0

2022/01/06 15:10 · neal

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
  • M1: /dev/spidev0.0
ODROID-XU4
target
root@odroid:~# ./spidev_test -D /dev/spidev1.0
ODROID-C1+
target
root@odroid:~# ./spidev_test -D /dev/spidev0.0
ODROID-C2
target
root@odroid64:~# ./spidev_test -D /dev/spidev0.0
ODROID-N2
target
root@odroid:~# ./spidev_test -D /dev/spidev0.0
ODROID-C4
target
root@odroid:~# ./spidev_test -D /dev/spidev0.0
ODROID-M1
target
root@odroid:~# ./spidev_test -D /dev/spidev0.0

These results should be the same.

target
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.

target
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.

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

Bits per word

8 bits

1MHz max speed and 8 bits per word.

target
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.

target
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.

target
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.

target
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.

target
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.

target
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.

target
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

2020/03/18 14:31 · luke.go
  • odroid-c2/application_note/gpio/spi.txt
  • Last modified: 2020/04/23 17:43
  • by luke.go