Cannot change Jetson Orin AGX GPIO output level after boot

I’m trying to use GPIO17 (pin 22 on 40-pin header) as an output GPIO, but I can’t get the voltage level to change from low to high, or from high to low using gpiod tools, libgpiod, or the Jetson.GPIO python library.

I’m able to change the starting output level (drive 0 or drive 1) by chaning the pinmux MB1 configuration in the Pinmux spreadsheet and reflashing my board, but I can’t change the output level at runtime using they gpiod tools, or through the pinmux register directly.

Setting GPIO17 (SOC_GPIO23), GPIO3_PP.04, as Bidirectional and Drive 1 in the pinmux spreadsheet, I see 1.6V on pin-22 of the 40-pin header after boot. Likewise if I set GPIO17 to Drive 0 in the pinmux spreadsheet, the voltage level on pin-22 after boot is 0V. Using gpioset to change the output level after boot, does not change the voltage level on pin-22.

I’ve tried to verified that gpioset is chaning the pinmux registers for PP.04, which it looks like it is, yet the voltage level of pin-22 does not change.

Example:

  • GPIO17 configured as Bidirectional and Drive 1 in pinmux spreadsheet.
  • After booting pin-22 shows 1.6V
~$ sudo gpioinfo | grep PP.04
        line  96:      "PP.04"       unused  output  active-high

PADCTL_G3_SOC_GPIO23_0:
~$ sudo busybox devmem  0x02430020
0x00000040

GPIO_P_ENABLE_CONFIG_04_0:
~$ sudo busybox devmem  0x02212480
0x00000003

GPIO_P_OUTPUT_CONTROL_04_0:
~$ sudo busybox devmem  0x0221248c
0x00000000

GPIO_P_OUTPUT_VALUE_04_0:
~$ sudo busybox devmem  0x02212490
0x00000001

Pinmux registers for PP.04 look correct after boot based on my current MB1 Pinmux configuration, GPIO17 - Bidirectional - Drive 1.

If I try to set the output level of line 96 (PP.04) to 0 using gpioset, the voltage level of pin-22 i remains at 1.6V.

With “sudo gpioset -m wait 0 96=0” active:

~$ sudo gpioinfo | grep PP.04
        line  96:      "PP.04"    "gpioset"  output  active-high [used]

PADCTL_G3_SOC_GPIO23_0:
~$ sudo busybox devmem  0x2430020
0x00000040

GPIO_P_ENABLE_CONFIG_04_0:
~$ sudo busybox devmem  0x02212480
0x00000003

GPIO_P_OUTPUT_CONTROL_04_0:
~$ sudo busybox devmem  0x0221248c
0x00000000

GPIO_P_OUTPUT_VALUE_04_0:
~$ sudo busybox devmem  0x02212490
0x00000000

Based on the pinmux registers for PP.04, it looks like when I set the GPIO output to 0, the GPIO pinmux registers are getting configured correctly to driving the pin low, but it still shows 1.6V on my multimeter.

What am I doing wrong? Am I looking at the correct pinmux registers for Orin AGX pin-22?

Hi,
If the device cannot be flashed/booted, please refer to the page to get uart log from the device:
Jetson/General debug - eLinux.org
And get logs of host PC and Jetson device for reference. If you are using custom board, you can compare uart log of developer kit and custom board to get more information.
Also please check FAQs:
Jetson AGX Orin FAQ
If possible, we would suggest follow quick start in developer guide to re-flash the system:
Quick Start — NVIDIA Jetson Linux Developer Guide 1 documentation
And see if the issue still persists on a clean-flashed system.
Thanks!

I do not have any issues flashing my board.

Does anyone have any suggestions or updates on why GPIO output control isn’t working on my Orin AGX board running Jetpack 6.1?

Are you talking about you modify the registers (padctl/GPIO_P_ENABLE_CONFIG_04_0) for PP04 but the result on multimeter is still wrong?

Which Jetpack release version is that?

I’m running JetPak 6.1 on my Orin AGX devkit.

Ideally I’d like to control the GPIO using the gpiod tools (gpioset) as described in my orginal post with commands like "“sudo gpioset -m wait 0 96=0”, or a simpile C app. I included the values of the individual GPIO pinmux registers for reference.

I’ve also tried creating a simple C app using the gpiod library, which seems to behave the same as gpioset, i.e. GPIO pinmux register get updated, but the voltage level on the GPIO pin does not change.

Here is the C app I tried for reference.

#include <gpiod.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define CHIP_NAME "gpiochip0"
#define CHIP_DEV_NAME "/dev/gpiochip0"

void print_usage(const char *prog_name) {
    printf("Usage: %s <gpio_line> [high|low]\n", prog_name);
    printf("  - <gpio_line>: The GPIO line number to control or check\n");
    printf("  - [high|low]: Optional, set the GPIO line to high or low\n");
}

int main(int argc, char *argv[]) {
    struct gpiod_chip *chip;
    struct gpiod_line *line;
    int line_num;
    int ret;
    int value;

    if (argc < 2 || argc > 3) {
        print_usage(argv[0]);
        return 1;
    }

    line_num = atoi(argv[1]);
    if (line_num < 0) {
        fprintf(stderr, "Invalid GPIO line number.\n");
        return 1;
    }

    // Open the GPIO chip
    chip = gpiod_chip_open(CHIP_DEV_NAME);
    if (!chip) {
        perror("Failed to open GPIO chip");
        return 1;
    }

    // Get the GPIO line
    line = gpiod_chip_get_line(chip, line_num);
    if (!line) {
        perror("Failed to get GPIO line");
        gpiod_chip_close(chip);
        return 1;
    }

    if (argc == 3) { // If a state is specified
        if (strcmp(argv[2], "high") == 0) {
            value = 1;
        } else if (strcmp(argv[2], "low") == 0) {
            value = 0;
        } else {
            fprintf(stderr, "Invalid state. Use 'high' or 'low'.\n");
            gpiod_line_release(line);
            gpiod_chip_close(chip);
            return 1;
        }

        // Request the line for output
        ret = gpiod_line_request_output(line, "gpiod-example", value);
        if (ret < 0) {
            perror("Failed to request line for output");
            gpiod_line_release(line);
            gpiod_chip_close(chip);
            return 1;
        }
        printf("Set GPIO %d to %s\n", line_num, argv[2]);
        sleep(5);
    } else { // No state specified, check current state
        // Request the line for input
        ret = gpiod_line_request_input(line, "gpiod-example");
        if (ret < 0) {
            perror("Failed to request line for input");
            gpiod_line_release(line);
            gpiod_chip_close(chip);
            return 1;
        }

        // Get the current value of the line
        value = gpiod_line_get_value(line);
        if (value == 1) {
            printf("Current Status of GPIO %d: HIGH\n", line_num);
        } else if (value == 0) {
            printf("Current Status of GPIO %d: LOW\n", line_num);
        } else {
            fprintf(stderr, "Failed to get GPIO value\n");
        }
    }

    // Clean up
    gpiod_line_release(line);
    gpiod_chip_close(chip);

    return 0;
}

Here is a python script I created using Jetson.GPIO, which also behave the same as gpiod (gpioset).

#!/usr/bin/env python3
import Jetson.GPIO as GPIO
import argparse
import time

# Setup command-line argument parsing
parser = argparse.ArgumentParser(description='Control or check status of a GPIO pin on Nvidia Jetson AGX Orin using BCM numbering.')
parser.add_argument('gpio', type=int, help='GPIO number to control or check (BCM numbering)')
parser.add_argument('state', nargs='?', choices=['high', 'low'], help='Set GPIO state to high or low (optional)')
args = parser.parse_args()

GPIO_NUMBER = args.gpio

# Setup GPIO mode
GPIO.setmode(GPIO.BOARD) # 40-pin header pin

try:
    if args.state:
        # Set up the GPIO pin as an output to set state
        GPIO.setup(GPIO_NUMBER, GPIO.OUT)
        # Set the GPIO pin to the specified state
        state_value = GPIO.HIGH if args.state == 'high' else GPIO.LOW
        GPIO.output(GPIO_NUMBER, state_value)
        print(f"Set GPIO {GPIO_NUMBER} to {args.state.upper()}")
        time.sleep(5)        
    else:
        # Set up the GPIO pin as an input to read state
        GPIO.setup(GPIO_NUMBER, GPIO.IN)
        # Read the current status of the GPIO pin
        current_status = GPIO.input(GPIO_NUMBER)
        print(f"Current Status of GPIO {GPIO_NUMBER}: {'HIGH' if current_status else 'LOW'}")

except Exception as e:
    print(f"An error occurred: {e}")

GPIO.cleanup(GPIO_NUMBER)

Modifying the GPIO Pin Direction and Initial State in the pinmux spreadsheet, creating a new device tree, and reflashing the board works to change the output voltage level, but I need to drive the GPIO high/low dynamically at runtime.

Hi,

I understand you want to use gpiod or some scripts to control. But that didn’t answer the question.

So will modify the register gives you the correct result even in run time?

I don’t care what is pre-defined in pinmux when you flashed. I just want to know if even modifying the register is not working here.

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