Jetson Nano SPI Bus Not Working

Hi

I am having trouble getting the SPI bus on my Jetson Nano to work. The SPI loopback test does not work. I ran my code which worked previously on a a previous install of the OS and it also does not work. When connecting an oscilloscope to the SPI lines in both cases I see no wave form when executing any SPI code.

I started over with a clean image (the latest one from the Nvidia website) multiple times. I did enable both SPI busses on the Jetson-IO interface. I also tried the solution suggested in the following post: SPI bus not working - #18 by hh7rtxl7 but that just ended up messing up my OS (maybe I did something wrong). I have also tried everything on both of the Jetsons I have, with the same result. I don’t understand why after a clean install and setting up the Jetson-IO correctly it does not work. Surely there cant be such a big bug in the default setup? Or perhaps I am missing something simple. Any suggestions would be much appreciated.

Hi johannescleuvennink,

Are you using the devkit or custom board for Jetson Nano?

Have you enabled SPI through both pinmux and device tree?

Hi

I am Using the Devkit.

I only enabled it though the Jetson-IO tool. I am not very familiar with the more technical details of the device tree and such. Could you possibly link some recourse that might guide me with that process?

So I checked the /boot/extlinux/extlinux.conf file and it looks like below:

> TIMEOUT 30
> DEFAULT JetsonIO
> 
> MENU TITLE L4T boot options
> 
> LABEL primary
>       MENU LABEL primary kernel
>       LINUX /boot/Image
>       INITRD /boot/initrd
>       APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0
> 
> # When testing a custom kernel, it is recommended that you create a backup of
> # the original kernel and add a new entry to this file so that the device can
> # fallback to the original kernel. To do this:
> #
> # 1, Make a backup of the original kernel
> #      sudo cp /boot/Image /boot/Image.backup
> #
> # 2, Copy your custom kernel into /boot/Image
> #
> # 3, Uncomment below menu setting lines for the original kernel
> #
> # 4, Reboot
> 
> #LABEL backup
> #    MENU LABEL backup kernel
> #    LINUX /boot/Image.backup
> #    INITRD /boot/initrd
> #    APPEND ${cbootargs}
> 
> LABEL JetsonIO
> MENU LABEL Custom Header Config: <HDR40 User Custom [2023-04-12-102710]>
> LINUX /boot/Image
> FDT /boot/kernel_tegra210-p3448-0000-p3449-0000-b00-user-custom.dtb
> INITRD /boot/initrd
> APPEND ${cbootargs}

I even tried adding the FDT line to the primary Lablel too, but it made no difference. I then decompiled the .dtb file and saw that all the SPI pins seem to be correctly configured as seen below. For this particular test I only enabled SPI1 through jetson IO.

pinmux@700008d4 {
compatible = “nvidia,tegra210-pinmux”;
reg = <0x0 0x700008d4 0x0 0x2a5 0x0 0x70003000 0x0 0x294>;
#gpio-range-cells = <0x3>;
status = “okay”;
pinctrl-names = “default”;
pinctrl-0 = <0x131>;
pinctrl-1 = <0x3e>;
pinctrl-2 = <0x3f>;
linux,phandle = <0x40>;
phandle = <0x40>;

  exp-header-pinmux {
  	phandle = <0x131>;
  	linux,phandle = <0x131>;

  	hdr40-pin37 {
  		nvidia,enable-input = <0x0>;
  		nvidia,tristate = <0x1>;
  		nvidia,pull = <0x1>;
  		nvidia,function = "rsvd3";
  		nvidia,pins = "spi2_mosi_pb4";
  	};

  	hdr40-pin26 {
  		nvidia,enable-input = <0x1>;
  		nvidia,tristate = <0x0>;
  		nvidia,pull = <0x2>;
  		nvidia,function = "spi1";
  		nvidia,pins = "spi1_cs1_pc4";
  	};

  	hdr40-pin24 {
  		nvidia,enable-input = <0x1>;
  		nvidia,tristate = <0x0>;
  		nvidia,pull = <0x2>;
  		nvidia,function = "spi1";
  		nvidia,pins = "spi1_cs0_pc3";
  	};

  	hdr40-pin23 {
  		nvidia,enable-input = <0x1>;
  		nvidia,tristate = <0x0>;
  		nvidia,pull = <0x1>;
  		nvidia,function = "spi1";
  		nvidia,pins = "spi1_sck_pc2";
  	};

  	hdr40-pin22 {
  		nvidia,enable-input = <0x0>;
  		nvidia,tristate = <0x1>;
  		nvidia,pull = <0x1>;
  		nvidia,function = "rsvd3";
  		nvidia,pins = "spi2_miso_pb5";
  	};

  	hdr40-pin21 {
  		nvidia,enable-input = <0x1>;
  		nvidia,tristate = <0x0>;
  		nvidia,pull = <0x1>;
  		nvidia,function = "spi1";
  		nvidia,pins = "spi1_miso_pc1";
  	};

  	hdr40-pin19 {
  		nvidia,enable-input = <0x1>;
  		nvidia,tristate = <0x0>;
  		nvidia,pull = <0x1>;
  		nvidia,function = "spi1";
  		nvidia,pins = "spi1_mosi_pc0";
  	};

  	hdr40-pin18 {
  		nvidia,enable-input = <0x0>;
  		nvidia,tristate = <0x1>;
  		nvidia,pull = <0x2>;
  		nvidia,function = "rsvd3";
  		nvidia,pins = "spi2_cs0_pb7";
  	};

  	hdr40-pin16 {
  		nvidia,enable-input = <0x0>;
  		nvidia,tristate = <0x1>;
  		nvidia,pull = <0x2>;
  		nvidia,function = "rsvd3";
  		nvidia,pins = "spi2_cs1_pdd0";
  	};

  	hdr40-pin13 {
  		nvidia,enable-input = <0x0>;
  		nvidia,tristate = <0x1>;
  		nvidia,pull = <0x1>;
  		nvidia,function = "rsvd3";
  		nvidia,pins = "spi2_sck_pb6";
  	};

From what I could tell from other sources this all seems correct, yet I still see no SPI output with any test I have done.

Please refer to the following thread to verify loopback test.
How to set gpio for spi? - #27 by DaneLLL

Hi

I tried the loopback test again but I still don’t receive anything. I also checked the CS0 and there is also No activity. I also connected the oscilloscope and again saw no activity on any of the SPI pins during the loopback test.

Could you help to refer to the following thread to remove GPIO usage for SPI pins?
MCP251x broken on Jetpack 4.6.3 - #11 by KevinFFF

I’m sorry but I don’t understand exactly what you want me todo, I am not so well versed with the inner workings of the system. Could you please provide some clear steps?

Please refer to the following steps for SPI loopback test

Step 1. Connect MOSI and MISO of SPI1
MOSI(PIN19 of 40-pin GPIO header)
MISO(PIN21 of 40-pin GPIO header)

Step 2. Remove GPIO usage of SPI pins
2-1. Check flash log to know which dtb you are using (ex. tegra210-p3448-0000-p3449-0000-b00.dtb)
2-2. Remove GPIO usage in that device tree
2-2-1. Method 1 - Remove from source
diff --git a/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0000-b00.dtsi b/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0000-b00.dtsi
index 1ea952f..49d4196 100644
--- a/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0000-b00.dtsi
+++ b/kernel-dts/porg-platforms/tegra210-porg-gpio-p3448-0000-b00.dtsi
@@ -27,11 +27,6 @@
                gpio_default: default {
                        gpio-input = <
                                TEGRA_GPIO(BB, 0)
-                               TEGRA_GPIO(B, 4)
-                               TEGRA_GPIO(B, 5)
-                               TEGRA_GPIO(B, 6)
-                               TEGRA_GPIO(B, 7)
-                               TEGRA_GPIO(DD, 0)
                                TEGRA_GPIO(E, 6)
                                TEGRA_GPIO(S, 5)
                                TEGRA_GPIO(A, 5)
@@ -49,11 +44,6 @@
                                TEGRA_GPIO(J, 7)
                                TEGRA_GPIO(G, 2)
                                TEGRA_GPIO(G, 3)
-                               TEGRA_GPIO(C, 0)
-                               TEGRA_GPIO(C, 1)
-                               TEGRA_GPIO(C, 2)
-                               TEGRA_GPIO(C, 3)
-                               TEGRA_GPIO(C, 4)
                                TEGRA_GPIO(H, 2)
                                TEGRA_GPIO(H, 5)
                                TEGRA_GPIO(H, 6)

2-2-2. Method 2 - Remove from decompiled dtb
2-2-2-1 Find you dtb in Linux_for_Tegra/kernel/dtb/tegra210-p3448-0000-p3449-0000-b00.dtb

2-2-2-2 Dissemble the dtb to dts
dtc -I dtb -O dts -o temp.dts tegra210-p3448-0000-p3449-0000-b00.dtb

2-2-2-3 Modify the following line
-        gpio-input = <0xd8 0xc 0xd 0xe 0xf 0xe8 0x26 0x95 0x5 0xbc 0xbd 0xbe 0xc1 0xc2 0xa8 0xc8 0xca 0x4d 0x4e 0x4c 0x4f 0x32 0x33 0x10 0x11 0x12 0x13 0x14 0x3a 0x3d 0x3e 0x41 0xe4>;
+        gpio-input = <0xd8 0x26 0x95 0x5 0xbc 0xbd 0xbe 0xc1 0xc2 0xa8 0xc8 0xca 0x4d 0x4e 0x4c 0x4f 0x32 0x33 0x3a 0x3d 0x3e 0x41 0xe4>;

2-2-2-4 Assemble the dts back to dtb
dtc -I dts -O dtb -o tegra210-p3448-0000-p3449-0000-b00.dtb temp.dts

2-2-2-5 Flash the board

Step 3. Running Jetson-IO to enable SPI1
3-1. Run Jetson IO
$ sudo /opt/nvidia/jetson-io/jetson-io.py
3-2. Configure SPI1
Configure Jetson 40pin Header => Configure header pins manually => Select "spi1 (19,21,23,24,26)" => Back -> Save pin changes => Save and reboot to reconfigure pins
3-3. Check pinmux for SPI if the same as following
$  sudo cat /sys/kernel/debug/tegra_pinctrl_reg | grep -i spi
Bank: 1 Reg: 0x70003050 Val: 0x0000e044 -> spi1_mosi_pc0
Bank: 1 Reg: 0x70003054 Val: 0x0000e044 -> spi1_miso_pc1
Bank: 1 Reg: 0x70003058 Val: 0x0000e044 -> spi1_sck_pc2
Bank: 1 Reg: 0x7000305c Val: 0x0000e048 -> spi1_cs0_pc3
Bank: 1 Reg: 0x70003060 Val: 0x0000e048 -> spi1_cs1_pc4
Bank: 1 Reg: 0x70003064 Val: 0x00006044 -> spi2_mosi_pb4
Bank: 1 Reg: 0x70003068 Val: 0x00006044 -> spi2_miso_pb5
Bank: 1 Reg: 0x7000306c Val: 0x00006044 -> spi2_sck_pb6
Bank: 1 Reg: 0x70003070 Val: 0x00006048 -> spi2_cs0_pb7
Bank: 1 Reg: 0x70003074 Val: 0x00006048 -> spi2_cs1_pdd0

Step 4. Probe SPI driver
$ sudo modprobe spidev

Step 5. Download/build this test file:
5-1 Download
$ wget https://raw.githubusercontent.com/torvalds/linux/v4.9/tools/spi/spidev_test.c
5-2 Build on the board
$ gcc -o spidev_test spidev_test.c

Step 6. Run the command and check if the result is expected:
$ sudo ./spidev_test -D /dev/spidev0.0 -v -p "HelloWorld123456789abcdef"
Or 
$ sudo ./spidev_test -D /dev/spidev0.0 -s 10000000 -v
1 Like

Thanks for the steps.

I don’t know how to check the flash log but I checked the dmesg and it looks like I also use the tegra210-p3448-0000-p3449-0000-b00.dtb file. So I decompiled it and tried to find the section you are referring to but I cannot find it. I crl-f and look for “gpio_default” but there are no results. Am I in the right file or am I missing something?

Do you have kernel source of L4T?

Do you use the following command to decompile?

$dtc -I dtb -O dts -o tegra210-p3448-0000-p3449-0000-b00.dts tegra210-p3448-0000-p3449-0000-b00.dtb

Please provide your flash log or serial console log for further check.

I’m afraid I do not know what you mean by “Do you have kernel source of L4T?”

Yes, I did use that command to decompile. Here is the resulting file. Perhaps you can tell me where in the file the changes need to be made.

tegra210-p3448-0000-p3449-0000-b00.dts (318.6 KB)

I’m not sure if this is the log you need but its the only one I could find. If its not right please tell me where I can find the log you need:

kern.log (97.8 KB)

You could refer to the following instruction to download and build kernel.
Kernel Customization — Manually Downloading and Expanding Kernel Sources

If you are using JP4.6.3(R32.7.3) for Jetson Nano, it should be tegra210-porg-gpio-p3448-0000-b00.dtsi, not the one you provided.(tegra210-p3448-0000-p3449-0000-b00.dts)

Please provide the flash log from host side. (i.e. the log showed on the console of your host PC while you are flashing the board)

I appreciate the effort you are putting in to help me, but I don’t understand exactly what you want me to do…

Why do you want me to download a new kernal? Witch one should I even get?

You said in your own example that you use the tegra210-p3448-0000-p3449-0000-b00.dtb file. now you say I need to edit the tegra210-porg-gpio-p3448-0000-b00.dtsi file. What is that? how do I access it? Is that “diff --get” command supposed do get it for me, because it does not work?

I cannot provide the flash log because I flash the OS to an SD card using balena etcher from my windows PC. I tried to find a log on balena etcher but I could not.

It cannot be this difficult to get a basic function working from a fresh install of the OS. Everywhere I could find they simply say to flash the OS, activate SPI on jetson IO and then the spidev test should work.

I really appreciate you trying, but I am new to this device and I need it to be dumbed down a bit more.

There are device tree files in kernel source.
Please refer to the instruction to get the kernel source so that you could modify tegra210-porg-gpio-p3448-0000-b00.dtsi to remove GPIO usage for the SPI pins.

This issue is about SPI pins be configured as GPIO so that it can’t be used for SPI.
That’s why I’m guiding you to remove these lines.

Thanks for the clarification. I have followed the instructions to download and extract the kernal source files for my release of L4T. I then searched the files to find the tegra210-porg-gpio-p3448-0000-b00.dtsi file. I found it, but it does not look exactly like the one in your example, so I dont know which lines to remove. Here is the file I have:

tegra210-porg-gpio-p3448-0000-b00.dtsi (1.7 KB)

There is however a similar file that does seem to have the same structure as your example. its the tegra210-porg-gpio-p3448-0000-a00.dtsi file (so a00 rather than b00) should I edit this one like you showed?

tegra210-porg-gpio-p3448-0000-a00.dtsi (2.1 KB)

Even if I do manage to edit the file correctly, what are the next steps? Do I then need to build a new kernal based on the edited file? Could you please then specify which instructions I should follow for this since there are a bunch of different instructions on that page to do different things.

Please make sure which pins for SPI and device tree you are using.

Have you tried to use Ubuntu as host PC to flash the devkit with SDKM or flash script?

I’ve listed the overall steps for SPI loopback test, and it is also verified on the Jetson Nano devkit.

Which page do you mean?

Please make sure which pins for SPI and device tree you are using.

I want to use the standard pins for SPI (SPI1: 19, 21, 23, 24, 26, SPI2: 13, 16,18, 22, 37). If I look at the results from the dmesg command, it looks like this:

DTS File Name: /dvs/git/dirty/git-master_linux/kernel/kernel-4.9/arch/arm64/boot/dts/…/…/…/…/…/…/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-p3448-0000-p3449-0000-b00.dts

So I’m guessing then I need to edit the tegra210-porg-gpio-p3448-0000-b00.dtsi file, but i don’t know which lines to remove. I don’t know how a line like TEGRA_GPIO(X, 6) corresponds to a pin like pin 19 for example. It would be great if you could look at the file I previously posted and tell me exactly which changes to make.

Have you tried to use Ubuntu as host PC to flash the devkit with SDKM or flash script?

No, but I will try that too.

So I followed the instructions on the following page you sent me: Kernel Customization — Jetson Linux Developer Guide documentation I followed steps 1-4 under the heading “Manually download and expand the kernel sources” Now if I edit the file what do I do next? do I continue with the steps under the heading “Build the kernel” and “build real time kernel”?

You could check the SPI pins corresponding to the number of GPIO pins through pinmux table of Jetson Nano here.

Build the kernel.

Could you help to run the following command in your board and share the result for further check?

$sudo cat /sys/kernel/debug/tegra_pinctrl_reg | grep -i spi

Ok so when I check the pinmux i see the spi pins are the same ones you sowed me previously:

TEGRA_GPIO(B, 4)
TEGRA_GPIO(B, 5)
TEGRA_GPIO(B, 6)
TEGRA_GPIO(B, 7)
TEGRA_GPIO(DD, 0)

and

TEGRA_GPIO(C, 0)
TEGRA_GPIO(C, 1)
TEGRA_GPIO(C, 2)
TEGRA_GPIO(C, 3)
TEGRA_GPIO(C, 4)

The problem is, as I told you before, that these are not in the tegra210-porg-gpio-p3448-0000-b00.dtsi file. They are however in the tegra210-porg-gpio-p3448-0000-a00.dtsi (Note a00 not b00) so should I modify the 00a one even thou my system currently uses the 00b device tree?

I also ran the command you requested and this is the result:

Bank: 1 Reg: 0x70003050 Val: 0x0000e044 → spi1_mosi_pc0
Bank: 1 Reg: 0x70003054 Val: 0x0000e044 → spi1_miso_pc1
Bank: 1 Reg: 0x70003058 Val: 0x0000e044 → spi1_sck_pc2
Bank: 1 Reg: 0x7000305c Val: 0x0000e048 → spi1_cs0_pc3
Bank: 1 Reg: 0x70003060 Val: 0x0000e048 → spi1_cs1_pc4
Bank: 1 Reg: 0x70003064 Val: 0x00006044 → spi2_mosi_pb4
Bank: 1 Reg: 0x70003068 Val: 0x00006044 → spi2_miso_pb5
Bank: 1 Reg: 0x7000306c Val: 0x00006044 → spi2_sck_pb6
Bank: 1 Reg: 0x70003070 Val: 0x00006048 → spi2_cs0_pb7
Bank: 1 Reg: 0x70003074 Val: 0x00006048 → 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: 0x00002040 → qspi_sck_pee0
Bank: 1 Reg: 0x7000308c Val: 0x00002000 → qspi_cs_n_pee1
Bank: 1 Reg: 0x70003090 Val: 0x00002040 → qspi_io0_pee2
Bank: 1 Reg: 0x70003094 Val: 0x00002040 → qspi_io1_pee3
Bank: 1 Reg: 0x70003098 Val: 0x00002040 → qspi_io2_pee4
Bank: 1 Reg: 0x7000309c Val: 0x00002040 → 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