Orin Nano Fast GPIO C++ Library with Direct Register Access

I have the Orin Nano developer kit with JetPack 6.0 (May 2024) and ready to use GPIO for my robot project implemented in C/C++ (to reduce feeback control system latency). I want to use GPIO with direct register access (DRA) for speed and reduced latency, so I cannot use the filesys approach. What is the official NVIDIA GPIO library for C/C++? Or which C/C++ library is recommended?

I want to make sure I use the correct library so as to not damage my developer kit, which I spent over $500. In my research, I found a few GPIO libraries, one by jwatte , one by Rubberazer, and another by pjueon. I want to emphasize, I cannot use the filesys approach. I think the latter two use the DRA approach. What does NVIDIA recommend?

Thank you.

Hi xplanescientist,

In JP6, we’ve also removed the support of controlling GPIO through sysfs.
Please use GPIO Character Device Userspace API instead and confirm you’ve configured the pinmux for GPIO usage before use.

It seems you have similar topic before( Jetson Nano Fast GPIO C++ Example with Direct Memory Access (DMA) - Jetson & Embedded Systems / Jetson Nano - NVIDIA Developer Forums). Have you tried that with the similar approach on Orin Nano with JP6?

That similar topic was for the old Jetson Nano with a very outdated Jetpack (4 years ago). I did try the GPIO library by valentis, but the usage was too low-level for me and it only partially worked. Valentis has not updated it in 5 years.

Since then I figured Nvidia would have come up with a new C/C++ GPIO library with direct register access for the Orin similar to what Arduino, Teensy and Raspberry Pi have done for high school students, college students, hobbyists, and small research firms. Together they have sold millions of units. I hope Nvidia does the same.

I did try the GPIO libary by Rubberazer. I’m happy to report it works great and is very straightforward to use. Here’s an excerpt of code that toggles a LED on pin #3 and reads the state of pin #7. It has functions to initialize the pins (by pin number not by GPIO id). When the main program loop concludes, the “gpioTerminate()” function releases the pins to their default state. GPIO functions very simple to use like Arduino and RPi.

   while (x<100) 
   {
      gpioWrite(3, 1);   // Args: pin #, state (0 or 1)
      usleep(1000);
      
      level = gpioRead(7);  // Arg: pin #
      printf("level: %d\n",level);
      
      sleep(1);
      gpioWrite(3, 0);  // Args: pin #, state (0 or 1)
      
      usleep(1000);
      
      level = gpioRead(7);  // Arg: pin #
      printf("level: %d\n",level);
      
      sleep(1);
      x++;
   }

It seems you’ve got it work through that github repository.

Do you mean that you are requesting for our official support about the DMA for GPIO?

I did further testing on toggling other pins using the GPIO library by Rubberazer. I noticed the LED lights were dimmer compared to other boards (RPi, Teensy, etc.). I checked the voltages on pins 1 and 2 of my Orin Nano Dev Kit, and they measured 3.3V and 5V respectively as expected. However, the output pins only measured 1.8V when toggled high. Why does it not output 3.3V? Does this mean the inputs are rated at 1.8V only?

Which PIN are you using?

We have 1.8V or 3.3V on Jetson, you can check the IO Block Voltage column in pinmux spreadsheet.
Or adding a level shifter to switch it from 1.8V to 3.3V.

Assuming I downloaded the correct orin nano pinmux file, all the pins broken out on the carrier board are 1.8V, except for the power pins. And the ones I tested in my C++ example are carrier pins 3, 7, 11, 15, and 19. My code toggles them on and off sequentially and it works as expected. However the LED lights are dim because of the 1.8V output.

As I work through other examples with UART, I2C, and SPI, there will be a problem interfacing with a Teensy 4.0 microcontroller, which operates at 3.3V. Will a level shifter be responsive enough to handle high speed communication? Is it better to use an optoisolator?

Hi, do you mean the pin 3, 7, 11, 15, 19 of J12 (40 pin header)? Those should be 3.3v level as there is a 1.8v-to-3.3v level shift on devkit board. If you only get 1.8v on these pins, please check if it is caused by the load of pin. Also you can refer to below doc for more detail of 40-pin header pins usage.
Jetson Nano Developer Kit 40-Pin Expansion Header GPIO Usage Considerations Applications Note

That’s correct, my pin numbers refer tp the 40 pin header on the carrier board. The only load on each of the J12 pins I mentioned (3, 7, 11, 15, & 19) is a LED and 100 ohm resistor - the output of each measures 1.8V. Pin 1 does measure 3.3V, but that is just a power pin. The carrier board is the Orin Nano Developer kit purchased at Sparkfun.com. Earlier this year I updated the QSPI uploader and I use the latest production release of JetPack 6.0 via an SD card. Somehow the level-shifter is disabled. Does it have to be enabled via a jumper? Do the earlier versions of the developer kit not include the level-shifter?

You may need to check if it is official devkit. The level shift is always there and enabled on devkit

I purchased the devkit from Sparkfun.com because the official Nvidia buy-jetson website lists Sparkfun as an authorized dealer. I took front and back photos of my devkit. You can see that pin 3 on the carrier board (J12 header) is toggled ON and measures 1.8V. Does my devkit appear to be the official Nvidia devkit?


It is official devkit. Pin 3 of J12 is I2C1_SDA which is pulled up to 3.3V. Please unconnect all external device and probe pin 3 directly. It should be 3.3v.

Right. I disconnected the leds and resistors and remeasured the voltage. Pin 3 indeed measures 3.3V, but when loaded with a LED and 100 ohm resistor, the voltage drops to 1.8V.

I tried the same experiment on my Teensy 4.0 32-bit microcontroller. The main CPU operates at 3.3V and there is no level shifter on the carrier board. When I toggle an arbitrary pin, it goes to 3.3V whether or not a load is connected.

The conclusion is that the Orin Nano Dev-Kit GPIO pins on the carrier board (J12) are indeed 3.3V. But with a small load, it will drop to 1.8V, because of the level shifter?

My plan now is to try out the UART pins and connect those to my Teensy 4.0 to establish a communication line. Hopefully the connection on the dev-kit is not considered a “load” so the 3.3V signal will be maintained?

Yes as you should be able to get from the doc Jetson Nano Developer Kit 40-Pin Expansion Header GPIO Usage Considerations Applications Note I posted before.

The document you cited is dated Feb. 2020 and pertains to the old Jetson Nano. Is there an updated version for the Orin Nano? Is there a single link where all the Orin Nano documentation and app notes reside? The main one I found is the Dev Kit User Guide link, but it’s more of a table-of-contents for other links.

I tried streaming data to my Windows PC via UART, and it worked successfully. The 1.8V voltage drop does not affect the UART communication. I connected the Dev-Kit to my windows PC with a USB to TTL Cable and data streamed without any problems over the course of 48 hours. Both UART1 (pins 8 & 10 on J12 header) and the Serial Console UART (on J14 header) worked successfully. I was even able to login to the Orin Nano from my Windows PC and run programs all from Putty.