So, I’ve spent the last week trying to piece together information on getting SPI to work on the Nano DeveloperKit and finally got it working yesterday. To save others some pain, I’ve documented the steps and created both patch and binary files. This only applies to the tegra210-p3448-0000-p3449-0000-a02 but I’m sure it can be adapted to other boards.
Just FYI… My first mistake was using the pinmux “helper” spreadsheets. Not only do you have to use a real Excel to get the macros to work, they produce files that cause the Nano to not boot. In my case, even though I only modified the spi1 pins, the resulting dtsi files had qspi and sdmmc1 disabled which prevents the device from booting.
So I went back to my previous experience with creating/modifying device trees for other boards and started from scratch. Once you know where all the pieces are, it’s actually not that hard. Here’s the result:
At the end of this, you should have:
/dev/spidev0.0
/dev/spidev0.1
/dev/spidev1.0
/dev/spidev1.1
and they should be routed to the appropriate pins on the 40-pin expansion connector.
What I don’t understand is why NVIDIA doesn’t just configure all the functions for the GPIO header as default. When opening/exporting a GPIO pin, it’s really easy for the device driver to override that pin to be a GPIO function, even if it’s by default configured for a peripheral, and then when closing the GPIO pin, the driver can undo the GPIO override.
Yeah I’m not sure either. It wouldn’t be too bad if you could just let u-boot load the dtb from /boot and pass it to the kernel as other platforms do but the whole TegraBoot → cboot → u-boot 12 partition thing just makes the process overly complex.
@gtj, so I tried your approach and wanted to enable spi1/spidev0.0 but I ended up with both enabled and not working anyway:
root@jetson:/home/jetson# sudo cat /sys/kernel/debug/tegra_gpio
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
A: 0:0 64 40 40 24 00 00 000000
B: 0:1 80 80 80 00 00 00 000000
C: 0:2 18 18 18 00 00 00 000000
root@jetson:/home/jetson# ls /dev/spi*
/dev/spidev0.0 /dev/spidev0.1
root@jetson:/home/jetson/Work/spi# ./spidev_test -D /dev/spidev0.0
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
root@jetson:/home/jetson/Work/spi#
root@jetson:/home/jetson/Work/spi# ./spidev_test -D /dev/spidev0.1
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
root@jetson:/home/jetson/Work/spi#
I’ve created an SD card image based on Tegra_Linux_Sample-Root-Filesystem_R32.2.1_aarch64.tbz2
that has spidev0.0 and spidev0.1 enabled. It also has the Tegra XUSB driver included in the kernel which should allow using a USB drive as the root filesystem.
Please test before using in production!
EDIT: Oops, there was an issue with that build. I’ve removed it for now.
thanks for your time on this.
and excuse my ignorance: are spidev0.0 and spidev0.1 both related to the SPI0 signals on the expander?
I’d like to avoid use of the SPI1 signals for now.
where can I find the ‘gpioinfo’ tool?
on spidev_test, I was using the code from the kernel, not the one from rpi fork, that’s why I couldn’t see the actual transfer. using verbose (-v) was showing it was working.
Both spi controllers are configured BUT only spi0 has spidev attached to it. So that’s spidev0.0 and spidev0.1. The pins assigned to spi1 should be free for other uses unless you attach a device driver to it.
The “gpiod” package has the gpio tools in it.
The spi bus on my Nano communicates with a 3D printer controller board. The controller board handles all the motion control stuff and the Nano handles all the admin stuff.
cool! thanks for the image and tool.
the tool is definitely good to have as a quick approach to enable spi straight from the nano itself.
any chance it could be combined with this https://github.com/rt-net/JetsonNano_DT_SPI/ to build everything needed (the 4 images) on the nano itself or is cross-compiling the only option?
That’s a good question. I’d need to pick apart the things in L4T that would be required to build the images. That would include the kernel but at least you don’t have to actually compile the kernel, just the dtbs. I can give it a try.
Yep. Just for SPI, you don’t have to build the kernel or modules themselves (thankfully), just the DTBs which takes only a few seconds. Building the kernel and modules on the Nano is a pretty serious time investment. :)
The L4T package has everything needed to create the signed images but there’s no out of the box way to flash them directly to the running sdcard. It’s easy enough using ‘dd’ though. Just have to create a script to do it.
I have some bad news regarding the image. it seems it is incomplete as I get errors while trying to build the inference engine from https://github.com/dusty-nv/jetson-inference
upon cmake, I get these:
CUDA_TOOLKIT_ROOT_DIR not found or specified
– Could NOT find CUDA (missing: CUDA_TOOLKIT_ROOT_DIR CUDA_NVCC_EXECUTABLE CUDA_INCLUDE_DIRS CUDA_CUDART_LIBRARY)
[…]
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
CUDA_CUDART_LIBRARY (ADVANCED)
[…]
CUDA_TOOLKIT_INCLUDE (ADVANCED)
it might have something to do with missing repo: file:/var/cuda-repo-10-0-local-10.0.326 as I was seeing a Not Found on ‘apt update’.
I don’t get these errors with the original image.
anyway, I’d say leave this for now since it is possible to dd the images to enable SPI.
thanks and cheers