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.

am335x pin mux change at run time

Other Parts Discussed in Thread: AM3359

Hi,

I need to switch the state of the pin mux for a certain pin at run time, preferably from a user space application.  I tried mmap'ing  the control module register for the pin as explained in section 9.3.51 of the TRM but without success.  The register acts as though it is read only even though the TRM says that it is read/write.

Is there another way to do this?  Is there perhaps a kernel driver function that can be called to accomplish this?  Or am I missing a configuration somewhere else that then allows me to change the state of the conf_<module>_pin register?

  • Hi Bob,

    Bob Koen said:
    Is there another way to do this?

    You can use the devmem2 function to change pinmux register from user space, i.e. if you want to set GPIO0_14 on device pad UART1_RXD (ball D16 in AM3359 ZCZ package) you should execute: 

    devmem2 0x44E10980 w 0x00000037    => this will mux GPIO0_14 on UART1_RXD (ball D16), with pullup enabled. 

    Best Regards. 
    Yordan

  • Hi Yordan,

    Devmem2 *should* work but does not.

    devmem2 0x44e108e0
    /dev/mem opened.
    Memory mapped at address 0xb6f79000.
    Value at address 0x44E108E0 (0xb6f798e0): 0x7

    devmem2 0x44e108e0 w 5
    /dev/mem opened.
    Memory mapped at address 0xb6fb4000.
    Value at address 0x44E108E0 (0xb6fb48e0): 0x7
    Written 0x5; readback 0x7

    I tried to change the register at 0x44e10980 that you suggest with similar results. These registers are being blocked from change in some way. I need to find a way to unblock them.
  • Hi Bob,

    I see you've asked this question also in another thread: e2e.ti.com/.../1523819
    There you specify that you use kernel 3.12 with Debian FS, right?

    Could you specify also which device tree file you use? In TI SDKs all am335x dts files (am335x-boneblack.dts, am335x-evm.dts & am335x-evmsk.dts) use the pad at address 0x44E108E0 as LCD_VSYNC, this pad is needed for LCD & HDMI to work.

    If I remove those device nodes & put this pin in a generic unused_pins dts node in am335x-bone-common.dtsi, devmem2 succeeds in writing into this register:
    root@am335x-evm:~# devmem2 0x44e108e0
    /dev/mem opened.
    Memory mapped at address 0xb6fa3000.
    Read at address 0x44E108E0 (0xb6fa38e0): 0x00000037
    root@am335x-evm:~# devmem2 0x44e108e0 w 0x00000031
    /dev/mem opened.
    Memory mapped at address 0xb6f89000.
    Read at address 0x44E108E0 (0xb6f898e0): 0x00000037
    Write at address 0x44E108E0 (0xb6f898e0): 0x00000031, readback 0x00000031

    Also you could check if there is a driver/process in your kernel that always keeps this pin in its default state.

    Best Regards,
    Yordan
  • Hi Yordan,

    Thanks, but...

    We gave your suggestion a try but got the same results as before.  Perhaps we aren't doing the unused_pins dts node properly?  Could you please post the snippet of your device tree that you created that did work properly?

    We are using a device tree file that was originally derived from the beaglebone device tree.  Our hardware does not use an LCD so we have repurposed those pins for other uses, including using the lcd_vsync pin from PRU1 to toggle the write line to an RS-485 transceiver.  The problem that I am trying to solve here is that there is a 5 second glitch at power up where that pin goes high when the device tree configures that pin as mode 5.  That causes a 5 second long dominant state on the RS-485 bus which really seems to upset all other devices connected to that bus.  If I configure the pin as mode 7 in the device tree then the glitch does not occur.  So I then want to switch the pin back to mode 5 just before handing it off to the PRU.

  • We finally got this to work by writing a kernel driver to write into the control register. As suggested by Thomas in the other thread this register is writable from kernel space.

    I am sure that there is a more elegant solution to this problem but we never found it.
  • Hi Bob, 

    I am glad to hear you've found a workaround for your issue. 

    Regarding the 5 second glitch you describe: 
     

    Bob Koen said:
    The problem that I am trying to solve here is that there is a 5 second glitch at power up where that pin goes high
     

    Check u-boot source code: board/ti/am335x/mux.c. In SDK7.0  u-boot (u-boot 2013.10-ti2013.12.01) the lcd_vsync pin is pulled up:   

    {OFFSET(lcd_vsync), MODE(1) | PULLUDEN | RXACTIVE}, /* NOR_A8 */ 

    And at boot time, until kernel driver takes control over this pin it stays pulled up.  Perhaps this is your case as well. Try changing this to pulldown at u-boot & see if this helps. 

    Best Regards, 
    Yordan

  • Hi Yordan,

    Thanks for your help. In the end we stayed with the workaround of using a small kernel driver to change the state of the pinmux at the time that we wanted to hand control of the pin to the PRU. It gives us the flexibility of controlling the pin as an I/O during manufacturing testing in order to verify the hardware that is controlled by the pin.

    Bob