Updated instructions for SPI on Nano DevelopmentKit with L4T 32.2.1

It’s a good thing I don’t do this sort of thing for a living. Oh wait…I do!. :)

Yeah. I forgot to mention that I had to remove the CUDA stuff in order to get the image under the 2gb github limit. I was going to zip those up in a separate tarball and post them but I forgot that as well. I’ll do it now and push them up to the github release in case someone needs them.

lol… luckily, the QA was on it… since I volunteered.

Has anyone had luck with either gtjoseph github repo:
https://github.com/gtjoseph/jetson-nano-support

or rt-net:
https://github.com/rt-net/JetsonNano_DT_SPI

I tried gtjosheph scripts, but it never enabled /dev/spidev* interfaces. I then tried rt-net, run.sh script and it did enable /dev/spidev0.0.

But when I transmit data through it I don’t see the SCLK, CS, MOSI toggle. I tried to use spidev_test:

nlbutts@jetson:~/projects$ sudo ./spidev_test -D /dev/spidev0.0 -v -p "test" -C
spi mode: 0x4
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 74 65 73 74 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | test
RX | 00 00 00 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | ....

But this is the result on the pins:
https://photos.app.goo.gl/RbJZrtEwc9nxprV16

When I run gpioinfo I get the following:

sudo gpioinfo | grep spi
gpiochip0 - 256 lines:
	line   0:      unnamed       unused   input  active-high 
	line   1:      unnamed       unused   input  active-high 
	line   2:      unnamed  "pcie_wake"   input  active-high [used]
	line   3:      unnamed       unused   input  active-high 
	line   4:      unnamed       unused   input  active-high 
	line   5:      unnamed       unused   input  active-high 
	line   6:      unnamed "vdd-usb-hub-en" output active-high [used]
	line   7:      unnamed       unused   input  active-high 
	line   8:      unnamed       unused   input  active-high 
	line   9:      unnamed       unused   input  active-high 
	line  10:      unnamed       unused   input  active-high 
	line  11:      unnamed       unused   input  active-high 
	line  12:      unnamed       unused   input  active-high 
	line  13:      unnamed       unused   input  active-high 
	line  14:      unnamed       unused   input  active-high 
	line  15:      unnamed       unused   input  active-high 
	line  16:      unnamed       unused   input  active-high 
	line  17:      unnamed       unused   input  active-high 
	line  18:      unnamed       unused   input  active-high 
	line  19:      unnamed       unused   input  active-high 
	line  20:      unnamed       unused   input  active-high 
	line  21:      unnamed       unused   input  active-high 
	line  22:      unnamed       unused   input  active-high 
	line  23:      unnamed       unused   input  active-high 
	line  24:      unnamed       unused   input  active-high 
	line  25:      unnamed       unused   input  active-high 
	line  26:      unnamed       unused   input  active-high 
	line  27:      unnamed       unused   input  active-high 
	line  28:      unnamed       unused   input  active-high 
	line  29:      unnamed       unused   input  active-high 
	line  30:      unnamed       unused   input  active-high 
	line  31:      unnamed       unused   input  active-high 
	line  32:      unnamed       unused   input  active-high 
	line  33:      unnamed       unused   input  active-high 
	line  34:      unnamed       unused   input  active-high 
	line  35:      unnamed       unused   input  active-high 
	line  36:      unnamed       unused   input  active-high 
	line  37:      unnamed       unused   input  active-high 
	line  38:      unnamed       unused   input  active-high 
	line  39:      unnamed       unused   input  active-high 
	line  40:      unnamed       unused   input  active-high 
	line  41:      unnamed       unused   input  active-high 
	line  42:      unnamed       unused   input  active-high 
	line  43:      unnamed       unused   input  active-high 
	line  44:      unnamed       unused   input  active-high 
	line  45:      unnamed       unused   input  active-high 
	line  46:      unnamed       unused   input  active-high 
	line  47:      unnamed       unused   input  active-high 
	line  48:      unnamed       unused   input  active-high 
	line  49:      unnamed       unused   input  active-high 
	line  50:      unnamed       unused   input  active-high 
	line  51:      unnamed       unused   input  active-high 
	line  52:      unnamed       unused   input  active-high 
	line  53:      unnamed       unused   input  active-high

Any ideas?

I run for now the rt-net

ls -la /dev/spidev*
crw------- 1 root root 153, 0 Dez 5 23:24 /dev/spidev0.0

root@jetson:~# gpioinfo | grep -i spi
line 12: “SPI1_MOSI” unused input active-high
line 13: “SPI1_MISO” unused input active-high
line 14: “SPI1_SCK” unused input active-high
line 15: “SPI1_CS0” unused input active-high
line 16: “SPI0_MOSI” unused input active-high
line 17: “SPI0_MISO” unused input active-high
line 18: “SPI0_SCK” unused input active-high
line 19: “SPI0_CS0” unused input active-high
line 20: “SPI0_CS1” unused input active-high
line 232: “SPI1_CS1” unused input active-high

I just ran a quick test on a fresh system using the tool from gtjoseph https://github.com/gtjoseph/jetson-nano-support/releases/download/sdcard/flash-dtb-update-2019-11-24.tar.gz available as release here https://github.com/gtjoseph/jetson-nano-support/releases and it all works fine:

jetson@nanobox:~$ ls -la /dev/spi*
crw------- 1 root root 153, 0 Dez 6 15:05 /dev/spidev0.0
crw------- 1 root root 153, 1 Dez 6 15:05 /dev/spidev0.1

sudo gpioinfo | grep -i spi
line 16: “SPI0_MOSI” unused input active-high
line 17: “SPI0_MISO” unused input active-high
line 18: “SPI0_SCK” unused input active-high
line 19: “SPI0_CS0” “cs_gpio” output active-high [used]
line 20: “SPI0_CS1” “cs_gpio” output active-high [used]
line 232: “SPI1_CS1” unused output active-high

sudo ./spidev_test -D /dev/spidev0.0 -v -p “test” -C
spi mode: 0x4
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 74 65 73 74 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |test|
RX | 74 65 73 74 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |test|

@gtj, there may be an issue with the device tree used in your setup: I was trying again to make an SPI LCD work and I noticed that with your DTB I get issues accessing GPIOs.
see above for some of the differences in the two DBT variants. the one from rt-net doesn’t throw any errors when trying to use GPIOs to control the LCD.

OK, I’ll take a look. This was with the tarball and “flashme.sh” correct?

that’s right.
I dd’d the 5 partitions from my other nano where I have only the spi0.0 enabled with the rt-net approach.
I managed to get a piscreen (raspberry pi SPI LCD) working https://devtalk.nvidia.com/default/topic/1066616/jetson-nano/-solved-lcd-tft-piscreen-not-working-on-r32-2-1/post/5409545/#5409545

@mirel.t.lazar Try the attached package and see if it works for you.

It only enables spidev0.0 and it uses hardware chip-select instead of gpio chip select.
flash-dtb-update-2019-12-07.tar.gz (504 KB)

I’ve updated my github repo with all you need to update a live Nano or an offline SDCard with the partitions necessary to enable SPI1 and /dev/spidev0.0. No need to install the Linux for Tegra package unless you want to modify the DTBs.

https://github.com/gtjoseph/jetson-nano-support/blob/master/README.md
https://github.com/gtjoseph/jetson-nano-support/releases/latest

I can confirm that the live update works. Although the SPI on the Jetson Nano behaves strangely. I will type up a new thread tonight on my findings. TLDR: SPI CS takes a long time to assert and deassert, which slows down the ability to read/write data at a high speed.

One of the things I did in this release was to have spi1 use hardware based chip select instead of GPIO based. I did this so there’d be less interference with other GPIO stuff. It’s odd that being hardware based is slower but I’ve seen that in the past. I can easily change just that CS pin back to CPIO and create a new package. Give me a few hours.

New release created that changes the chip select control method back to GPIO.

https://github.com/gtjoseph/jetson-nano-support/releases/download/v1.0.2/flash-dtb-update-2019-12-09.tar.gz

Hi gtj,

I just flash the tegra210-p3448-0000-p3449-0000-a02-spidev-0.dtb in jetson-nano-support to Nano dev kit which runs on l4t-r32.2.3-4.9. But it shows “SPI0_CS1” is not used. Any idea would be appreciated.

FYI,

sercomm@tegra-ubuntu:~/spi$ sudo gpioinfo | grep -i spi
        line  12:  "SPI1_MOSI"       unused   input  active-high
        line  13:  "SPI1_MISO"       unused   input  active-high
        line  14:   "SPI1_SCK"       unused   input  active-high
        line  15:   "SPI1_CS0"       unused   input  active-high
        line  16:  "SPI0_MOSI"       unused   input  active-high
        line  17:  "SPI0_MISO"       unused   input  active-high
        line  18:   "SPI0_SCK"       unused   input  active-high
        line  19:   "SPI0_CS0"    "cs_gpio"  output  active-high [used]
        line  20:   "SPI0_CS1"       unused   input  active-high
        line 232:   "SPI1_CS1"       unused   input  active-high
sercomm@tegra-ubuntu:~/spi$ cat /proc/devices | grep -i spi
153 spi
sercomm@tegra-ubuntu:~/spi$ ls /dev | grep -i spi
spidev0.0
sercomm@tegra-ubuntu:~/spi$ sudo ./spidev_test -D /dev/spidev0.0 -v -p "test" -C
spi mode: 0x4
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 74 65 73 74 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | test
RX | 00 00 00 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | ....

Sigh. I knew someone would want the second chip select. :)
I left it out to free up that GPIO pin for other reasons. If you really need the second chip select I can make a package for you. Let me know.

I really wish nvidia would make this process easier. :(

Hi gtj,

Thanks for your reply.

sercomm:~/spi$ bash spi.sh
[sudo] password for sercomm:
spi mode: 0x4
bits per word: 8
max speed: 500000 Hz (500 KHz)
mode & SPI_TX_QUAD=0
mode & SPI_TX_DUAL=0
mode & SPI_RX_QUAD=0
mode & SPI_RX_DUAL=0
mode & SPI_LOOP=0
Function:[transfer]--LineNum:[172]
verbose=1
TX | 74 65 73 74 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | test
output_file=0
Function:[transfer]--LineNum:[193]
RX | 00 00 00 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | ....
input_tx
sercomm:~/spi$ bash spi.sh
spi mode: 0x4
bits per word: 8
max speed: 5000000 Hz (5000 KHz)
mode & SPI_TX_QUAD=0
mode & SPI_TX_DUAL=0
mode & SPI_RX_QUAD=0
mode & SPI_RX_DUAL=0
mode & SPI_LOOP=0
Function:[transfer]--LineNum:[172]
verbose=1
TX | 74 65 73 74 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | test
output_file=0
Function:[transfer]--LineNum:[193]
RX | 00 00 00 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __  | ....
input_tx
sercomm:~/spi$ gpio
gpiodetect  gpiofind    gpioget     gpioinfo    gpiomon     gpioset
sercomm:~/spi$ sudo gpioinfo | grep -i spi
        line  12:  "SPI1_MOSI"       unused   input  active-high
        line  13:  "SPI1_MISO"       unused   input  active-high
        line  14:   "SPI1_SCK"       unused   input  active-high
        line  15:   "SPI1_CS0"       unused   input  active-high
        line  16:  "SPI0_MOSI"       unused   input  active-high
        line  17:  "SPI0_MISO"       unused   input  active-high
        line  18:   "SPI0_SCK"       unused   input  active-high
        line  19:   "SPI0_CS0"    "cs_gpio"  output  active-high [used]
        line  20:   "SPI0_CS1"       unused   input  active-high
        line 232:   "SPI1_CS1"       unused   input  active-high

Our hardware only use SPI0_CS0. After shortcut 19pin(SPI0_MOSI) and 21pin(SPI0_MISO). The spidev_test script above shows zeros but not “test”.
Could you help me to figure out what the problem it is?

Thanks again.

Hi mirel.t.lazar,

How could you receive data “test”?
Thanks.

maybe there is… the other night I was fiddling with pwm and since I already know things are never easy with Nvidia (let’s not mention Linus ;-)= ) I ended up using this:
apt install busybox

Enable Pin 32 / PWM0

busybox devmem 0x700031fc 32 0x45
busybox devmem 0x6000d504 32 0x2

Enable Pin 33 / PWM2

busybox devmem 0x70003248 32 0x46
busybox devmem 0x6000d100 32 0x00

Then enable & control the pwm, e.g.

cd /sys/devices/7000a000.pwm/pwm/pwmchip0
|–echo 0 > export # Control PWM0 on Pin 32
|–echo 2 > export # Control PWM2 on Pin 33

is there a way to do the same for enabling SPI on-the-fly?
more info here https://devtalk.nvidia.com/default/topic/1057330/jetson-nano/what-pins-can-be-used-for-pwm-control-except-33-in-samples/post/5386543/#5386543

@garretzou
what do you have on: sudo cat /sys/kernel/debug/tegra_gpio ?

I used the flash package as explained in https://devtalk.nvidia.com/default/topic/1062646/jetson-nano/updated-instructions-for-spi-on-nano-developmentkit-with-l4t-32-2-1/post/5409375/#5409375

on mine now
root@jetson:~# gpioinfo | grep -i spi
line 12: “SPI1_MOSI” unused input active-high
line 13: “SPI1_MISO” unused input active-high
line 14: “SPI1_SCK” unused input active-high
line 15: “SPI1_CS0” unused input active-high
line 16: “SPI0_MOSI” unused input active-high
line 17: “SPI0_MISO” unused input active-high
line 18: “SPI0_SCK” unused input active-high
line 19: “SPI0_CS0” unused input active-high
line 20: “SPI0_CS1” unused input active-high
line 232: “SPI1_CS1” unused input active-high

root@jetson:~# cat /sys/kernel/debug/tegra_gpio
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
A: 0:0 64 40 40 24 00 00 000000
B: 0:1 f0 00 00 20 00 00 000000
C: 0:2 00 00 00 00 00 00 000000

root@jetson:~# ls /dev/spi*
/dev/spidev0.0