This is to report an issue I encountered in R32.3.1, using the jetson-io.py tool to enable SPI.
Note: Thanks for providing this new tool!
I am porting my sensor from Raspberry Pi 3B to Nvidia Jetson Nano.
I am using SPI0 to connect my sensor, specifically pins 19, 21, 23, 24, 26.
Those pins are properly enabled by jetson-io.py when I choose the enable SPI option.
My sensor slave is using pin 26 for CS, so that’s CS1, and thus, will be CS pin for SPI0 channel 1.
When I checked spidev devices, I saw these:
nvidia@nvidia:~/$ ll /dev/*spi*
crw-rw---- 1 root gpio 153, 0 Jan 31 17:18 /dev/spidev0.0
crw-rw---- 1 root gpio 153, 2 Jan 31 17:18 /dev/spidev1.0
I tried sending data to /dev/spidev1.0 (used linux’s spidev_test.c as reference) but I don’t receive any signals in SPI0 pins when I did that (checked via oscilloscope).
So next, I tried to read/write data at /dev/spidev0.0 and there was CLK, MOSI, but my sensor wasn’t responding.
The CS being driven by Nano as the Master was pin 24 (CS0), which was for channel 0.
Since wrong CS was being triggered by Nano, I can’t use the SPI0 channel 1 connection properly.
So I checked my working SPI setup in Raspberry Pi Model 3B and that one had this:
raspi@raspi:~/$ ll /dev/*spi*
crw-rw---- 1 root gpio 153, 0 Jan 31 18:21 /dev/spidev0.0
crw-rw---- 1 root gpio 153, 2 Jan 31 18:21 /dev/spidev0.1
This means that:
- /dev/spidev0.x is actually for SPI0 (19, 21, 23, 24, 26);and
- /dev/spidev1.x is actually for SPI1 (13, 16, 18, 22, 37).
And if 2 channels will be used for SPI0, there should have been /dev/spidev0.0 and /dev/spidev0.1 for each.
So my problem seems to be, the jetson-io.py tool only generated pin-config for /dev/spidev0.0 but not /dev/spidev0.1 - and I need to use /dev/spidev0.1 if my SPI slave’s CS is connected at pin 26 (CS1).
I believe both /dev/spidev0.0 and /dev/spidev0.1 should be available for SPI0 when you enable SPI0 via jetson-io.py, considering both pin 24 (CS0) and pin 26 (CS1) are both enabled and available for use anyway.
In any case, I had to check if my theory is right so I did the following steps.
- I decompiled the generated dtb (for the compatible dtb, I had to check which one was before I found the correct one) by Nano at /boot/dtb, and extracted its DTS. I saw this part in that DTS:
spi@7000d400 {
<snipped this part>
<snipped this part>
spi@0 {
compatible = "spidev";
reg = <0x0>;
spi-max-frequency = <0x1f78a40>;
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x7>;
};
- I figured I had to add another entry like this just below that spi@0 block, to make /dev/spidev0.1 appear:
+ spi@1 {
+ compatible = "spidev";
+ reg = <0x1>;
+ spi-max-frequency = <0x1f78a40>;
+ nvidia,enable-hw-based-cs;
+ nvidia,rx-clk-tap-delay = <0x7>;
};
-
After saving the new dts (tegra210-p3448-0000-p3449-0000-b00-user-custom-modified-spidev0-1-enabled.dtb), I re-compiled the dts into a new dtb;
-
Pasted that new dtb to both /boot/dtb (for jetson-io.py use) and /boot (for actual reference of kernel upon boot-up);
-
Changed the /boot/extlinux/extlinux.conf to let kernel refer that new dtb upon boot-up like this:
LABEL JetsonIO
MENU LABEL Custom 40-pin Header Config
LINUX /boot/Image
- FDT /boot/tegra210-p3448-0000-p3449-0000-b00-user-custom.dtb
+ FDT /boot/tegra210-p3448-0000-p3449-0000-b00-user-custom-modified-spidev0-1-enabled.dtb
INITRD /boot/initrd
APPEND ${cbootargs}
-
Did a reboot.
-
After that I rechecked my spidev, and /dev/spidev0.1 is finally added there:
nvidia@nvidia:~/$ ll /dev/*spi*
crw-rw---- 1 root gpio 153, 0 Jan 31 19:36 /dev/spidev0.0
crw-rw---- 1 root gpio 153, 1 Jan 31 19:36 /dev/spidev0.1
crw-rw---- 1 root gpio 153, 2 Jan 31 19:36 /dev/spidev1.0
I tried and my SPI was working properly, using pin 26 (CS1) and sending/writing data to /dev/spidev0.1.
My question is, are the steps I did above correct? Did I miss or misunderstood anything?
- If the steps above are NOT correct, can you please advise the correct way of doing this?
- If the steps above are correct, can I request for Nvidia to fix this in their next release (ie, make jetson-io.py automatically add spidev pin config for channel 1 too, not just channel 0)? Otherwise, us using the channel 1 will anyway still need to re-compile the dts and all, which I avoid as much as possible which was the reason why I moved from R32.2.0 to R32.3.1 (since dts/dtb stuff are like a blackhole for the most of us... I think).
I tried checking around the forums but I haven’t found a similar issue (maybe because R32.3.1 is new).
Thank you very much in advance.
Note: If I don’t do the above change, I can make my SPI work with my current setup by shorting pin 24 and pin 26, but that defeats the purpose of having 2 channels for SPI0.