Fix x3 boot issue

This commit is contained in:
jpirnay
2026-04-20 17:33:46 +02:00
parent a7638bb7d3
commit 9f95567212
2 changed files with 29 additions and 13 deletions
+23 -9
View File
@@ -309,22 +309,29 @@ void HalGPIO::verifyPowerButtonWakeup(uint16_t requiredDurationMs, bool shortPre
bool HalGPIO::isUsbConnected() const {
if (deviceIsX3()) {
// X3: infer USB/charging via BQ27220 Current() register (0x0C, signed mA).
// Positive current means charging.
// X3: GPIO20 is repurposed as I2C SDA, so the X4 pin-level USB detect is
// unusable here — the I2C pull-ups would always report HIGH. Probe the
// BQ27220 fuel gauge instead. Using just Current() mis-reports "not
// connected" when the battery is full (current ~= 0 mA); combine it with
// the Flags() DSG bit so we report true whenever the charger is present
// (DSG=0 means charging or fully charged, not discharging).
for (uint8_t attempt = 0; attempt < 2; ++attempt) {
int16_t currentMa = 0;
if (X3GPIO::readBQ27220CurrentMA(&currentMa)) {
if (currentMa > 0) {
uint16_t flags = 0;
if (X3GPIO::readI2CReg16LE(I2C_ADDR_BQ27220, BQ27220_FLAGS_REG, &flags)) {
if ((flags & BQ27220_FLAG_DSG) == 0) {
return true;
}
break;
int16_t currentMa = 0;
if (X3GPIO::readBQ27220CurrentMA(&currentMa) && currentMa > 0) {
return true;
}
return false;
}
delay(2);
}
// Fall back to the same USB pin-level detection used by X4.
return digitalRead(UART0_RXD) == HIGH;
return false;
}
// U0RXD/GPIO20 reads HIGH when USB is connected
// X4: U0RXD/GPIO20 reads HIGH when USB is connected
return digitalRead(UART0_RXD) == HIGH;
}
@@ -336,6 +343,13 @@ HalGPIO::WakeupReason HalGPIO::getWakeupReason() const {
LOG_DBG("GPIO", "getWakeupReason: wakeupCause=%d, resetReason=%d, usbConnected=%d", static_cast<int>(wakeupCause),
static_cast<int>(resetReason), usbConnected);
// X3: USB alone cannot cold-boot the MCU — the battery-latch MOSFET must be
// closed by a physical power-button press. So any POWERON reset on X3 is a
// button press, regardless of whether USB happens to be plugged in as well.
if (deviceIsX3() && wakeupCause == ESP_SLEEP_WAKEUP_UNDEFINED && resetReason == ESP_RST_POWERON) {
return WakeupReason::PowerButton;
}
if ((wakeupCause == ESP_SLEEP_WAKEUP_UNDEFINED && resetReason == ESP_RST_POWERON && !usbConnected) ||
(wakeupCause == ESP_SLEEP_WAKEUP_GPIO && resetReason == ESP_RST_DEEPSLEEP && usbConnected)) {
return WakeupReason::PowerButton;
+6 -4
View File
@@ -23,10 +23,12 @@
#define X3_I2C_FREQ 400000
// TI BQ27220 Fuel gauge I2C
#define I2C_ADDR_BQ27220 0x55 // Fuel gauge I2C address
#define BQ27220_SOC_REG 0x2C // StateOfCharge() command code (%)
#define BQ27220_CUR_REG 0x0C // Current() command code (signed mA)
#define BQ27220_VOLT_REG 0x08 // Voltage() command code (mV)
#define I2C_ADDR_BQ27220 0x55 // Fuel gauge I2C address
#define BQ27220_SOC_REG 0x2C // StateOfCharge() command code (%)
#define BQ27220_CUR_REG 0x0C // Current() command code (signed mA)
#define BQ27220_VOLT_REG 0x08 // Voltage() command code (mV)
#define BQ27220_FLAGS_REG 0x0A // BatteryStatus() / Flags() command code (bit0=DSG)
#define BQ27220_FLAG_DSG 0x0001 // DSG bit: 1 = discharging, 0 = charging or at rest
// Analog DS3231 RTC I2C
#define I2C_ADDR_DS3231 0x68 // RTC I2C address