C/C++ GPIO issue

Hello,

I have a standard Jetson Nano board (with the 40-way header).
I’m trying to use that 40-pin GPIO using C/C++, by directly programming the GPIO registers (rather than using /sys/class/gpio) because I need it to be fast.

My code is here: GitHub - shabaz123/tx1_gpio and can be built using:
mkdir build
cd build
cmake …
make

My code uses mmap to create memory access to all the GPIO registers in a single block, and then accepts a GPIO name string (such as GPIO3_PJ.07 which is pin 12 on the 40-pin connector) and builds a list of registers for it (stored in a typedef structure called regset).
Then, it directly programs the registers via the memory mapped region.
However, it doesn’t work : (

This is the output (code is run as superuser):

./gpio_tx1
GPIO registers mapped to 0x7f836e0000
gpio_name=GPIO3_PJ.07, controller_num[1…8]=3, port_num[0…3]=1
controller_num[1…8]=3
port_num[0…3]=1
pin[0…7]=7
gpio_cnf_addr=0x6000d204
gpio_msk_cnf_addr=0x6000d284
gpio_oe_addr=0x6000d214
gpio_msk_oe_addr=0x6000d294
gpio_out_addr=0x6000d224
gpio_msk_out_addr=0x6000d2a4
gpio_in_addr=0x6000d234
portJ: CNF=0080, MSK_CNF=9090, OE=0000, MSK_OE=0000, OUT=0000, MSK_OUT=0000, IN=0000
setting GPIO to output mode…
writing 0x8080 to gpio_msk_cnf_addr 0x6000d284
writing 0x8080 to gpio_msk_oe_addr 0x6000d294
setting GPIO to a 1…
writing 0x8080 to gpio_msk_out_addr 0x6000d2a4
portJ: CNF=0080, MSK_CNF=9090, OE=0000, MSK_OE=0000, OUT=0000, MSK_OUT=0000, IN=0000
done

As can be seen, I think it does correctly calculate the register addresses corresponding to the correct port, and it seems to set the correct values (in my opinion), but the read values clearly show that the MSK_OE and MSK_OUT do not get set.

What’s going on? Any help would be appreciated.
I have searched and all help seems to point to the following location:

which points to this code:

However, that code doesn’t compile (it gives an error because GPIO_12 is not defined). When I define that (I used this code:

define GPIO_12 0x6000d004

then, the LED code there runs, but certainly does not produce any output on the gpio12 output (pin 37). I know this because I am using a very low current LED and resistor, and I can only see the LED lit if I use echo sys/class/gpio commands from the shell. So, I know that electrically the LED will light, but it certainly does not using that example code, nor my code.

Hi shabaz,

Are you using the devkit or custom board for Jetson Nano?
What’s your Jetpack version in use?

Have you tried to use Jetson-GPIO to control GPIO?

Hi Kevin,
Thanks for the response.
It is the standard devkit, not a custom board. I’m using # R32 (release), REVISION: 6.1, GCID: 27863751, BOARD: t210ref, EABI: aarch64, DATE: Mon Jul 26 19:20:30 UTC 2021 however that should not make a difference to the direct register access, since those are chip-level, not OS or driver level.
I don’t wish to use Jetson-GPIO, because it will be far slower than direct register access. I have confirmed using echo sys/class/gpio commands from the Linux shell, that the electrical connection to the GPIO is fine, because I can make the LED light up that way. But that’s not the way I want to do it. I cannot make it light up using direct register access. Is the register content that I am writing correct?

Could you update to the latest R32.7.4 to verify?

Please share the detailed steps how you reproduce the issue on the devkit. (including the code you run and every commands)

Hi,

Here are the complete steps:
From the Linux command prompt, type:

git clone https://github.com/shabaz123/tx1_gpio.git
cd tx1_gpio
mkdir build
cd build
cmake ..
make

Then as super-user, type:

./gpio_tx1

You’ll see output showing what registers were programmed. However if you check pin 12 of the 40-pin connector, you’ll see that the output did not go high.

Hi Kevin,

I think we can close this issue, because, although that code still doesn’t work, I decided not to trust any online example code, and created some new code from scratch (which I will upload onto GitHub once it is tidied up a bit). Now the code works, although there are still some issues, but I will raise them in a new post if/when required.
Just for information, I measured the output GPIO speed, and the oscilloscope screenshot below shows the huge difference by using direct registers with C/C++, compared to using a Python library. As can be seen, the direct access speed is more that 50 times faster than Python. This is why I’m surprised there doesn’t seem to be any existing C/C++ GPIO library that uses direct register access (and not using /sys/class/gpio ).

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.