SPI bus not working

I’ve got two Jetson Nanos, and can’t get the SPI bus to work on either of them (presumably for the same reason on both).

If I run ls -lah /dev/spidev* on either one, I can see that there are 4 SPI devices I can talk to (bus 0 or 1, chip select 0 or 1 for each), and all of them are readable/writable by users in the gpio group, which is a group that I am in. I can also run lsmod | grep spi and get back spidev 13282 0. That last 0 is a little odd because it indicates that nothing is using the module, but at least the module exists and is ready to go if something wants to use it.

I plugged pin 19 into pin 21 on the “jetson-io-base-a” breakout board, which is supposed to be plugging MOSI into MISO on SPI bus 0. I then ran spidev-test from GitHub - rm-hull/spidev-test, but I only receive null bytes, indicating that the SPI bus isn’t working properly (it’s not receiving the data it’s sending despite the pins being jumped together).

I’ve tried running sudo /opt/nvidia/jetson-io/jetson-io.py, but on one of my jetsons, it exits immediately with no output, and on the other it lets me configure camera-related stuff but has no options for configuring SPI or other GPIO pin things. I suspect that this is the thing that’s going wrong, that if I could successfully get jetson-io.py to enable the SPI pins, things would improve. On the other hand, given that the /dev/spidev* devices already exist, maybe the SPI bus is already set up and I don’t need to worry about jetson-io.py at all, and the problem is elsewhere.

Any idea what’s going wrong? What should I try next?

Please upgrade to J4.6.1 or J4.6.2(r32.6.1/r32.7.x) and using jetson-io to configure 0n the device that able run and connect the MOSI/MISO for loopback test to verify.

And reference to below topic to modify the device tree manually for the device unable run jetson-io.

Do you have a link to instructions of how to upgrade to J4.6.2? I’ve tried various things, but am not confident I’m on the right track. For example, sudo apt-get install nvidia-jetpack only got to version 4.5, rather than 4.6.

I would suggest using sdkmanager to update it.

I tried following the instructions at https://developer.nvidia.com/drive/sdk-manager: I joined the developer program, and downloaded the .deb file. However, because my desktop machine has an AMD chipset, I can only seem to get the .deb file for AMD64, but the Nano uses an ARM chipset so it can’t install the package. I can’t easily download from Log in | NVIDIA Developer on the Nano itself because it has a GUI-less setup and it’s unclear how to log in to the developer program from just the terminal.

Is there a way to choose which chipset I download the .deb file for? Barring that, could you link to instructions of how to accomplish the suggestions you’ve made?

The .deb should able to install for AMD chipset. Does your host are ubuntu 16.04?

That’s the opposite of what I’m looking for: I agree that the .deb can install on AMD, but the Nano is an ARM chipset, and the .deb cannot install on that. I’m running Ubuntu 18.04.

I don’t think sdkmanager current support on ARM system.

Alright, the thing I had misunderstood about your previous suggestion was that sdkmanager doesn’t run on the Nano, it runs on my work computer and writes to the nano over USB.

I’ve now updated my Nano to Jetpack 4.6.2. I can check this by following the instructions at https://forums.developer.nvidia.com/t/checking-jetpack-version-on-jetson-nano/110901:

jetson@george:~$ dpkg-query --show nvidia-l4t-core
nvidia-l4t-core	32.7.2-20220420143418

and per JetPack Archive | NVIDIA Developer, version 32.7.2 is only used in Jetpack version 4.6.2.

No luck: jetson-io.py still lets me configure cameras and nothing else. I tried to follow the instructions at About using spi on Jetson NANO to manually configure the SPI pins, but running dmesg | grep -i kernel gives no output. I decided to modify /boot/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb because that’s the file that seems to have the SPI definitions inside it.

I’ve set the pins for SPI1 to “spi1” and the pins for SPI2 to “spi2”, and am confident I did that correctly because I can read them back out of the .dtb file:

jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi1_mosi_pc0 nvidia,function
spi1
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi1_miso_pc1 nvidia,function
spi1
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi1_sck_pc2 nvidia,function
spi1
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi1_cs0_pc3 nvidia,function
spi1
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi1_cs1_pc4 nvidia,function
spi1
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi2_mosi_pb4 nvidia,function
spi2
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi2_miso_pb5 nvidia,function
spi2
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi2_sck_pb6 nvidia,function
spi2
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi2_cs0_pb7 nvidia,function
spi2
jetson@george:~$ fdtget /boot/dtb/kernel_tegra210-p3448-0002-p3449-0000-b00.dtb /pinmux@700008d4/unused_lowpower/spi2_cs1_pdd0 nvidia,function
spi2

I rebooted, reran sudo modprobe spidev to get the devices back, but still, spidev_test doesn’t work (it only receives null bytes, no matter what data is sent out).

What else should I try? Do I need to somehow disable the pins as GPIO before enabling them as SPI? Is it a problem that the paths to these pins include the phrase “unused_lowpower”? Is there a link to clear instructions somewhere of how to enable the SPI bus?

What’s the GPIO state.

sudo cat /sys/kernel/debug/tegra_gpio

sudo cat /sys/kernel/debug/tegra_pinctrl_reg | grep -i spi
jetson@george:~$ sudo cat /sys/kernel/debug/tegra_gpio
[sudo] password for jetson: 
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
 A: 0:0 64 40 40 04 00 00 000000
 B: 0:1 00 00 00 00 00 00 000000
 C: 0:2 00 00 00 00 00 00 000000
 D: 0:3 00 00 00 00 00 00 000000
 E: 1:0 00 00 00 00 00 00 000000
 F: 1:1 00 00 00 00 00 00 000000
 G: 1:2 00 00 00 00 00 00 000000
 H: 1:3 fd 99 00 60 00 00 000000
 I: 2:0 07 07 03 02 00 00 000000
 J: 2:1 00 00 00 00 00 00 000000
 K: 2:2 00 00 00 00 00 00 000000
 L: 2:3 00 00 00 00 00 00 000000
 M: 3:0 00 00 00 00 00 00 000000
 N: 3:1 00 00 00 00 00 00 000000
 O: 3:2 00 00 00 00 00 00 000000
 P: 3:3 00 00 00 00 00 00 000000
 Q: 4:0 00 00 00 00 00 00 000000
 R: 4:1 00 00 00 00 00 00 000000
 S: 4:2 80 80 00 00 00 00 000000
 T: 4:3 01 01 00 00 00 00 000000
 U: 5:0 00 00 00 00 00 00 000000
 V: 5:1 02 00 00 02 00 00 000000
 W: 5:2 00 00 00 00 00 00 000000
 X: 5:3 78 08 08 70 00 60 606000
 Y: 6:0 02 00 00 02 00 00 000000
 Z: 6:1 0e 08 00 06 00 04 000400
AA: 6:2 00 00 00 00 00 00 000000
BB: 6:3 00 00 00 00 00 00 000000
CC: 7:0 92 80 80 10 00 12 121200
DD: 7:1 00 00 00 00 00 00 000000
EE: 7:2 00 00 00 00 00 00 000000
FF: 7:3 00 00 00 00 00 00 000000
jetson@george:~$ sudo cat /sys/kernel/debug/tegra_pinctrl_reg | grep -i spi
Bank: 1 Reg: 0x70003050 Val: 0x0000e015 -> spi1_mosi_pc0
Bank: 1 Reg: 0x70003054 Val: 0x0000e015 -> spi1_miso_pc1
Bank: 1 Reg: 0x70003058 Val: 0x0000e015 -> spi1_sck_pc2
Bank: 1 Reg: 0x7000305c Val: 0x0000e015 -> spi1_cs0_pc3
Bank: 1 Reg: 0x70003060 Val: 0x0000e015 -> spi1_cs1_pc4
Bank: 1 Reg: 0x70003064 Val: 0x00006016 -> spi2_mosi_pb4
Bank: 1 Reg: 0x70003068 Val: 0x00006016 -> spi2_miso_pb5
Bank: 1 Reg: 0x7000306c Val: 0x00006016 -> spi2_sck_pb6
Bank: 1 Reg: 0x70003070 Val: 0x00006016 -> spi2_cs0_pb7
Bank: 1 Reg: 0x70003074 Val: 0x00006015 -> spi2_cs1_pdd0
Bank: 1 Reg: 0x70003078 Val: 0x0000e015 -> spi4_mosi_pc7
Bank: 1 Reg: 0x7000307c Val: 0x0000e015 -> spi4_miso_pd0
Bank: 1 Reg: 0x70003080 Val: 0x0000e015 -> spi4_sck_pc5
Bank: 1 Reg: 0x70003084 Val: 0x0000e015 -> spi4_cs0_pc6
Bank: 1 Reg: 0x70003088 Val: 0x00002015 -> qspi_sck_pee0
Bank: 1 Reg: 0x7000308c Val: 0x00002015 -> qspi_cs_n_pee1
Bank: 1 Reg: 0x70003090 Val: 0x00002015 -> qspi_io0_pee2
Bank: 1 Reg: 0x70003094 Val: 0x00002015 -> qspi_io1_pee3
Bank: 1 Reg: 0x70003098 Val: 0x00002015 -> qspi_io2_pee4
Bank: 1 Reg: 0x7000309c Val: 0x00002015 -> qspi_io3_pee5
Bank: 0 Reg: 0x70000b70 Val: 0x00000001 -> drive_qspi_comp_control
Bank: 0 Reg: 0x70000b78 Val: 0x00000001 -> drive_qspi_lpbk_control
Bank: 0 Reg: 0x70000a78 Val: 0x00808000 -> drive_qspi_comp

The GPIO state is correct but the SPI pin configure is incorrect.
Make sure your modification is applied by dumped device tree.

dtc -I fs /proc/device-tree -O dts -o extracted_proc.dts

What should we look for in the dumped device tree to check if it’s correct? What should we do to change it? Do you have a link to instructions on how to do this correctly?

Have reference to below topic to check the dump file.

I got it to work! For anyone else with this problem, here’s what fixed it for me. Edit /boot/extlinux/extlinux.conf, and check that it’s got an FDT line which specifies which .dtb file to use. This line was missing for me, and the scary thing is that if you specify the wrong .dtb file, you brick the entire system until you reflash everything from scratch (which we’ve had to do several times). How do you tell which .dtb file to use? No idea; we tried a couple different ones before we got it right. Here’s what our /boot/extlinux/extlinux.conf file looks like now:

TIMEOUT 30
DEFAULT primary

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      FDT /boot/tegra210-p3448-0002-p3449-0000-b00.dtb
      APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0 sdhci_tegra.en_boot_part_access=1 nv-auto-config

The FDT line had been missing entirely, and we added it in.

Then, you need to go to that .dtb file, and decompile it to a .dts text file:

dtc -I dtb -O dts -o ~/tegra.dts /boot/tegra210-p3448-0002-p3449-0000-b00.dtb

(-I specifies the input format, -O specifies the output format, and -o specifies the output file location)

Edit that text file with the changes Shane suggested above. Specifically, for each of the spi*_*_* entries, in the nvidia,function field, change “rsvd” to “spi” (so, for spi1, change “rsvd1” to “spi1”, and for spi2, change “rsvd2” to “spi2”).

Now, it’s time to recompile the .dts file back to a .dtb file:

dtc -I dts -O dtb -o ~/tegra.dtb ~/tegra.dts
sudo cp ~/tegra.dtb /boot/tegra210-p3448-0002-p3449-0000-b00.dtb

Reboot, and either it’ll work, or you’ll have bricked your whole system and need to reinstall everything using the sdkmanager tool. This tool runs on your laptop, not the Jetson itself, and must be run on Ubuntu 18.04. If you are running a different OS (including a different version of Ubuntu!), you’ll need to set up a virtual machine running Ubuntu 18.04 to use this tool, or I think Nvidia has docker images of Ubuntu 18.04 with the sdkmanager inside.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.