GPIO DMA Address Map

Using jetson-nano-gpio-example as a reference, I’ve gotten input being detected on the pins that are already mapped within the included gpionano.h header.
I need more inputs that what is mapped/defined in the gpionano.h file.

In another thread here, someone mentioned to run ‘sudo cat /sys/kernel/debug/tegra_pinctrl_reg’
I ran that, and the address range output is all in 0x7000… range, which is strange to me, since all of the addresses in gpionano.h are in the x60000… range. This conflict is confusing to me, why are these addresses different?

Here is a spreadsheet I made in an attempt to organize what I’ve found so far.

I request a #define (address) for each gpio pin that is on the developer boards J41 GPIO Expansion Header.

Edit 3: I’ve forked the repo. and added an additional example for a keyboard emulator. While testing this, I did notice something seems incorrect with the initialization of the gpio pins via the methods used by these examples.

If I simply run the switch example, or my keyboard_emu example, input is not detected at all until after I go into python and setup the pin using the following code:
import RPi.GPIO as GPIO

Would it be possible for someone to look over the example code and recommend changes to properly init the pins without having to do the python stuff first? (I’ll push changes to my forked repo so that other users in the future may benefit from this)

hello wassti,

please refer to TX1 TRM, and please refer tp [Table 1: System Address Map] for start address, it’s start from 6000:d000 for GPIO-1.
then you should also access pinmux spreadsheets, for the actual pins, and please map the pin with tegra-gpio.h.

BTW, you should check # cat/sys/kernel/debug/gpio for allocated GPIOs.
for example, gpiochip0: GPIOs 0-255, parent: platform/6000d000.gpio, tegra-gpio

I’ve been reading the TRM and pinmux spreadsheets for a couple days now, my spreadsheet there has columns from the pinmux spreadsheet. While I was going over this documentation, I did notice a lot of conflicting information, to use one example, in some documents, J41 Pin 24 is referenced as being SPI0_CS0. However, in other documenation, it is labled as SPI1.

Running the cat/sys/kernel/debug/gpio does give me more insight into how these might be organized, however, I also must assume that you mean GPIO-1-GPIO-0 existing at 6000d000, not GPIO-1-GPIO-1, is this correct? Edited for clarity, talking about the pin #, not the bank #

I’m confused as to how I am supposed to get addresses from cat/sys/kernel/debug/gpio when I run this, it shows me for example that gpio-12 is assigned to SPI1_MOSI, which could be J41-pin19 or J41-pin37. From the examples, I have the address of both of those pins, J41-pin19=0x6000d008 and J41-pin37= 0x6000d00C C is equal to 12, so lets assume GPIO-12 is J41-pin37.
Now lets do the same for J41-pin19(SPI0_MOSI), looking at the cat/gpio again, SPI0_MOSI is set to gpio-16, but we know the address already from the example, but this is where I get lost. Shouldn’t gpio-16 be an address that ends with 0? But the example shows it ends with an 8. I will modify my circuit and code to test these specific pins and these specific address’, but something just isn’t adding up imo.

hello wassti,

it’s preferred to use the GPIO port index,
for example,
it’s gpio-0 ~ gpio-7 for port-A, total 256 pins available.

#define TEGRA_GPIO(port, offset) \
  	((TEGRA_GPIO_PORT_##port * 8) + offset)

here’s an example,
SPI1_MOSI. it’s GPIO3_PB.04 = 1 * 8 + 4 = gpio-12.
SPI0_MOSI. it’s GPIO3_PC.00 = 2 * 8 + 0 = gpio-16,

Thanks for your patience with me :)

I still don’t understand how we get an address to define in the header.
For Example, in that header, there is:
#define GPIO_216 0x6000d60C // Jetson Nano 7[AUDIO_MCLK]
#define GPIO_50 0x6000d108 // Jetson Nano 11[UART2_RTS]
#define GPIO_194 0x6000d600 // Jetson Nano 15[LCD_TE]
#define GPIO_14 0x6000d004 // Jetson Nano 13[SPI2_SCK]
#define GPIO_16 0x6000d008 // Jetson Nano 19[SPI1_MOSI]
#define GPIO_38 0x6000d100 // Jetson Nano 33[GPIO_PE6]
#define GPIO_77 0x6000d204 // Jetson Nano 38[I2S4_SDIN]
but in addition to those addresses, I would like to have addresses for:

#define GPIO_12 // Jetson Nano 37[SPI2_MOSI]
#define GPIO_14 // Jetson Nano 26[SPI1_CLK]
#define GPIO_51 // Jetson Nano 36?[UART1_CTS][UART2_CTS]?
#define GPIO_76 // Jetson Nano 35[I2S4_LRCK]
#define GPIO_168 // Jetson Nano 32[LCD_BL_PWM]
#define GPIO_200 // Jetson Nano 31[GPIO_PZ0]
#define GPIO_149 // Jetson Nano 29[CAM_AF_EN]
#define GPIO_20 // Jetson Nano 24[SPI0_CS1]
#define GPIO_19 // Jetson Nano 26[SPI0_CS0]
#define GPIO_13 // Jetson Nano 22[SPI1_MISO]
#define GPIO_15 // Jetson Nano 18[SPI1_CS0]
#define GPIO_232 // Jetson Nano 16[SPI1_CS1]
#define GPIO_79 // Jetson Nano 12[I2S0_SCLK]

Trying to follow your example:
GPIO3_PC.00 = 2 * 8 + 0 = gpio-16
#define GPIO_16 0x6000d008

S = 18 (19th letter but arrays start at 0 so x-1)
18 * 8 = 144
144 + 5 = 149

Or am I not understanding what the below code does?

#define TEGRA_GPIO(port, offset) \
  	((TEGRA_GPIO_PORT_##port * 8) + offset)

so if I’m following you correctly, I put

#define GPIO_BASE	0x6000d000
#define TEGRA_GPIO_PORT_S 18
#define TEGRA_GPIO(port, offset) \
  	((port * 8) + offset + GPIO_BASE)


into my header. This compiles. When I run it, I get an output of “Bus Error” and the program terminates.

I’ve finally stumbled across this github repo, which seems to have all of the offsets defined. The blink example contained within also works with no changes.

I’ve forked and added some input examples to this repo. However, some pins don’t seem to go into gpio/input mode, I assume I need to disable the spi/uart that is in control of those pins, its strange though, because the lock bit does not appear to be set on them.