Skip to content

Commit 27663ea

Browse files
lovyan03ainyan03
authored andcommitted
Merge pull request #375 from ainyan03/core2v11_ext_off
Power: Core2 v1.1 suspend the DCDC under-voltage power-off while disabling the external output (cherry picked from commit 784e58a)
1 parent 4ca1673 commit 27663ea

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

src/utility/Power_Class.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ namespace m5
9696
/// switch-over), and enabling without a battery may block for up to 1 s while the protection check
9797
/// waits for the TS reading to settle. The switch-over is serialized with setUsbOutput and the
9898
/// internal speaker enable, so those may wait for it as well.
99+
/// @note Core2 v1.1 (AXP2101; a Tough with the AXP2101 takes the same path): disabling
100+
/// the output while powered from USB with no battery makes the ESP32 brownout and
101+
/// reset (the board's VBUS-to-bus switch closes before the boost stops and the
102+
/// transient pulls VSYS down). The PMIC stays on and the board reboots with the
103+
/// output enabled again, so a sketch that unconditionally disables it at startup
104+
/// will reboot in a loop on such a unit. With a battery, or with 5 V supplied on
105+
/// the bus, the transition itself does not disturb the board. Disabling an enabled
106+
/// output blocks for about 20 ms while the PMIC's DCDC under-voltage power-off is
107+
/// suspended; the output is left untouched when that protection cannot be suspended.
99108
void setExtOutput(bool enable, ext_port_mask_t port_mask = (ext_port_mask_t)0xFF);
100109

101110
/// deprecated : Change to "setExtOutput"

src/utility/Power_Class.inl

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,10 @@ namespace m5
858858
// , 0x18, 0x0E
859859
};
860860
Axp2101.writeRegister8Array(reg_data_array, sizeof(reg_data_array));
861+
// Re-arm the DCDC1/DCDC3 under-voltage power-off that setExtOutput(false)
862+
// suspends; an ESP32 brownout reset during that call skips the restore.
863+
// Forced like the table above: these bits are the chip default.
864+
Axp2101.bitOn(0x23, 0x05);
861865

862866
// for Core2 v1.1 (AXP2101+INA3221)
863867
if (Ina3221[0].begin())
@@ -1189,7 +1193,41 @@ namespace m5
11891193
if (_pmic == pmic_axp2101) {
11901194
cancel = (enable && (Ina3221[0].getShuntVoltage(0) < 0.0f || Ina3221[0].getShuntVoltage(1) < 0.0f) && (8 >= Axp2101.getBatteryLevel()));
11911195
if (!cancel) {
1192-
Axp2101.setBLDO2(enable * 3300);
1196+
if (enable) {
1197+
Axp2101.setBLDO2(3300);
1198+
break;
1199+
}
1200+
// Core2 v1.1: BLDO2 drives both the boost enable and the /EN of the
1201+
// switch that ties USB VBUS to the 5V bus. While BLDO2 falls the switch
1202+
// closes before the boost stops, and the boost output feeds back into
1203+
// VBUS -> PMIC -> boost. With no battery this sags VSYS and the AXP2101
1204+
// powers off on DCDC under-voltage (latched until the power key).
1205+
// Suspending that power-off for the transition turns it into an ESP32
1206+
// brownout reset instead; begin() re-arms it after such a reset.
1207+
// (A Tough with the AXP2101 shares this path; the suspend is harmless there.)
1208+
uint8_t r90, r23 = 0;
1209+
if (!Axp2101.readRegister(0x90, &r90, 1)) { r90 = 0xFF; } // unreadable: assume a transition
1210+
bool transition = (r90 & (1 << 5)) != 0;
1211+
bool suspended = false;
1212+
if (transition) {
1213+
// Fail closed: when the power-off cannot be suspended the output is left as is.
1214+
if (!Axp2101.readRegister(0x23, &r23, 1)) {
1215+
ESP_LOGW("Power", "setExtOutput(false): protection register unreadable, refused.");
1216+
break;
1217+
}
1218+
suspended = (r23 & 0x05) != 0;
1219+
if (suspended && !Axp2101.writeRegister8(0x23, r23 & ~0x05)) {
1220+
ESP_LOGW("Power", "setExtOutput(false): could not suspend the DCDC UVP power-off, refused.");
1221+
break;
1222+
}
1223+
}
1224+
Axp2101.setBLDO2(0);
1225+
if (suspended) {
1226+
m5gfx::delay(20); // the transition completes within 10 ms (measured)
1227+
if (!Axp2101.writeRegister8(0x23, r23)) {
1228+
ESP_LOGW("Power", "setExtOutput(false): DCDC UVP power-off not re-armed.");
1229+
}
1230+
}
11931231
break;
11941232
}
11951233
} else {

0 commit comments

Comments
 (0)