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: PRU access to pinmux settings

Hi all,

For an PRU application I'm doing I need to change the MUX for a pin from MODE6 (gpo)  to MODE7 (gpi) and viceversa, the reson is because I've something like this:

 - http://pastebin.com/iL4kwJ9P

On transmit mode PRU0_PRU_R30_15 (TXD) needs to be configured as GPO (MODE6) but on receive mode needs to be configured as Input (or high impedance) MODE7 to not force RX line. I tried to do this by writing directly to the padconf register ( conf_gpmc_ad13, 0x44e10834 ) but seems writting to this register has no effect.  So I tried to do the same using devmem2 in userspace, and I obtained the same result, writting to 0x44e10834 has no effect. For example the following code just tries to change from INPUT | MODE7 (0x2f) to OUTPUT | MODE7 (0x07) but doesn't work.

# ./devmem2 0x44e10834
/dev/mem opened.
Memory mapped at address 0xb6f86000.
Value at address 0x44E10834 (0xb6f86834): 0x2F

# ./devmem2 0x44e10834 b 0x0f
/dev/mem opened.
Memory mapped at address 0xb6fd6000.
Value at address 0x44E10834 (0xb6fd6834): 0x2F
Written 0xF; readback 0x2F

# ./devmem2 0x44e10834 b 0x0f
/dev/mem opened.
Memory mapped at address 0xb6f37000.
Value at address 0x44E10834 (0xb6f37834): 0x2F
Written 0xF; readback 0x2F

I remember do this with OMAP3, is AM335x different in that aspect?, need I to do something else to be able to change the mux in runtime ?

Thanks in advance.

  • Hi again,

    Found why I can't change from userspace using devmem2, control module registers cannot be accesed from userland (needs privileged mode) so pinmux needs to be set from a kernel module or from PRU. But this doesn't explain why I can't set using the PRU, I made a simple code to show how I can try to set the mux for one pin.

    Mux is configured 0x0e (PIN_OUTPUT | MUX_MODE6 (GPO direct mode)) by default and I want to change to 0x2f, after executing this code in the PRU mux register is still at 0x0e value.

     ./devmem2 0x44e10834
     /dev/mem opened.
     Memory mapped at address 0xb6f43000.
     Value at address 0x44E10834 (0xb6f43834): 0xE

    Any idea what I'm missing ?

    /* Macro for accessing a hardware register (32 bit) */
    #define HWREG(x) (*((volatile unsigned int *)(x)))
    
    volatile register unsigned int __R30;
    
    /* unsigned int* shared_ram = (unsigned int *)0x10000; */
    int finish = 0;
    
    /*
     * AM335x PRU-ICSS Reference Guide (Rev. A), p. 272
     *
     * The PRU-ICSS CFG block contains the registers for control and status of
     * power management, memory parity, and enhanced PRU GP ports functions.
     */
    #define SYSCFG  0x26004
    #define GPCFG0  0x26008
    
    /* GPIO configuration mux */
    #define PADCONF_GPMC_AD13       0x44e10834
    /* GPIO modes */
    #define SET_MODE_GPO            0x0e    /* PIN_OUTPUT | MUX_MODE6 (GPO direct mode) */
    #define SET_MODE_GPI            0x2f    /* PIN_INPUT  | MUX_MODE7 */
    
    int main(int argc, const char *argv[]) {
        unsigned int gpio;
    
        shared_ram = (volatile unsigned int *)0x10000;
    
        /*
         * Enable OCP so we can access the whole memory map for the
         * device from the PRU. Clear bit 4 of SYSCFG register
         */
        HWREG(SYSCFG) &= 0xFFFFFFEF;
    
        /*
         * GPI Mode 0, GPO Mode 0 
         */
        HWREG(GPCFG0) = 0;
    
        /*
         * Configure pin mux for gmpc_ad13
         */
        HWREG(PADCONF_GPMC_AD13) = SET_MODE_GPI;
        while(!finish) {
            /*
             * 200 MHz @ 5ns - delay 50us (10Khz)
             */
            __delay_cycles(10000);
        }
    
        /*
         * stop pru processing
         */
        __halt();
    
        return 0;
    }
    

  • Hi again,

    Found the answer here:

    processors.wiki.ti.com/.../PRU-ICSS_FAQ

    Q: Why can the PRU not edit pinmux settings?

    The PRU does not have privileges to edit the pinmux or pad config settings in the device-level Control Module. However, the PRU can read these registers.

    So now the question is, assuming this schematic

    http://pastebin.com/iL4kwJ9P

    Is possible switch from output to input (or high impedance) for PRU0_PRU_R30_15 (TXD) pin inside the PRU ?

  • Hi Enric,

    As you have already discovered, the PRU GPI/Os are uni-directional (not bi-directional) and while some of the PRU GPIs and GPOs are muxed on the same pin, the PRU does not have privileges to write to the AM335x Control Registers to change the pinmuxing.  

    However, you could use the PRU Digital I/Os to achieve a high impedance output.  If you require a bi-directional implementation, you can either consider tying a PRU GPI & GPO pins or a PRU Dig I/O output and input signal together in hardware.  

    The  PRU Cape and PRU software package might be a helpful reference.  The PRU Cape's temperature sensor uses  uses a PRU Dig I/O output and PRU GPI signal to achieve an open-drain, bidirectional signal, and the software package includes a corresponding demo (under the pru_cape/pru_fw/PRU_HDQ_TempSensor0/1 directory).  

    Regards,

    Melissa