Merge pull request #113 from jpirnay/fix-x3-boot
fix: x3 boot issue regression (#102)
This commit is contained in:
+24
-9
@@ -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(¤tMa)) {
|
||||
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(¤tMa) && 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;
|
||||
}
|
||||
|
||||
@@ -332,6 +339,14 @@ HalGPIO::WakeupReason HalGPIO::getWakeupReason() const {
|
||||
const auto wakeupCause = esp_sleep_get_wakeup_cause();
|
||||
const auto resetReason = esp_reset_reason();
|
||||
|
||||
// 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.
|
||||
// Short-circuit before isUsbConnected() to skip the BQ27220 I2C probe/retry.
|
||||
if (deviceIsX3() && wakeupCause == ESP_SLEEP_WAKEUP_UNDEFINED && resetReason == ESP_RST_POWERON) {
|
||||
return WakeupReason::PowerButton;
|
||||
}
|
||||
|
||||
const bool usbConnected = isUsbConnected();
|
||||
LOG_DBG("GPIO", "getWakeupReason: wakeupCause=%d, resetReason=%d, usbConnected=%d", static_cast<int>(wakeupCause),
|
||||
static_cast<int>(resetReason), usbConnected);
|
||||
|
||||
+6
-4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user