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.

BBB: Can't toggle GPIO1[1]

Other Parts Discussed in Thread: AM3359

Board: BBB, A6
AM335X_StarterWare_02_00_01_01
CCSv5.5, Windows7

Hi,


I modified the project gpioLEDBlink with the intention to additionally toggle GPIO1[1], but all I can see on the scope is a constant HIGH level.
This is how  GPIO1[1] is set:

  void GPIO1Pin1PinMuxSetup(void) {
      volatile unsigned int var2, var3;

      var2 = *(unsigned int *) (SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(1));


HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(1)) = (1<<4) + (0<<3) + 7; //Offset 0x804 is for conf_gpmc_ad1 ( for gpio1[1]) // with pull-up resistor enabled var3 = *(unsigned int *)(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(1)); }


The result here is var2 = var3 = 0x31, i.e. MODE0 and the write operation did not change anything.
In the memory browser this is shown:
offset to Control Module    contents
----------------------------------------
0x800                                   0x31
0x804                                   0x31    for GPIO1[1]
0x808                                   0x31                
0x80C                                  0x31
0x810                                  0x27
0x814                                  0x27    for GPIO1[5]
etc.

Applying the appropriate function to GPIO1[5] provides a positive result, i.e. GPIO1[5] toggles.
But that is only because the register already had been set to 0x27 (MODE7), writing to the register is not possible.

And no, I have not switched to user mode. The function above is invoked right after GPIO1Pin23PinMuxSetup() (which resides in Debug library), the original function from project gpioLEDBlink.

So the question is what has to be done to write to that register, for instance to conf_gpmc_ad1 at offset 0x804?
Does anybody have an idea?

Thank you!

Martin

  • Hi Martin,

    For using the GPIO1[1] pin, the mux mode has to be configured for MODE7 in the control register conf_gpmc_ad1(offset : 0x804).

    From the above observation, it seems the mux mode is not configured properly because the value in the regiseter is showing as 0x31. The lsb 3 bits should have been "111" instead of  "001".

    It is enough to write just MODE7 value to the register. Please refer the pin mux configuration of gpio pin in the Starterware beaglebone LEDblink example.

    Regards,

    M.Jyothi Kiran

     

  • Hi Jyothi,

    thanks for your response.
    You are exactly right and I am aware of this.

    But the problem is that it is not possible to write to this register.
    The StarterWare example is meant for GPIOI1[23]. It is ok because the register already has a value of 0x27 before
      HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_A(7)) = CONTROL_CONF_MUXMODE(7);
    tries to write '7' to it.
    (By the way, AM335X_StarterWare_02_00_01_01 does not seem to have a definition for MODE7, but uses CONTROL_CONF_MUXMODE(7) instead.)

    Can you think of any reason why it is not possible to write to the register?
    Is there a write protection status bit anywhere that has to be disabled?

    Thank you.

    Regards,
    Martin

  • Hi Jyothi,

    the next idea was that it might have something to to with the description at
       http://beagleboard.org/support/bone101/#headers-black
    where pins are mentioned that are used by other capes.

    But then I tried to write to the register (at addr SOC_CONTROL_REGS + + CONTROL_CONF_GPMC_CSN(0) = 0x44E1 087C) to configure GPIO1[29].
    The result was the same: Writing was not possible.
    Any suggestions are welcome!
    Thank you.

    Martin

  • Martin,

    you DEFINIELY have to set correct pin MUX, elsewhere it will not work. There is a tool available from TI where you can configure your pins as desired and then can create some C-code which contains the required MUX-functions. I'd recommend to use this tool to find the correct pin-multiplexing parameters.

  • Hi Jyothi,

    I just run the Pin Mux Utility.
    My processor is Sitara XAM3359AZCZ100.
    Would that correspond to AM335x Rev 1x or AM335x Rev 2x?
    3.3V for all domains?

    As I am not using Linux I am afraid there is not a function writel(....) as shown in mux.h.
    But doesn't that function just do what I have been trying to do: writing a value to a memory location?

    The definition in mux.h is this:
    #define MUX_VAL(OFFSET,VALUE)\
        writel((VALUE), AM335X_CTRL_BASE + (OFFSET)

    Could you do me a favor and check if AM335X_CTRL_BASE is identical to 0x44E1 0000 in your Linux development kit?
    If it is I cannot see what should be different to using
      HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(1)) = 7;
    or
      *(unsigned int *) (SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(1)) = 7

    These are the parameter definitions:
    #define CONTROL_CONF_GPMC_AD(n)   (0x800 + (n * 4))
    #define SOC_CONTROL_REGS          (0x44E10000)

    What do you think?

    Regards,
    Martin

  • Hi Jyothi,

    perhaps the function writel() is doing something we don't know.

    Would it be possible for you to share the source code of  that function?

    Regards,

    Martin

  • Hi Martin,

    The control register address offset 0x44E1 0000 and pinmux register conf_gpmc_ad1 offset 0x804  are correct.

    The below line should be enough to write the registe value correctly:

    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(1)) = 7;

    There is one restriction to write in to control module registers:  "For writing to the control module registers, the Cortex A8 MPU will need to be in privileged mode of operation and writes will not work from user mode."

    Could you please check whether A8 is in previlaged mode, when write instruction is executed? If A8 mode is correct, then the write should happen properly with the above instruction.

    Regards,

    M.Jyothi Kiran

     

  • Hello

    to convert the output of the pinmux tool you have to do the following steps

    first at mux.h replace

    #define MUX_VAL(OFFSET,VALUE) writel((VALUE), AM335X_CTRL_BASE + (OFFSET));

    with

    HWREG( SOC_CONTROL_REGS + (OFFSET)) = (VALUE);

    and  #include "hw_types.h"

    at pinmux.h

     #include "mux.h" 

    and delete  /* Design Status: NO ERRORS */ and Spaces  


  • Hi Jyothi,

    so far I relied on the note
        "On entry to the main() function of application, the system will be in privileged mode."
    from the StarterWare manual.

    When I step-debug through main() and watch the CPSR register, the lower 5 bits are M = Mode of ARM = 10000. I assume that CPSR[1] is the bit for user/privileged mode and 0 means privileged mode.
    Then this would mean A8 is in privileged mode.
    Calling
        CPUSwitchToUserMode();
    however does not change these 5 mode bits. So I am not sure if one can rely on that information.
    When
        CPUSwitchToPrivilegedMode(); (which uses a sWi instruction)
    is called, the PC does not return, i.e. the function after CPUSwitchToPrivilegedMode(); is not reached.
    Halting the debugger then leads to the message
        No source available for "0x20084"
    or
        No source available for "0x20008" .

    So the question comes up, "What causes this function to crash?"

    and "What are the indications for being in privileged mode?"

    Regards,
    Martin

  • Hi Martin,

    Please find below explanation:

    "When I step-debug through main() and watch the CPSR register, the lower 5 bits are M = Mode of ARM = 10000. I assume that CPSR[1] is the bit for user/privileged mode and 0 means privileged mode.
    Then this would mean A8 is in privileged mode.'

    If the lower 5 bits of CPSR register are "10000", then the mode is User mode. It is not previlege mode. Please refer the below link which explains about ARM mode bits:

    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0290g/I27695.html

    Since the mode is user mode, the write to conf_gpmc_ad1 is not possible.

    Please check why the arm mode is not in previleged mode on entry to main().

    Regards,

    M.Jyothi Kiran

     

     

     

     

  • Hello Tobias,

    thanks for that hint. Good to know how to make things easier, even if it does'nt solve my problem writing to the register.

     Regards,

    Martin

  • Hello Jyothi,

    thank you. That is interesting.

    It is a very strange behaviour.
    When my application is loaded, M is usually b10000.
    When gpioLEDBlink.out is loaded, M is always b11111.
    If after that my application is loaded, M sometimes is b11111 or b10000, but in most cases b10000.

    But the story already starts when a new and empty project is build and loaded: M is b10000 right at the beginning.
    What is the difference between an example project and a new empty project?
    Could the missing .cmd-file be responsible?

    But the application I have been testing so far has one.


    Regards,
    Martin

  • Hi Martin,

    In starterware, on startup, control will first jump to reset handler "Entry".  This reset handler sets up the stack pointers for all the modes. The mode will be switched to supervisor mode(previleged mode) at the end of reset handler. The reset handler will present inside the file "system_config/armv7a/cgt/init.asm". From the reset handler the code will jump to the function "start_boot", which will take care of interrupt vector configuration and then it will jump to main() function.

    In Starterware, all these functionalities will present inside the folder "system_config" and this library "system.lib" will be linked to all the example projects. Since the mode switching is taken care inside the startup code, on entry to main(), the ARM will be in correct mode(previleged mode).

    The CCS empty project, that you have created, may be using default startup functionality that is provided by CCS and it may not be taking care of ARM mode.

    Regards,

    M.Jyothi Kiran

  • Hi Jyothi,

    the problem has been solved.
    I had been using AM3359.cmd from CCS instead of using a .cmd file from StarterWare.
    The Starterware command file has additional information for linking 'Entry'.

    However, as with the example project gpioLEDBlink, CPUSwitchToPrivilegedMode() does not switch back to privileged mode once A8 is in user mode.

    Thank you very much for your support!

    Regards,

    Martin