When designing electronics, occasionally a bug will catch me by surprise. In one of our current projects, a low-power stand-by mode is required. The lower the current, the longer the battery life, so work through all possibilities: switch the processor from a high-speed clock to the low-speed real-time-clock crystal at 32KHz; disable all processor internal devices like ADCs, timers, UARTs; place communication modules like Bluetooth Low Energy devices in deep-sleep states; ensure no pull-up/down resistor is biased; block paths to switching regulator feedback resistor networks; watch out for floating pins.
With no connection to an input, especially one made of high input impedance FETs (all modern processors), just about any signal can bias it a little, partially turning on internal transistors, producing a path through which current can flow. If it’s a GPIO pin, these are by definition bidirectional. Setting the GPIO direction to an output will prevent this unwanted biasing problem, but it will potentially increase standby current a little more than if the pin were an input with a pull-up/pull-down resistor on it.
So what’s the bug? A GPIO pin driving a LED is made an output during normal processor operation. When putting the processor into sleep mode, since there is a pull-up on this pin, the more desirable pulled-up input configuration can be exploited for a little power savings. Just before putting the processor to sleep, this pin is converted to an input; the circuit becomes what is shown in the above sketch. What could go wrong? LEDs have an undocumented feature: run current through them, and they light up; but, shine a bright light on them, and they develop a bias voltage. The transfer of light to current is very poor, so circuit function is barely affected; but in this case, the FET input impedance is so high that the bias voltage can lower the voltage on the GPIO input.
The circuit shown inverts its input, so the bottom transistor is on, and the top one is off. When light hits the LED, the voltage at its cathode drops below VDD, weakly enabling the top transistor, allowing a little current to flow from VDD through both transistors to ground. It’s light sensitive too, which is how it was discovered. This was a little comical, as every time I brought a probe near it, the shade from my own hand would cover the LED, and the current would drop; move away, and it would rise.