This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM65X: GPIO control from command line

Part Number: PROCESSOR-SDK-AM65X
Other Parts Discussed in Thread: AM6548, TLV320AIC3106

Hi Forum,

I am trying to configure GPIO pins as inputs or outputs, and then write to or read from them using simple command-line utilities in Linux.  I am using the Processor SDK for Linux, 06.00.00.07.

Can someone provide example of configuring pins for inputs (possibly with pull-ups or pull-downs, or floating), and as outputs from the command line?  And some examples for then reading or writing to the configured pins from the command line?

Also, I know that there is some sort of mapping between Linux GPIO numbers and the physical GPIO pins on the AM6548.  Can anyone explain where this mapping is described?  For examples, there are various processor sections for GPIO0, GPIO1, WKUP_GPIO, etc., but I have no idea how these pins correspond to Linux GPIO integer values.

Some concrete examples (or a pointer to a good reference on the topic) would be greatly appreciated.  Our custom board is largely based on the EVM for the AM65x, but of course we have some pins that are dedicated to GPIO for various inputs and outputs.  We have a couple of outputs connected to drive LEDs, and just getting a sanity check on being able to turn those on and off would be a huge confidence boost.  Likewise, connecting a logic high or logic low to a GPIO input and being able to read it would greatly increase confidence.

I'd like to do this for all of the GPIO we have available on our board, which is why I am requesting the mapping between the Linux GPIO number and the actual GPIOx_nn pin on the AM6548.

If there is an easier way to do this, I am certainly open to suggestions.  I am a relative novice with embedded Linux, and we are just bringing our first AM6548 design to life.

Thanks for your time and help!

Scott

  • Hi Scott,

    Usually AM65x device pins are configured at u-boot and/or kernel level, in DTS files. Check below e2e thread for details:

     You can try to access (read/write) GPIO pad configuration registers from user space with devmem2 and/or omapconf tool.

    Regards,
    Pavel

  • Thanks for your reply, Pavel.

    omapconf was not available on the AM65x Linux kernel, but devmem2 was.

    By looking at a pad configuration register for a GPIO using devmem2, I saw that it had a value of 0x8210007.  According to the Pad Configuration Registers description in the Technical Reference Manual for the AM65x (Rev. D), the bits indicate pullup/pulldown is disabled, TX_DIS driver is disabled for that pad,  RXACTIVE receiver is disabled for that pad, weak pullup/pulldown is disabled for that pad, and Mode 7 (GPIO) is selected for that pad.

    In order to be able to read and/or write the pin direction and value from /sys/class/gpio (sysfs), I had to add the following to my Linux DTS file:

    //SDW - test to see if pad configuration works if we add to GPIO driver
    &main_gpio0 {
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_gpio0_pins_default>;
    	status = "okay";
    };
    
    &main_pmx0 {
    	main_gpio0_pins_default: main-gpio0-pins-default {
            pinctrl-single,pins = <
                // Encoder on P9 - treated as GPIO for testing
                AM65X_IOPAD(0x013C, PIN_OUTPUT | PIN_INPUT, 7)    /* (AH22) GPIO0_79 (EQEP1_A) */
                AM65X_IOPAD(0x0140, PIN_OUTPUT | PIN_INPUT, 7)    /* (AE21) GPIO0_80 (EQEP1_B) */
                AM65X_IOPAD(0x015C, PIN_OUTPUT | PIN_INPUT, 7)    /* (AC20) GPIO0_87 (EQEP1_I) */
                AM65X_IOPAD(0x0144, PIN_OUTPUT | PIN_INPUT, 7)    /* (AC22) GPIO0_81 (EQEP1_S) */
            >;
        };
    
    ...etc...

    After rebuilding and booting Linux, I could read the pad configuration register for AH22 using "devmem2 0x11c13c":

    root@am65xx-evm:~# devmem2 0x11c13c
    /dev/mem opened.
    Memory mapped at address 0xffff90240000.
    Read at address  0x0011C13C (0xffff9024c13c): 0x00050007

    This indicates that the pad configuration register is locked against further writing, TX_DIS driver is enabled, RXACTIVE receiver is enabled, weak pull-up/down is disabled, and Mode 7 (GPIO) is selected.

    I could then configure and read/write the port using /sys/class/gpio as follows.  The sysfs pin number for GPIO0_79 is (56 + 79) = 135, where 56 is the first pin controlled by gpiochip56, which controls GPIO0_nn.

    root@am65xx-evm:/sys/class/gpio# echo 135 > export
    root@am65xx-evm:/sys/class/gpio# cd gpio135
    root@am65xx-evm:/sys/class/gpio/gpio135# cat direction
    in
    root@am65xx-evm:/sys/class/gpio/gpio135# echo out > direction                   
    root@am65xx-evm:/sys/class/gpio/gpio135# cat direction
    out
    root@am65xx-evm:/sys/class/gpio/gpio135# cat value
    0
    root@am65xx-evm:/sys/class/gpio/gpio135# echo 1 > value
    root@am65xx-evm:/sys/class/gpio/gpio135# cat value
    1
    root@am65xx-evm:/sys/class/gpio/gpio135# echo 0 > value
    root@am65xx-evm:/sys/class/gpio/gpio135# cat value
    0

    Note that even if I wanted to use the pin as an output, I needed to configure it in the DTS with PIN_INPUT | PIN_OUTPUT to enable both the receiver and transmitter on the pad.  This allowed me to read back the values actually present at the output pins.

    It seems a bit cumbersome to have to force the pad configuration in the DTS by defining each pad and then making sure it is referenced by some driver, but that was the only way I came up with that worked.  If there is a better way to perform pad configuration, please let me know.  For GPIO1_nn pins, a similar group of pins would be defined, and then referenced by &main_gpio1.

    Thanks, and best regards,

    Scott

  • Scott,

    I would recommend you to check how pin AD19 gpio0_71 is configured as output and reuse the same approach. This gpio0_71 pin is used to generate reset signal to audio codec AIC3x.

    linux-4.19.38/arch/arm64/boot/dts/ti/k3-am654-gp.dtso

    &main_pmx0 {

        aic3106_pins: aic3106_pins {
            pinctrl-single,pins = <
                AM65X_IOPAD(0x011c, PIN_OUTPUT, 7) /* (AD19) PRG1_PRU0_GPO15.GPIO0_71 */
            >;
        };
    };

    tlv320aic3106: tlv320aic3106@1b {

    gpio-reset = <&main_gpio0 71 GPIO_ACTIVE_LOW>; /* gpio0_71 */

    }

     

    You can explore register SOC_PADCONFIG_71 at 0x0011C11C address.

     

    Regards,
    Pavel

  • Thanks for your reply, Pavel,

    Your example is helpful, but doesn't really address how GPIO pins can be read/written from the command line or via scripts.  Do you have any examples of this?  My previous example using /sys/class/gpio exports, followed by setting direction and "cat"-ing the value seems to work, but is pretty cumbersome.

    I have heard of libgpiod, which appears to set up GPIO using devices, and provides a variety of utilities for manipulating GPIO in user space, but it does not appear to be built into the Processor Linux SDK.  Do you know if this approach is supported, or is planned to be supported?

    Many thanks, and best regards,

    Scott

  • Scott,

    Let me clarify. There are two registers for directions here.

    First input/output direction is set in padconfig registers, in example SOC_PADCONFIG_79 or CTRLMMR_PADCONFIG79 at address 0x0011C13C. The input/output direction is set with bit [18] RXACTIVE (0: output, 1: input)

    AM65X_IOPAD(0x013c, PIN_OUTPUT, 7)

    Second input/output direction is set in GPIO0 module registers, in GPIO_DIRx registers. Check AM65x TRM, section 12.1.2.4.2 GPIO Function. This is the direction you are configuring with GPIO sysfs.

     

    Regards,
    Pavel

  • Thanks Pavel,

    Seems strange that I was not able to read back what had been written to an output unless I specifically configured the padconfig to both PIN_INPUT | PIN_OUTPUT.  I actually went through this in detail with a local TI FAE, and that's what we came up with.

    Can you explain why the actual output value that is set for a particular GPIO cannot be read back unless the padconfig register is set up this way?

    Your help is greatly appreciated!

    Scott

  • Scott,

    I am not sure I understand your latest question. Do you mean that you set a GPIO pin PADCONFIG register to PIN_OUTPUT in linux DTS file, and then you are NOT able to read the correct value from this PADCONFIG register in userspace with devmem2 tool?

    Note that any pin can be input/output (PIN_INPUT) or output only (PIN_OUTPUT). I mean that when using PIN_INPUT in DTS file, you are making this pin input/output (not input only). Check again bit [18] RXACTIVE of PADCONFIG registers.

    Regards,
    Pavel