SPI configuration for TX2

I looked at the details posted on https://devtalk.nvidia.com/default/topic/978809/full-procedure-for-enabling-spi-on-the-tx1-/?offset=14#5201578 but this is for TX1, Is this same for TX2 as well?

I also have same problem. Does anyone have idea???

It’s not the same, I’m away from my development computer at the moment (holidays) but I will try assist from memory.

Apologies if you know some of this stuff already but I think I’m covering some of the main points.

This is for using SPI on the TX2 running 28.1 through the J21 headers:

Where’s the J21 headers? (http://www.jetsonhacks.com/nvidia-jetson-tx2-j21-header-pinout/) - shoutout to JetsonHacks, fantastic resource for noobs.

  1. SPI MOSI (19)
  2. SPI MISO (21)
  3. SPI CLK (23)
  4. SPI CS (24)

Assuming you’re using SPIDev (at the very least to try the loopback) ensure it’s used when building your kernel (http://elinux.org/Jetson/TX1_SPI#Installing_SPIdev_Kernel_Module)

Device tree
First off, being able to modify the device tree is required. All resources online are generally for the TX1 before 28.1 and there’s some differences.
The device tree entry for SPI on the J21 header is entry: ‘spi@3240000
In this guide that you’ve probably come across (http://elinux.org/Jetson/TX1_SPI#Enabling_SPIdev_in_the_Device_Tree) this is where you make the entry to use SPIDEV.

Previously on the TX1 a change had to be made for GPIO to use SPI (http://elinux.org/Jetson/TX1_SPI#Configuring_GPIO_Pinmux_for_SPI) - This is not required for the TX2.

SPI Master or SPI Slave?
SPI Master works fine, SPI Slave kinda works… but I’ve had a lot of trouble with it.

Question, how do you build your kernel and Device Tree Binaries (DTB), do you do it on the target (actual Jetson TX2) or on a host machine?

I’ll try answer what I can

I have a TX2 board and I am trying to enable the SPI as you have described.

I followed the procedure you mentioned. However, I am confused to which dtb file did you modify and update? As far as I know, there is no particular dtb loaded as per extconf.conf file.

As you have mentioned there are not many resources for R28.1, the only documentation I could find was http://elinux.org/Jetson/TX2_DTB , but I do not understand what/where does Jetpack/3.1… does/exist? Is it like a command or do you have to install jetpack 3.1 and access the dtb through the folders?

Request you to help/share your experience.

Thanks in advance.

Hi, Sagar7sharma.

First off, do you have the kernel sources? If not, you will need them to build the kernel to include SPI.

However, I am confused to which dtb file did you modify and update?
Assuming you have the kernel sources, I’ve modified this dts file (hardware/nvidia/soc/t18x/kernel-dts/tegra186-soc/tegra186-soc-base.dtsi) - On reflection, this file is not best practice to edit or change, but at the very least it will let you include spidev on the tegra186-spi for the SPI pins available on the J21 headers.

(dts = device tree source, dtb = device tree blob/binary)

spi3: spi@3240000 {
		compatible = "nvidia,tegra186-spi";
		reg = <0x0 0x03240000 0x0 0x10000>;
		interrupts = <0 39 0x04>;
		nvidia,dma-request-selector = <&gpcdma 18>;
		#address-cells = <1>;
		#size-cells = <0>;
		#stream-id-cells = <1>;
		dmas = <&gpcdma 18>, <&gpcdma 18>;
		dma-names = "rx", "tx";
		nvidia,clk-parents = "pll_p", "clk_m";
		clocks = <&tegra_car TEGRA186_CLK_SPI4>,
			<&tegra_car TEGRA186_CLK_PLLP_OUT0>,
			<&tegra_car TEGRA186_CLK_CLK_M>;
		clock-names = "spi", "pll_p", "clk_m";
		resets = <&tegra_car TEGRA186_RESET_SPI4>;
		reset-names = "spi";
		status = "disabled";
	spi@0 {
			compatible = "spidev";
			reg = <0x0>;
			spi-max-frequency = <0x1312D00>;
			nvidia,cs-setup-clk-count = <0x1e>;
			nvidia,cs-hold-clk-count = <0x1e>;
			nvidia,rx-clk-tap-delay = <0x1f>;
			nvidia,tx-clk-tap-delay = <0x0>;		

Hi David,

Yes, I have the kernel sources which I downloaded and extracted earlier (l4T sources R28.1).

I was able to install the SPIdev kernel module as you earlier mentioned in this post, but did not really see it under ‘lsmod’.

On the other hand, regarding dts file (hardware/nvidia/soc/t18x/kernel-dts/tegra186-soc/tegra186-soc-base.dtsi), I am away from the development board as of now. I will check that up soon.

I was under the impression that I need to convert the existing dtb to dts using the dtc, edit it and recompile it to dtb. Am I right? or would it work if I just editted the tegra186-soc…base.dtsi and rebooted the system.

Sorry, I am relatively new to this. Thanks again.

OK, you have the sources, great!

Can you confirm the .ko file for SpiDev is being built? i.e. your build process is producing the kernel module SpiDev.

The DTS file (source) I mentioned above (hardware/nvidia/soc/t18x/kernel-dts/tegra186-soc/tegra186-soc-base.dtsi) can be modified to include SpiDev (line 19-28 are the important bits), to build your kernel you should be doing the following commands from (kernel_source):

sudo make O=$OUTPUT_FOLDER zImage 
sudo make O=$OUTPUT_FOLDER prepare
sudo make O=$OUTPUT_FOLDER modules_prepare
sudo make O=$OUTPUT_FOLDER modules 

Regarding building the Device Tree, what I suggested above is all you should need to get you up and running.

Are you building your kernel on a host machine (separate machine) or a target machine (Jetson TX2)?

Yes! I followed the procedure as listed here (http://elinux.org/Jetson/TX1_SPI#Installing_SPIdev_Kernel_Module) and was able get a SPIdev.ko file.

However, following that I got confused for where to locate the existing dtb as the extconf.conf no longer has the FDT entry and the procedure following the same link makes changes existing dtb.

And yes, I am building the kernel on the target machine[Jetson TX2]. I hope to run the machine as a Slave but need to verify the same.

I will try what you suggested soon and get back. Thanks.

OK, the FDT entry is no longer on 28.1
So… On the Jetson, navigate to /boot/dtb/ - there should be a file there tegra186-quill-p3310-1000-c03-00-base.dtb de-compile that (http://elinux.org/Jetson/TX1_SPI#Extracting_DTB_to_Source):

$ cd /boot/dtb
$ dtc -I dtb -O dts -o tegra186-quill-p3310-1000-c03-00-base.dts tegra186-quill-p3310-1000-c03-00-base.dtb

Patch it with the device tree patch (comment #5)

compile it(http://elinux.org/Jetson/TX1_SPI#Recompiling_the_New_DTB):

$ cd /boot/dtb
$ dtc -I dts -O dtb -o tegra186-quill-p3310-1000-c03-00-base.dtb tegra186-quill-p3310-1000-c03-00-base.dts

Obligatory this is not best practice to modify a device tree mention , ideally you should be doing it all from source on a host/development machine to flash onto target.

Hello David,

Thanks for the help.

I could compile the dts to dtb as you stated.

I am able to build the kernel (spidev.ko) but I don’t see spidev0.0 under my device node.

I have read few posts stating I have to manually create the spidev0.0 using mknod but I do not know if this is the right thing to do.

"I am able to build the kernel (spidev.ko) but I don’t see spidev0.0 under my device node. "

Do you see ‘spidev3.0’ (or similar) when you run the following?

$ ls /dev

If not, check your modules.dep file to see if spidev is in there:

$ cd /lib/modules/$(uname-r)
$ cat modules.dep

When you’re building spidev.ko do you know where it is being put? It should be in (kernel_src)/drivers/spi/spidev.ko but it *should* be copied to /lib/modules/(uname -r) as one of the last stages of the build process. This is where (I believe) it gets put into your ‘modules.dep’ file as mentioned above.

I do not see spidev under

$ ls /dev

I see the spidev at modules.dep in file

cat modules.dep

When I grep it with spidev I get the follow : kernel/drivers/spidev.ko

How do I go about forward with this?

Ok, then what I think is happening is that your device tree is not set up correctly, can you do an insmod on spidev to make it appear in /dev/?

$ cd /lib/module/($uname -r) 
$ sudo insmod spidev

As per this http://elinux.org/Jetson/TX1_SPI#Recompiling_the_New_DTB, one of the last stages include

sudo cp drivers/spi/spidev.ko /lib/modules/$(uname -r)/kernel/drivers

So my spidev.ko file exist on

/lib/modules/$(uname -r)/kernel/drivers

When I do sudo insmod from

/lib/module/($uname -r)

it says

insmod: ERROR: could not <b>load</b> module spidev: No such file or directory

When I do sudo insmod from

/lib/modules/$(uname -r)/kernel/drivers

it says

insmod: ERROR: could not <b>insert</b> module spidev: file exists

insmod: ERROR: could not insert module spidev: file exists
I would only expect to see that error when a module has been inserted
Try removing it and re-inserting it

$ cd /lib/modules/$(uname -r)/kernel/drivers 
$ sudo rmmod spidev
$ ls /dev/
$ sudo insmod spidev

What’s the output when you do ‘$ rmmod spidev’ ?

sudo rmmod spidev

It successfully removed the spidev.

ls /dev/

No spi entries.

When I do

sudo insmod spidev
insmod: ERROR: could not load module spidev: No such file or director

When I copy the spidev.ko back to

sudo cp $kernel_src/drivers/spi/spidev.ko /lib/modules/$(uname -r)/kernel/drivers


sudo shutdown -r now
modprobe spidev
ls /dev/spi*
ls:cannot access '/dev/spi*': no such file or directory

I’m a little unsure what’s actually happening, if it helps, I’ve never had to do a ‘modprobe’ spidev after bootup.

hi frends, I need expert help, lol
I need to connect an oled screen to tx2 spi !

need :
GND (G) ok!
VIN (+) ok!
SCLK (CL) ok!
MOSI (SI) ok!

well, R (reset) is optional,

but need DC (SPI data/command) !!!

Cant find connection on tx2 J21

Help !

Thanks friends.

see response here: https://devtalk.nvidia.com/default/topic/1024806/jetson-tx2/how-to-enable-spi-spidev-on-28-1-on-target-/?offset=7#5214450

TX2 SPI configuration details available here: https://elinux.org/Jetson/TX2_SPI

NOTE: Posting for completion of this thread.