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.

Controlling Initial State of GPIO Output Pin

Dear TI,

We would like to go configure a GPIO pin from its initial input state to an output driving high, unfortunately, it always seems to initially drive low.

We are using a TM4C1290N.  A snipped of our code is below with our instrumentation (debug pin toggles for the oscilloscope) removed for clarity:

 

// the initial write to the data register seems to have no effect.  We are trying to set it high so when we make it an output it won't glitch low

  GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_PIN_3) ;

// We program the pin to be an output, but it will initially drive the pin low not high like we want
   GPIOPinTypeGPIOOutput(GPIO_PORTM_BASE, GPIO_PIN_3);

// The next line will bring the pin high, but the glitch is not good for our application
   GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_PIN_3) ;

What is the proper way to change an input to an output driving high without a low glitch?  I noticed one other similar post 6 years ago on an older part where the order of the PadSelect and the DirModeSelect were reversed and that fixed the problem.  For us, it seemed that those calls were already done in the correct order.  We tried changing the order and it made no difference.  It looks like our library source file was created in 2014. 

Thank you for your help.

Brett

  • Hello Bret,

    One way is to have an external pull up. At power up, the device is going to be tristated, so w/o a pull up it will float low. Having a pull up will ensure that the signal is high. The next thing to do is to break the pad configuration so that first DATA register is written high, then DIR is made 1 for output mode.

    Regards
    Amit
  • I remembered this exact issue - yet am surprised by its 6 year age.

    May we assume this is not the intrusion of "WPD" (weak pull-down) via the PadSelect function?

    Purely a swag - might your initializing that GPIO as, "Open Drain" - rather than "Push-Pull" - along w/deployment of an external pull-up R - eliminate that unwanted, "initial drive to low?"   Our firm uses ARM MCUs from many - I believe this "has" worked - yet I can't recall which vendor's MCU(s) accepted this method.  

    Note that it was possible to (later) switch from Open-Drain to Push-Pull - w/that "drive to low" remaining suppressed.

  • Hi Amit,

    Thanks for your quick reply.  We discovered this problem on an open drain output that IS pulled up.  We could NOT find a way to change the pin to an output without it driving low EVEN IF we set the data register to 1 before changing from an input to an output.  I decided to have my programmers check to see if they could change ANY GPIO pin to an output without it driving low and it does not seem possible - any write to the data register before the pin is configured to an output appears to be ignored.

    I don't understand what you mean by, "break the pad configuration"?  The code we are using, and the code I originally posted is -

    // processor boots up and pins are inputs....

    .

    .

       GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_PIN_3) ;

       GPIOPinTypeGPIOOutput(GPIO_PORTM_BASE, GPIO_PIN_3);

    As you can see above we are writing the pin to a 1 and then calling the library function to set the pin as an output, BUT at this point it is DRIVING low.  We also see this same behavior on another pin we are configuring as an open drain output.

    NOTE, the library code for the function GPIOPinTypeGPIOOutput sets the Pad first and then sets the Dir.  I pasted it below -

    GPIOPinTypeGPIOOutput(uint32_t ui32Port, uint8_t ui8Pins) {

        //

        // Check the arguments.

        //

        ASSERT(_GPIOBaseValid(ui32Port));

     

        //

        // Set the pad(s) for standard push-pull operation.

        //

        GPIOPadConfigSet(ui32Port, ui8Pins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);

     

        //

        // Make the pin(s) be outputs.

        //

        GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_OUT); }



    Does our code above look correct to you?  Can you post some sample code that you think works?  Thanks for your help,

    Brett

     

     

     

  • Hello Brett,

    I have a question: If the IO was already low and the configuration is set to High, then there would not be a H->L->H transition if the Pin is configured as output first and then driven high. OR. Is this issue coming on a pad which already has a pull up and the sequence mentioned by you did not affect the state of the IO during the transition?

    Regards
    Amit
  • Hi Amit,

    We have looked at BOTH a GPIO pin that has an external pull up that we configure as open drain, AND a general GPIO pin that is not externally pulled up or down.

    Below are the 2 scenarios we have tested -

    Configuring GPIO line that has an external pull up (~200K) -
    1. Processor resets and all GPIO is tri-state. Our output line can correctly be seen high on the scope.
    2. Before we make this pin an output we write a 1 to the data register.
    3. We configure the pin as an open drain output expecting the line to stay high because of 2.
    4. Unfortunately, after making the pin an output the pin pulls down immediately as if 2 above had no effect.

    Configuring a GPIO line with no external pull up.
    1. Processor resets and all GPIO is tri-state. Our output line can be seen low pulled down by the scope probe.
    2. Before we make this pin an output we write a 1 to the data register.
    3. We configure the pin as a standard output and expect the line to drive high.
    4. Unfortunately, after making the pin an output the pin stays low as if 2. above had no effect.

    The question we have is how are you suppose to switch from a tri-state input (GPIO default) to an output without it driving low.

    I can send you scope traces and the code that generated the scope traces if that would help you.

    Was there a library code version that had this problem? I'm just grasping at straws here.

    Thanks,
    Brett
  • Thanks for you help cb1. I like your WPD idea; unfortunately, I don't think that's it for a few reasons. Originally, we noticed the problem on an output configured as an open drain. The external pull up resistor is about 200K. When you look on the scope the line is pulled down immediately when the port is switched to an output - not what you would expect from a weak pull down. Supposedly, when the chip reboots the pin should not have pull downs or pull ups enabled, and if there was a WPD enabled, it wouldn't be able to pull 200K hard to ground like we're seeing. Again, thanks for your help. We are obviously missing something if indeed it is possible to have glitch free GPIO.
  • Hello Brett,

    Some changes need to be made to the manner in which the GPIO is being configured for this case.

    First of all for the case in which there is an external pull up (200K seems awfully weak).

    First set the GPIODIR bit to 1 for the corresponding Port Pin
    Then set the GPIODATA bit to 1 for the corresponding Port Pin
    Finally set the GPIODEN bit to 1 for the corresponding Port Pin.

    For the second case also do the same step.

    Regards
    Amit
  • Hi Amit,

    We have verified your suggestion works! This is essentially what is recommended by the data sheet section 10.4, but unfortunately the library routines GPIOPinTypeGPIOOutput and GPIOPinTypeGPIOOutputOD can not be used if you want the intial state of your pin to be high.

    To implement your suggestion we bypassed those upper level routines and used the following -
    GPIODirModeSet(GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_DIR_MODE_OUT);
    GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_PIN_3) ;
    GPIOPadConfigSet(GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);

    Also, unfortunately, that order isn't very intuitive, but that just speaks to the fact this is a fairly complicated part.

    Thanks for your help in resolving this problem!

    Brett
  • Brett Preston said:
    unfortunately, that order isn't very intuitive, but that just speaks to the fact this is a fairly complicated part.

    "Isn't very intuitive" (to be extremely) kind.    You Sir, qualify as tech able AND a diplomat...   (some here would argue/propose that such critical tech data should replace the uber important, "Blogs, Groups, Videos" which imposes/infests itself (most always, unwanted) atop each forum page!)

  • Non-intuitive? Inverted from expectations might be closer.

    Robert
  • I'm going to go with 'Works as designed'. Sometimes library code doesn't have the same assumptions you do. In this case you have to fully set the initial state of the pin before you enable the output driver.
  • In the quest of "best description" I propose, "Works as designed, yet inadequately described/detailed."

    The API (should) guard against such "sequence sensitivity" (and often does) yet (unfortunately) hiccups here...
  • Hello cb1,

    I agree with you. The API design should have taken this into consideration, by means of a flag or a new flash API could be made which will set the state w/o glitch. Of course the ROM version shall be unavailable.

    Regards
    Amit
  • Amit Ashara said:
    Of course the ROM version shall be unavailable.  

    And (of course) that's unfortunate.   Users - in the (hope) of saving (some) flash space:

    • preclude themselves from any/all (flash) code updates, bug fixes & improvements
    • soldier on w/"code current (only) when that ROM mask was created"
    • find that "flash savings" is less than hoped for due to new "calling overheads" and the necessity to test to confirm that the function is resident w/in ROM

    Yes the ROM (sometimes) giveth - yet it (too often) taketh away!

    Might the "golden glow" of "ROM benefits" be entering the (same) "down-elevator" as the various "Code-Security Implementations - which never (really) protect?

  • Hello cb1

    A ROM change is performed when there is a new revision. Since there is none planned right now, it has to be a Flash API

    Regards
    Amit
  • One year later...

    I wanted to like this and post a comment here, for I have just faced the same problem and this "awkward" sequence indeed solves the issue.
    Glad I did not have to hand solder a bunch of resistor dividers on my brand new board!!!

    Bruno
  • Was it "just rumor" which reported an, "under-age/undocumented work crüe" - arriving earlier - resistors in hand - and then "scowling/departing?" And - do not most all "brand new boards" bear a full complement of "whoops" component additions & several, "correcting" wire tacks?