Why would you enable pullup for a GPIO pin in push-pull mode?

Just like the pull-up, the reason to do this is a bit weak. Is it wrong to do this? Certainly not. Should you do this though? Possibly. Does it make much sense for a code example that is doing nothing but flashing an LED? Not really.

This series of ST microcontrollers have their pull-up and pull-down resistors controlled completely independently from anything else, allowing you to indeed do current-wasting configurations like this one, where the pull-up will do nothing when the pin is high, and will waste maybe a hundred µA or two of current (still without doing anything) when low.

There is a reason one might wish to do this, and it is simply to ensure the pin will be pulled to a default state if the mode is changed away from push-pull mode later. While it is true that neither the pull-up or pull-down resistors serve any purpose in push-pull mode, the pull-up resistor at least is likely desirable in all other modes: open-drain, and input. So if you aren't counting every µA, and might be changing the roles of certain pins, it can make sense to leave the pull-up turned on all the time, just to ensure that the pin will never get floated by accident or otherwise glitch when the pin mode of the GPIO pin is switched to something other than push-pull. Indeed, any time you had a pin in push-pull mode and needed to switch it to open-drain or an input mode, you would probably activate the pull-up resistor before actually switching to that mode, so the ability to have the pull-up resistor turned on even when in push-pull mode is certainly useful and important. It is needed to prevent glitching when changing the pin to input or open drain, depending on what is connected to it of course.

Now, it is definitely an odd choice to use it in an example like they have. Just to be absolutely clear, one could (and arguably should in most cases) set GPIO_InitStruct.Pull to GPIO_NOPULL when using the pin in push-pull mode.

Of course, if you do that, you will have to remember to turn on a pull-up or pull-down resistor (if there isn't an external one) should you change the pin mode to something other than push-pull. Perhaps ST is just playing it safe and assuming someone blinking an LED will stand a good chance of overlooking this, at least initially. Or maybe it was just a small oversight. Regardless, it certainly serves no real purpose in the example shown and because of that, I feel it mostly just confuses the point of the documentation here.

Which is why you've come to stack exchange to even ask this question. Maybe someone from ST will update the PDF after reading this. In my opinion, they should, as it is clearly confusing people and that is the last thing one would want documentation to do.

Beyond that, don't read too much into it. You'll run across little oddities like this fairly regularly, but don't start second guessing yourself each time it happens. I think most of us probably like to pretend all our datasheets and documentation and application notes are error-free, with every line of example code and every sentence purposeful and well thought-out. But we're all human, and as long as humans are still writing datasheets and documentation, sometimes you'll find mistakes. Many mistakes you'll come across are relatively benign and result in something that is merely a little strange or unnecessary like this example. These are also the ones that often never get corrected, simply because it doesn't really matter that much and no one can be bothered.

How I handled specific code oddity, and a good way to handle something like this in the future is to consult the actual datasheet of the chip in question. Understand how the port physically works, and then you'll be confident enough that there isn't really a reason to turn on the pull-up in that situation and not worry about it. If you understand how the chip functions, that's all you need. You'll be able to spot, rather than be at the mercy of, any weirdness contained in any example code for the chip, regardless of who wrote it.


From STM32L4x5 and STM32L4x6 RM0351 - Reference manual.

A GPIO can have the following modes:

  • Input floating
  • Input pull-up
  • Input pull-down
  • Analog
  • Output open-drain with pull-up or pull-down capability
  • Output push-pull with pull-up or pull-down capability
  • Alternate function push-pull with pull-up or pull-down capability
  • Alternate function open-drain with pull-up or pull-down capability

Weak 40kΩ pull-ups and pull-downs make no sense for a push/pull output capable of sinking/sourcing 25mA (impact is only 0.125mA at 5V). But this assumes the GPIO pin will not change it's mode.

Any GPIO pin can transition from one mode to another. An input can become an output and vice versa. Bidirectional and multi purpose pins.

Note all the output and alternate modes have pull-up and pull-down capability, while input is divided into three categories (floating, pull-up and pull-down). Why would you need an open-drain output with pull-down capability?

To avoid GPIOs floating as a pin transitions from output to input, pull-ups and pull-downs are provided on all outputs to set inputs to a default or off state.

If the GPIO pin will not ever change it's mode, configure with NOPULL.