How I fixed a stuck-low button input on the G070 - check the UCPD strobe

Oct 30, 2026 Last reply: 1 day ago 3 Replies

First reply

HollowWren120

Ran into the exact same trap on a G0B1 last year, except mine was PA8 driving an interrupt line from a sensor board. The pin whould idle low through a 10k pull-up I'd fitted on the breakout, and I burned two evenings convinced the sensor was holding the line down. Desoldered…

Read the full reply

Lost a whole evening to this one last month, so here it is in case it saves someone else the pain. I had a pushbutton on PB15 configured as plain input with the internal pull-up, and it read low constantly no matter what. Swapped buttons, checked continuity, even tried a different board. Nothing. The catch with the G0 series is that some pins get a pull-down enabled right out of reset depending on the state of their neighbouring pins, and PB15 is one of them. It's part of the USB Type-C dead battery support, which is completely irrelevant if you're not using USB, but the hardware doesn't care. So your nice pull-up gets fought by a hidden pull-down and the pin just sits low.



The fix is one line in your init before you touch GPIO clocks. Turn on the SYSCFG clock, then set the UCPD1 strobe bit in SYSCFG_CFGR1. That releases the hidden pull-down and PB15 suddenly behaves like a normal input. Set your pull-up after that and you're done. Worth reading the errata or the reference manual section on SYSCFG if you're on this family, because PA8, PD0 and PD2 can have the same issue. It's the kind of thing you only find after an hour of doubting your own soldering.


Ran into the exact same trap on a G0B1 last year, except mine was PA8 driving an interrupt line from a sensor board. The pin whould idle low through a 10k pull-up I'd fitted on the breakout, and I burned two evenings convinced the sensor was holding the line down. Desoldered the sensor, measured the trace, tried a second MCU board. Same result every time.

What finally cracked it for me was the register view in STM32CubeIDE. I was poking around one night and noticed the pull-down bit for PA8 sitting at 1 even though my init code never set it. That sent me to the reference manual and then the errata sheet, where the whole UCPD default state thing is spelled out. Genuinely felt like the chip was gaslighting me up to that point.

For anyone who wants a hardware workaround instead of the one-liner, a reasonably strong external pull-up will also win the fight. I've since used 4k7 on these pins with no trouble. But honestly the SYSCFG write is cleaner, and I've made it a fixed step in my board init template now for every G0 project, wether or not I think the pin is affected.

Also worth checking with a debugger if you're unsure. Reset the chip, halt before your init runs, and read the GPIO pull registers directly. Seeing those stray bits set with your own eyes beats guessing.

This is eerie timing because my breadboard button has been doing the same thing and I was about to bin the whole row of the board thinking it was broken. Swapped wires, tried another pin hole, nothing. So basicly there's a tiny second resistor inside the chip pulling the pin down that turns itself on at power up, and you have to tell the chip to turn it off first. My question is, does that setting stick if the board loses power, or does the code have to do it again every single time it boots?

Same deal here but on a knockoff blue pill style board I used for a one-off gate controller, pin never came up until I added that syscfg write. What got me was how the button only started working after I reflashed, so I kept blaming my wiring for days. Now I just copy that init line into every project before anything else, saved me more than once since. Still not sure why the datasheet buries something like that so deep.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required