Difference between revisions of "Jetson/TX2 SPI"
(→Enabling the New DTB) |
(→Enabling the New DTB) |
||
(8 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | This how-to enables SPI in the kernel for [[Jetson_TX2|Jetson TX2]] with L4T R28.1 (JetPack 3.1). For the previous version see, [[Jetson/TX1 SPI]]. | + | This how-to enables SPI in the kernel for [[Jetson_TX2|Jetson TX2]] with L4T R28.1 (JetPack 3.1) through R32.1 (JetPack 4.2). For the previous version see, [[Jetson/TX1 SPI]]. |
{| style="color: black; background-color: #ffffff; width: 825px;" | {| style="color: black; background-color: #ffffff; width: 825px;" | ||
Line 28: | Line 28: | ||
L4T source tarball available here: https://developer.nvidia.com/embedded/dlc/l4t-sources-28-1 | L4T source tarball available here: https://developer.nvidia.com/embedded/dlc/l4t-sources-28-1 | ||
− | JetsonHacks also has a script (https://github.com/jetsonhacks/buildJetsonTX2Kernel) | + | JetsonHacks also has a script (https://github.com/jetsonhacks/buildJetsonTX2Kernel). This script is for L4T 28.2, and will need some editing for 28.1 or earlier. |
$ git clone http://github.com/jetsonhacks/buildJetsonTX2Kernel.git | $ git clone http://github.com/jetsonhacks/buildJetsonTX2Kernel.git | ||
Line 104: | Line 104: | ||
$ cd /boot/dtb/ | $ cd /boot/dtb/ | ||
− | $ sudo dtc -I | + | $ sudo dtc -I fs -O dts -o extracted_proc.dts /proc/device-tree |
=== Update The Device-Tree === | === Update The Device-Tree === | ||
Line 129: | Line 129: | ||
'''nvidia,cs-hold-clk-count = <0x1e>; | '''nvidia,cs-hold-clk-count = <0x1e>; | ||
'''nvidia,rx-clk-tap-delay = <0x1f>; | '''nvidia,rx-clk-tap-delay = <0x1f>; | ||
− | '''nvidia,tx-clk-tap- | + | '''nvidia,tx-clk-tap-delay = <0x0>; |
'''}; | '''}; | ||
}; | }; | ||
Line 138: | Line 138: | ||
$ cd /boot/dtb/ | $ cd /boot/dtb/ | ||
− | $ sudo dtc -I dts -O dtb -o tegra186-quill-p3310-1000-c03-00-base.dtb | + | $ sudo dtc -I dts -O dtb -o tegra186-quill-p3310-1000-c03-00-base.dtb extracted_proc.dts |
=== Enabling the New DTB === | === Enabling the New DTB === | ||
− | + | The r28, r32 release must update the dtb by below command. | |
− | + | sudo ./flash.sh -r -k kernel-dtb jetson-tx2 mmcblk0p1 | |
− | As in [[Jetson/TX2 DTB]], enable '''FDT''' in <code>/boot/extlinux.conf</code> | + | Do not update the DTB by below for r28. r32 and later release. |
+ | As in [[Jetson/TX2 DTB]], enable '''FDT''' in <code>/boot/extlinux.conf</code> | ||
TIMEOUT 30 | TIMEOUT 30 | ||
Line 165: | Line 166: | ||
$ ls /dev/spi* | $ ls /dev/spi* | ||
$ /dev/spidev.3.0 | $ /dev/spidev.3.0 | ||
+ | |||
+ | == Modifying the Pinmux Configuration == | ||
+ | |||
+ | The final piece to enabling the SPI bus is to ensure the interface pins on the SoC are correctly configured to route the SPI signals. This signal routing is controlled by a feature on the SoC called the pinmux. If the pinmux is not correctly configured, the driver will load, and will be able to operate the SPI controller on the SoC, but the SPI controller will not be electrically connected to the external SPI pins. | ||
+ | |||
+ | Nvidia's L4T versions prior to R28.3 shipped with the SPI4 (SoC internal name, called SPI1 externally) signals enabled. Starting with L4T 28.3, [https://devtalk.nvidia.com/default/topic/1056610 the pinmux configuration file for some board-and-SoC configurations must be updated] to re-enable SPI4. | ||
+ | |||
+ | === Locating the Pinmux Configuration File === | ||
+ | |||
+ | The pinmux config is part of the bootloader, and is specific to the SoC model and carrier board. The board-and-SoC-specific pinmux configuration files can be found in <L4T dir>/bootloader/t186ref/BCT/tegra186-mb1-bct-pinmux-*.cfg. | ||
+ | |||
+ | === Verifying Correct Pinmux Settings === | ||
+ | |||
+ | Generally this file should not be edited in place, but rather should be generated using the SoC pinmux spreadsheet and converted to a pinmux config [[Jetson/AGX Xavier Update Pinmux|as documented here for Xavier]], but manually updating pinmux values [[Jetson/AGX Xavier Update Pinmux Manually|can be a relatively straightforward process]]. | ||
+ | |||
+ | The pinmux config file contains a sequence of register offsets and values. The correct offsets and values for enabling SPI4 are | ||
+ | |||
+ | pinmux.0x02430038 = 0x00000401; # gpio_cam4_pn3: spi4, tristate-disable, input-disable | ||
+ | pinmux.0x02430040 = 0x00000455; # gpio_cam5_pn4: spi4, pull-down, tristate-enable, input-enable | ||
+ | pinmux.0x02430048 = 0x00000401; # gpio_cam6_pn5: spi4, tristate-disable, input-disable | ||
+ | pinmux.0x02430050 = 0x00000409; # gpio_cam7_pn6: spi4, pull-up, tristate-disable, input-disable | ||
+ | |||
+ | An example of entries which would leave SPI4 disabled: | ||
+ | |||
+ | pinmux.0x02430038 = 0x00000445; # gpio_cam4_pn3: spi4, pull-down, tristate-disable, input-enable | ||
+ | pinmux.0x02430040 = 0x00000445; # gpio_cam5_pn4: spi4, pull-down, tristate-disable, input-enable | ||
+ | pinmux.0x02430048 = 0x00000445; # gpio_cam6_pn5: spi4, pull-down, tristate-disable, input-enable | ||
+ | pinmux.0x02430050 = 0x00000449; # gpio_cam7_pn6: spi4, pull-up, tristate-disable, input-enable | ||
+ | |||
+ | === Updating Pinmux Configuration on Chip === | ||
+ | |||
+ | If changes to the pinmux configuration file were required, the updated configuration needs to be written to the target in order to take effect: | ||
+ | |||
+ | $ cd <L4T_dir> | ||
+ | $ sudo ./flash.sh jetson-tx2 mmcblk0p1 | ||
+ | |||
+ | == Testing Communication == | ||
+ | |||
+ | The easiest way to verify SPI communication is to: | ||
+ | * use a jumper to connect pins 19 and 21 (MOSI and MISO) of the J21 connector block | ||
+ | * in a copy of the kernel sources, change directories to tools/spi/ | ||
+ | * run <code>CROSS_COMPILE=<path to aarch64 cross tools> make</code> | ||
+ | ** this requires an aarch64 (arm64) compatible gcc to be installed | ||
+ | ** Ex: <code>sudo apt install gcc-aarch64-linux-gnu; CROSS_COMPILE=/usr/bin/aarch64-linux-gnu- make</code> | ||
+ | * copy the resulting spidev_test binary to the target system | ||
+ | * Run <code>spidev_test -D /dev/spidev3.0</code> | ||
+ | |||
+ | The program will send a test pattern out on MOSI, and because MOSI and MISO were jumpered together, will read it back in on MISO, and should display a non-zero sequence of received data. If only zeroes are reported, verify that pins 19 and 21 are correctly jumpered together, and that the pinmux configuration is correct for enabling the SPI interface. | ||
+ | |||
+ | The spidev_test program can also be used to test communication with a slave device, by using command line arguments to change protocol settings, specify the data to send, etc. |
Revision as of 20:49, 13 August 2019
This how-to enables SPI in the kernel for Jetson TX2 with L4T R28.1 (JetPack 3.1) through R32.1 (JetPack 4.2). For the previous version see, Jetson/TX1 SPI.
DevTalk Thread — see https://devtalk.nvidia.com/default/topic/1024806/how-to-enable-spi-spidev-on-28-1-on-target-/ |
Contents
Locating the SPI Pins
First, in the Jetson TX2 Developer Kit, the SPI pins are located on the J21 header - http://www.jetsonhacks.com/nvidia-jetson-tx2-j21-header-pinout/
- Pin 19 - SPI(3) MOSI
- Pin 21 - SPI(3) MISO
- Pin 23 - SPI(3) CLK
- Pin 24 - SPI(3) CS#0
Building SPIDev Module
It's suggested to enable support for SPIDev (userspace API).
To do that, we'll download the L4T kernel sources, enable SPIDev module in the kernel configuration, build and install the module.
Downloading the Kernel Sources
L4T source tarball available here: https://developer.nvidia.com/embedded/dlc/l4t-sources-28-1
JetsonHacks also has a script (https://github.com/jetsonhacks/buildJetsonTX2Kernel). This script is for L4T 28.2, and will need some editing for 28.1 or earlier.
$ git clone http://github.com/jetsonhacks/buildJetsonTX2Kernel.git $ cd buildJetsonTX2Kernel $ ./getKernelSources.sh
The JetsonHacks script should have downloaded the kernel sources to the /usr/src/ folder.
Configuring the Kernel
Edit the tegra18_defconfig
file:
$ cd /usr/src $ cd /kernel/kernel-4.4/ $ cd /arch/arm64/configs/ $ sudo gedit tegra18_defconfig
Add the following to just below CONFIG_SPI_TEGRA114_SPI=y
CONFIG_SPI=y CONFIG_SPI_TEGRA114=y CONFIG_SPI_SPIDEV=m CONFIG_QSPI_TEGRA186=y
Building the Kernel
Generate the new .conf
file after the changes to tegra18_defconfig
$ cd /usr/src/kernel/kernel-4.4 $ sudo make tegra18_defconfig
Build the kernel modules:
$ cd ~/buildJetsonTX2Kernel $ sudo ./makeKernel.sh
Ensure the SPIDev Kernel module is copied to /lib/modules
$ sudo cp /usr/src/kernel/kernel-4.4/drivers/spi/spidev.ko /lib/modules/$(uname -r)/kernel/drivers/
Update module dependencies and kernel image:
$ sudo depmod $ sudo ./copyImage.sh
Reboot to new config:
$ sudo reboot
Verifying SPIDev Module
To verify the SPIDev kernel module that we built is enabled, navigate to /lib/modules/$(uname -r)
$ cd /lib/modules/$(uname -r) $ cat modules.dep # print the contents of modules.dep to the screen, and ensure spidev.ko is in there # e.g. @line 23 # kernel/drivers/spi/spidev.ko
Modifying the Device Tree
Next, we must enable the SPI device in the Jetson's device tree.
To do this, we'll install the device tree compiler (DTC), modify the device tree source (DTS), and re-build the device tree binary (DTB).
Installing DTC Tool
First we need the device-tree-compiler
$ sudo apt-get update $ sudo apt-get install device-tree-compiler
Decompiling Device Tree
To obtain the device tree source (DTS) that we'll edit, first we need to decompile the current device tree binary (DTB) back to source:
$ cd /boot/dtb/ $ sudo dtc -I fs -O dts -o extracted_proc.dts /proc/device-tree
Update The Device-Tree
Use your text editor of choice to update the DTS that we decompiled above:
$ sudo gedit myTX2DeviceTreeSource.dts
Make the following patches:
spi@3240000{ compatible = "nvidia,tegra186-spi"; reg = <0x0 0x3240000 0x0 0x10000>; .... .... .... linux,phandle = <0x80>; spi@0 { compatible = "spidev"; reg = <0x0>; spi-max-frequency = <0x1312D00>; nvidia,enable-hw-based-cs; nvidia,cs-setup-clk-count = <0x1e>; nvidia,cs-hold-clk-count = <0x1e>; nvidia,rx-clk-tap-delay = <0x1f>; nvidia,tx-clk-tap-delay = <0x0>; }; };
Recompiling the Device Tree
Use DTC again to recompile the modifying DTS back into the new DTB:
$ cd /boot/dtb/ $ sudo dtc -I dts -O dtb -o tegra186-quill-p3310-1000-c03-00-base.dtb extracted_proc.dts
Enabling the New DTB
The r28, r32 release must update the dtb by below command.
sudo ./flash.sh -r -k kernel-dtb jetson-tx2 mmcblk0p1
Do not update the DTB by below for r28. r32 and later release.
As in Jetson/TX2 DTB, enable FDT in /boot/extlinux.conf
TIMEOUT 30 DEFAULT PRIMARY MENU TITLE p2771-0000 eMMC boot options LABEL primary MENU LABEL primary kernel LINUX /boot/Image FDT /boot/dtb/tegra186-quill-p3310-1000-c03-00-base.dtb APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4
Reboot for the changes to take effect:
$ sudo reboot
Verifying SPIDev Device
To confirm the SPIDev module has loaded and created the SPI device, check if SPIdev is available in your /dev
folder:
$ ls /dev/spi* $ /dev/spidev.3.0
Modifying the Pinmux Configuration
The final piece to enabling the SPI bus is to ensure the interface pins on the SoC are correctly configured to route the SPI signals. This signal routing is controlled by a feature on the SoC called the pinmux. If the pinmux is not correctly configured, the driver will load, and will be able to operate the SPI controller on the SoC, but the SPI controller will not be electrically connected to the external SPI pins.
Nvidia's L4T versions prior to R28.3 shipped with the SPI4 (SoC internal name, called SPI1 externally) signals enabled. Starting with L4T 28.3, the pinmux configuration file for some board-and-SoC configurations must be updated to re-enable SPI4.
Locating the Pinmux Configuration File
The pinmux config is part of the bootloader, and is specific to the SoC model and carrier board. The board-and-SoC-specific pinmux configuration files can be found in <L4T dir>/bootloader/t186ref/BCT/tegra186-mb1-bct-pinmux-*.cfg.
Verifying Correct Pinmux Settings
Generally this file should not be edited in place, but rather should be generated using the SoC pinmux spreadsheet and converted to a pinmux config as documented here for Xavier, but manually updating pinmux values can be a relatively straightforward process.
The pinmux config file contains a sequence of register offsets and values. The correct offsets and values for enabling SPI4 are
pinmux.0x02430038 = 0x00000401; # gpio_cam4_pn3: spi4, tristate-disable, input-disable pinmux.0x02430040 = 0x00000455; # gpio_cam5_pn4: spi4, pull-down, tristate-enable, input-enable pinmux.0x02430048 = 0x00000401; # gpio_cam6_pn5: spi4, tristate-disable, input-disable pinmux.0x02430050 = 0x00000409; # gpio_cam7_pn6: spi4, pull-up, tristate-disable, input-disable
An example of entries which would leave SPI4 disabled:
pinmux.0x02430038 = 0x00000445; # gpio_cam4_pn3: spi4, pull-down, tristate-disable, input-enable pinmux.0x02430040 = 0x00000445; # gpio_cam5_pn4: spi4, pull-down, tristate-disable, input-enable pinmux.0x02430048 = 0x00000445; # gpio_cam6_pn5: spi4, pull-down, tristate-disable, input-enable pinmux.0x02430050 = 0x00000449; # gpio_cam7_pn6: spi4, pull-up, tristate-disable, input-enable
Updating Pinmux Configuration on Chip
If changes to the pinmux configuration file were required, the updated configuration needs to be written to the target in order to take effect:
$ cd <L4T_dir> $ sudo ./flash.sh jetson-tx2 mmcblk0p1
Testing Communication
The easiest way to verify SPI communication is to:
- use a jumper to connect pins 19 and 21 (MOSI and MISO) of the J21 connector block
- in a copy of the kernel sources, change directories to tools/spi/
- run
CROSS_COMPILE=<path to aarch64 cross tools> make
- this requires an aarch64 (arm64) compatible gcc to be installed
- Ex:
sudo apt install gcc-aarch64-linux-gnu; CROSS_COMPILE=/usr/bin/aarch64-linux-gnu- make
- copy the resulting spidev_test binary to the target system
- Run
spidev_test -D /dev/spidev3.0
The program will send a test pattern out on MOSI, and because MOSI and MISO were jumpered together, will read it back in on MISO, and should display a non-zero sequence of received data. If only zeroes are reported, verify that pins 19 and 21 are correctly jumpered together, and that the pinmux configuration is correct for enabling the SPI interface.
The spidev_test program can also be used to test communication with a slave device, by using command line arguments to change protocol settings, specify the data to send, etc.