ESP32-S2: need to adjust Brown Out Level at runtime
Posted: Sun Feb 04, 2024 2:38 am
This may sound a bit strange (but I'm known to "misuse" things all the time): I need to programmatically change the brown-out detector's setpoint from the application firmware.
In short: I have a short-term power backup system from a 3.0v ultracapacitor, followed by a boost converter. (The ESP32-S2 shuts off the boost converter after running shutdown tasks comprising several seconds...but the boost chip does not have a disconnect functionality, so this shutdown does not totally disconnect power to the ESP32-S2. Instead, the ESP32-S2 VDD will drop to ~2.9v, and then slowly drop to zero as the capacitor discharges over the next few minutes.)
The default ESP32-S2 brown-out voltage is perfectly fine for normal operation, where the WiFi/normal operation power spikes can easily cause brief transients on the VDD line--I am not having any issues with processor malfunction or unexpected brown-out resets. As a result, I do not want to change the DEFAULT brown-out voltage (then risking system instability). (My assumption is that this is ~2.43v, which is perfectly fine.)
The problem starts when the ESP32-S2 shuts down the boost converter. When this happens, the ESP32-S2 VDD is going to abruptly drop to <2.7v...but any capacitor/battery voltage will slowly rise after a large load has been disconnected. This has a serious potential to play "blinky lights" with the ESP32-S2's brown-out detector: when the ESP32-S2 is held in brown-out reset, the capacitor voltage will slowly rise until it is above the brown-out threshold...then the ESP32-S2 will start up (= pulling more power) and soon brown out again. Ad infinitum until the capacitor eventually discharges below the ESP32-S2 brown-out threshold.
However, if I programmatically set the brown-out detector threshold to 3.19v right before shutting off the boost converter (remember, the ultracap is 3.0v max), the ESP32-S2 is guaranteed to be held in brown-out reset until VDD reaches 3.30v. That will only happen when main power has been restored--and the resulting brown-out reset will reboot the ESP32-S2 with default configs, setting the brown-out detector back to the default (2.43v?)
In the ESP32-S2 Technical Reference Manual v1.1, I found the following info on page 273: Section 9.3.4.4 Brownout Detector (sorry, don't know how to embed images here, so I copied it):
It's not like the brown-out detector's setpoint is in eFuse, so it's not like there's hardware limitations for changing this brown-out detector voltage reference.
How do I change the brown-out detector voltage threshold at runtime?
In short: I have a short-term power backup system from a 3.0v ultracapacitor, followed by a boost converter. (The ESP32-S2 shuts off the boost converter after running shutdown tasks comprising several seconds...but the boost chip does not have a disconnect functionality, so this shutdown does not totally disconnect power to the ESP32-S2. Instead, the ESP32-S2 VDD will drop to ~2.9v, and then slowly drop to zero as the capacitor discharges over the next few minutes.)
The default ESP32-S2 brown-out voltage is perfectly fine for normal operation, where the WiFi/normal operation power spikes can easily cause brief transients on the VDD line--I am not having any issues with processor malfunction or unexpected brown-out resets. As a result, I do not want to change the DEFAULT brown-out voltage (then risking system instability). (My assumption is that this is ~2.43v, which is perfectly fine.)
The problem starts when the ESP32-S2 shuts down the boost converter. When this happens, the ESP32-S2 VDD is going to abruptly drop to <2.7v...but any capacitor/battery voltage will slowly rise after a large load has been disconnected. This has a serious potential to play "blinky lights" with the ESP32-S2's brown-out detector: when the ESP32-S2 is held in brown-out reset, the capacitor voltage will slowly rise until it is above the brown-out threshold...then the ESP32-S2 will start up (= pulling more power) and soon brown out again. Ad infinitum until the capacitor eventually discharges below the ESP32-S2 brown-out threshold.
However, if I programmatically set the brown-out detector threshold to 3.19v right before shutting off the boost converter (remember, the ultracap is 3.0v max), the ESP32-S2 is guaranteed to be held in brown-out reset until VDD reaches 3.30v. That will only happen when main power has been restored--and the resulting brown-out reset will reboot the ESP32-S2 with default configs, setting the brown-out detector back to the default (2.43v?)
In the ESP32-S2 Technical Reference Manual v1.1, I found the following info on page 273: Section 9.3.4.4 Brownout Detector (sorry, don't know how to embed images here, so I copied it):
Unfortunately, I haven't been able to find anything about this register anywhere else on the entire Internet. Heck, this post here likely will become the #1 Google search result simply by default! The closest I was able to find to the subject was this GitHub issue, which did indicate that it's set by the bootloader: https://github.com/espressif/arduino-esp32/issues/2580I2C register ULP_CAL_REG5[2:0] configures the trigger threshold of the brown-out detector;
Table 63: Brownout Detector Configuration
* ULP_CAL_REG5[2:0] - VDD (Unit: V)
* 0 - 2.67
* 1 - 3.30
* 2 - 3.19
* 3 - 2.98
* 4 - 2.84
* 5 - 2.67
* 6 - 2.56
* 7 - 2.44
It's not like the brown-out detector's setpoint is in eFuse, so it's not like there's hardware limitations for changing this brown-out detector voltage reference.
How do I change the brown-out detector voltage threshold at runtime?