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.

LM4F231E5QR - Unable to mux PF0

Team,

I am about to post a question and an answer regarding an issue that I recently worked on and found it a valuable experience that I hope can be used in the future.

When using an LM4F231E5QR (REV A1), and attempting to use QEI0 on PF0/PF1 there was an issue. While in debug I observered the encoder's position and speed. The position oscillated between 2 points but the speed registered movement. When scoping the pins, it appeared that the encoder was working correctly, and when reviewing the code, the configurations seemed correct.

Unfortunately the following was what the processor was actually seeing.

The issue at its core was that PF0 was not actually being configured as QEI0 - phA0. It was locked as an NMI. In my following post, I will walk you through how to restore the PF0 to a GPIO capable of being modified.

Regards,

Ricky Chelminski
Digital Applications

  • Team,

    When using the lm4f231e5qr (Rev A1) there are a few GPIO pins which have been described in the errata as defaulting their alternate function. The full list can be found in the described Errata Rev.A .

    In the errata, there is a suggested workaround for all the listed pins, but a slightly more in-depth workaround for 2 pins (PD7 and PF0).

    Workaround:

    To reconfigure the pins to their intended reset state (GPIO Input, GPIODEN = 0), software must clear the corresponding bits in the GPIOAFSEL and GPIODEN registers for the associated pins.

    For pins PD7 and PF0, software must clear the corresponding AFSEL bit using the register commit control procedures described in the Commit Control section in the General-Purpose Input/Outputs chapter in the Data Sheet .

    Note that the PD7 and PF0 should be grounded, if possible, to prevent triggering an NMI. If that is not possible, an NMI handler must be implemented in case a High level is applied to PD7 or PF0 before they can be reconfigured.

    lm4f231e5qr Data sheet: http://www.ti.com/lit/gpn/lm4f231e5qr

    Note: This issue was fixed in Rev A3.

    The following is an implementation of the above errata workaround. It will be modifying the GPIO pin PF0 to allow further configurability.

     

    Step 1 – Modify Main

    In the setup of your system (usually Main) you will have to enable the GPIO port. This is the line you will look for.

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    Directly following this line add these lines

    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= GPIO_PIN_0;
    HWREG(GPIO_PORTF_BASE + GPIO_O_AFSEL) &= 0xfe;
    HWREG(GPIO_PORTF_BASE + GPIO_O_DEN) &= 0xfe;
    HWREG(GPIO_PORTF_BASE + GPIO_O_PCTL) = 0x00;

    Line 1, unlocks the GPIO.
    Line 2 allows the registers AFSEL,PUR,PDR, and DEN to be written.
    Line 3 clears the AFSEL register per the workaround.
    Line 4 clears the DEN register per the workaround.
    Line 5 turns all of PORTF back to a GPIO.

    With the pin unlocked, it allows the pin to be configured to whatever peripheral

    Step 2 – Add an NMI handler

    Add the following extern to either your header file or the top of your c file

    extern void NmiSR(void);

    Then, add the NMI ISR function to your c file

    void NmiSR(void)
    { //ignore NMI}

    Step 3 – Modify your startup file (*.s)

    For this example we will use Keil uVision startup code. For reference, it is called “startup_rvmdk.S,” though this step is just as integral for any other programming environment.

    In the startup file, there will be a section called Vector table. You will see that there is already a handler for NMI interrupts, called NmiSR. This is a label and if you dig further into your startup file you will see that it connects to a bit of code that will look like this,

                    NmiSR
                                    B             NmiSR

    This is an infinite loop branching to itself if an NMI occurs.

    Either delete those two lines, or comment them out.

    Then go back above the vector table. There may be a section where you have placed external declarations, and if not then I place it before the vector table but after the reset code section.

    Add the following line:

    EXTERN NmiSR

    Conclusion

    After these steps have been implemented you will have successfully modified the pin, allowing it to be a GPIO or other peripheral.

    Regards,

    Ricky Chelminski
    Digital Applications

  • @Ricky - Thank you - detail provided will help many.  Perhaps some additional points bear mention:

    a) PF0 & PD7's "special conditions" are listed both in the MCU datasheet and errata.  Those getting stuck have not properly (if at all), "RTFM."

    b) Note that you've "and'ed" both 0 bits w/in AFSEL & DEN with a 0 - this is a good & protective technique as other bits in play are unaffected. 

    c) MCU datasheet provides a nice listing of the various register values which enable multiple configurations of these (& other) pins on these complex MCUs

    For the record - similar PF0 encounters have occured earlier - link below provides additional subject material for those interested...

    http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/471/t/171296.aspx