Remember when you had to jump through all sorts of hoops to get your NVIDIA Jetson NVIDIA Kit to be able to understand Serial Protocol Interface (SPI) devices? Those days be gone. Looky here:
Background
The introduction of JetPack 4.3 brings with it a new tool, Jetson-IO. All of the Jetson developer kits include a 40-pin GPIO expansion header. Many of the pins can be used either as General Purpose I/O (GPIO) or Special Function I/O (SFIO). SFIO are functions such as I2C, I2S, SPI, and so on.
The default configuration of the pins is defined and programmed into the Jetson when flashed. Previously you had to go through a, let’s call it less than straightforward, process to reconfigure the pins to your needs.
The new Jetson-IO tool is here to help! While the previous process is useful for system designers, the majority of developers many times just look to modify the pins to the NVIDIA recommended special functions.
For example, if we look at a typical Jetson GPIO Expansion Header (such as this one for the Jetson Nano), we see that there are several pins that list as SPI_1, but we know that in the default configuration they are GPIO.
This is similar to other Linux embedded systems such as the Raspberry Pi. The RPi has a similar utility, raspi-config, to help with configuring pins on that device.
The default configuration sets most of the pins to GPIO. Here’s how to run Jetson-IO to change that.
Jetson-IO
The Jetson-IO utility is just a youngster, and in its initial release on the Jetson in JetPack 4.3 (L4T 32.3.1) there are some issues. These issues are noted in the documentation. The following two issues have been addressed in later releases.
The first issue involves initialization of some of the code. To fix it:
$ sudo find /opt/nvidia/jetson-io/ -mindepth 1 -maxdepth 1 -type d -exec touch {}/__init__.py \;
The second issue occurs only on the Jetson Nano. On the Jetson Nano, one of the directories needs to be set up:
$ sudo mkdir /boot/dtb
$ sudo cp -v /boot/tegra210-p3448-0000-p3449-0000-[ab]0[02].dtb /boot/dtb/
Then there’s a niggle to which you should be aware. If the Terminal window that you are working in is too small, then the menus have difficulty displaying. Make sure that your Terminal window is large, so it can hold the menus.
Running Jetson-IO
After the setup, we’re ready to go:
$ sudo /opt/nvidia/jetson-io/jetson-io.py
Which will bring us to the main screen:
We select Configure 40-pin expansion header:
In our case we select SPI1 (pins 19,21,23,24,26). Use the arrow keys to navigate to the desired entry, Return selects/deselects the entry. Select Back when done. You should see the new configuration on the main menu. Save and reboot to reconfigure pins. You will go through the familiar Confirm/’Deny everything you have ever done’ prompts, then the system will reboot. After that, SPI goodness is available.
Of course, the Jetson-IO utility has much more functionality than this simple example. Look through the documentation to see what you can do to amaze your friends and confuse your enemies!
SPI Display Example
In the video, we connect to a Adafruit 1.8″ TFT Display to a Jetson Nano. The display is also available through Digikey and Adafruit. There is an excellent tutorial on the Adafruit site about the Display and how to use it. We won’t go over this too much more here.
After soldering the headers onto the display, we wire the display:
Jetson Nano | Adafruit 1.8″ TFT Display |
Pin 6 GND | Pin 1 GND |
Pin 1 3.3V | Pin 2 VCC |
Pin 18 gpio15 | Pin 3 Reset |
Pin 22 gpio13 | Pin 4 D/C |
Not Connected | Pin 5 CARD_CS |
Pin 24 SPI_1_CS0 | Pin 6 TFT_CS |
Pin 19 SPI_1_MOSI | Pin 7 MOSI |
Pin 23 SPI_1_SCK | Pin 8 SCK |
Not Connected | Pin 9 MISO |
Pin 17 3.3V | Pin 10 LITE |
Note that while SPI is only 4 signals (6 if you count power and ground), this device has a couple of more in use. One of the extra connections provides power to the backlight of the display.
There are a couple of examples for this particular display on the JetsonHacksNano account on Github in the repository SPI-Playground. Clone the repository, and switch over that that repositories example directory:
$ git clone https://github.com/JetsonHacksNano/SPI-Playground
$ cd SPI-Playground/examples
There you will find instructions on how to install the prerequisites in the README.md file:
$ sudo apt-get install python3-pip
$ pip3 install adafruit-blinka
$ pip3 install adafruit-circuitpython-busdevice
$ pip3 install adafruit-circuitpython-rgb-display
$ sudo apt-get install python3-pil
Examples
There are two examples here.
Example 1 will display a shark on the screen.
$ python3 rgb_display_pillow_image.py
The second example shows some of the Jetson stats on the display:
$ python3 rgb_display_pillow_stats.py
All in all, pretty straightforward. At least compared to the old days!
Notes:
- Example shown: JetPack 4.3/L4T 32.3.1
- Jetson Nano
20 Responses
very good!
Thank you for the kind words, and thanks for reading!
where is the DTBrowse?
It’s a program I wrote, it is not available.
I know it,thank you.
can you share DTBrowse tool,i am fish man ,it is hard reading device tree for me.if you wish to share it ,email to zsjalive@126.com. thanks so much.
Hi there,
Thank you so much for this helpful tutorial.
I have a question regarding the second step. After I reconfigure the GPIO header to SPI1, I save and reboot. Then when I check again the header, I find that the pins went back to their original state “unused”.
Is that normal? and if it’s not, do you know what could be the reason?
Thank you for your help
That is not normal. I have not encountered that issue. Please ask this question on the official NVIDIA Jetson Nano forum, where a large group of developers and NVIDIA engineers share their experience. The forum: https://forums.developer.nvidia.com/c/agx-autonomous-machines/jetson-embedded-systems/jetson-nano/76
Hi.
Thank you so much for this tutorial.
I always refer to this site.
After I reconfigure the GPIO header to SPI1, I save and reboot.
Refer to the following URL, I used the spidev_test.c to test the self loop when connect MOSI(19) and MISO(21).
But, it displayed only zeros.(output : RX | 00 00 00 00 00 …)
When I check again the header, I confirmed that SPI is enabled.
I confirmed that the output of `ls /dev/spidev*` is `/dev/spidev0.0`.
Do you get similar results? and if you don’t, do you know what could be the reason?
URL -> https://elinux.org/Jetson/TX2_SPI#Testing_Communication
spidev_test.c -> https://github.com/rm-hull/spidev-test/blob/master/spidev_test.c
HW : Jetson AGX Xavier
L4T/JetPack : Jetpack4.3
Hi,
In the version R32.4.2, I can config the SPI0 and run successfully in the Kit whith the SD module of B01, But when I replace to eMMC module of B01. The Jetson-IO can not run. So how to config SPI0 in the eMMC module of B01
Hi,
I would like use the SPI display like a main display, in other words, show the interfaz l4t of Jetson and run codes. Is it possible?
I suppose you could. You will need to write a program to do that.
dear jetsonhacks i am using jetpack 4.6 and I do those steps but when I run jetson-io flashing window and closing.
how can i fix
hello,
I am using jetpack 4.6
when i execute “python3 rgb_display_pillow_image.py” i get the blow error.
Traceback (most recent call last):
File “rgb_display_pillow_image.py”, line 20, in
spi = board.SPI()
File “/home/evren/.local/lib/python3.7/site-packages/board.py”, line 311, in SPI
return busio.SPI(SCLK, MOSI, MISO)
File “/home/evren/.local/lib/python3.7/site-packages/busio.py”, line 286, in __init__
self._spi = _SPI(portId)
File “/home/evren/.local/lib/python3.7/site-packages/adafruit_blinka/microcontroller/generic_linux/spi.py”, line 22, in __init__
self._spi = spi.SPI(device=(portid, 0))
File “/home/evren/.local/lib/python3.7/site-packages/Adafruit_PureIO/spi.py”, line 167, in __init__
raise IOError(“{} does not exist”.format(device))
OSError: /dev/spidev0.0 does not exist
Exiting…
Cleaning up pins
It says that SPI is not available. Which Jetson are you using?
4.6-b199
I meant which Jetson, (Nano, Nano 2GB, Xavier NX … ) Is it a module or developer kit?
Jetson Nano 4GB developer kit
Jetson Nano 4GB developer kit
Does jetson-io show that the SPI signals are set? I’m beginning to think that there might be an issue with JetPack 4.6 and that package and the way that they handle the device tree overlay.