I solved an annoying problem with a glorious hack...
First, a refresher on my "power off" strategy: It's way simpler and more robust to reboot the MCU to fully reset all memory/state rather than write code to explicitly re-initialize EVERYTHING. So that's how I power off. Reboot the MCU, and MCU enters a "sleep" state by default after some basic initialization. A couple pin input change interrupts can wake the MCU to allow it to decide whether to finish initializing and power everything on, or just go back to sleep if power-on conditions are not met.
This works great for basic power on/off flows because the MCU will stop enabling the load switches for switched power by default when rebooting - they require high signal to power on.
But I have some situations where I need to restart rather than power off. To handle this, I store a value in EEPROM before rebooting, then upon booting I check for that value in EEPROM to decide whether to immediately power on, or go to sleep. But the load switches briefly lose their "enable" signal from the MCU while the MCU reboots, which causes a brief flicker of power interruption to the handset, Bluetooth module, and audio circuitry. This looks/sounds pretty "glitchy" because it causes a flicker on the handset display, backlight turns off for a second until it is turned back on during the startup sequence, and it causes an audio "pop" sometimes.
So my hack is to invert the load switch "enable" signal from the MCU with a transistor so that the load switches are enabled by default unless the MCU explicitly outputs a high signal to disable them. This allows power to remain on while rebooting for a restart. I just had to invert some power on/off logic a bit. Upon booting, I must explicitly disable switched power before entering the sleep state if not powering on immediately.
The downsides to this hack are:
- When initially connecting power to my circuit, the load switches will be immediately enabled (powering on the handset, etc.) for a small fraction of a second before the MCU reaches the point of initialization where it disables switched power. A brief flicker can sometimes be seen on the display.
- Not really a problem because the circuit should have constant power supply in normal usage. It will only completely lose power if disconnected from external power AND the batteries discharge down to the low voltage cutoff protection level (which is below my own "low battery" threshold where the user will have been warned of low battery, then I automatically power off and refuse to power back on until battery voltage increases above a threshold). This power flicker would occur when connecting external power to charge the batteries after they have been fully discharged.
- Some power must be wasted to "hold" the switched power "off" via the transistor.
- I minimized this by using 1M resistors for both the base and collector of the transistor.
I still think it's better than trying to reinitialize without a MCU reboot, which would be a lot of programming effort with a lot of risk of missing something that needs to be reset, which could cause obscure bugs that are hard to diagnose.
BTW - TI does offer a few load switches that are "active low" instead of "active high", which would allow me to get rid of the transistor inverter. However, there are very few "active low" options, and none of them can handle the 12+V I need to switch for the handset.