feat: Add touch coordinate mapping and RTOS task yielding (#2481)
Co-authored-by: Julia Nguyen <julia@uxj.io>
This commit is contained in:
co-authored by
Julia Nguyen
parent
c9188a7347
commit
f42fab1c66
+35
-50
@@ -1,8 +1,11 @@
|
||||
#include "HalPowerManager.h"
|
||||
|
||||
#include <BoardConfig.h>
|
||||
#include <Logging.h>
|
||||
#include <PowerManager.h>
|
||||
#include <WiFi.h>
|
||||
#include <esp_sleep.h>
|
||||
#include <soc/soc_caps.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
@@ -11,14 +14,8 @@
|
||||
HalPowerManager powerManager; // Singleton instance
|
||||
|
||||
void HalPowerManager::begin() {
|
||||
if (gpio.deviceIsX3()) {
|
||||
// X3 uses an I2C fuel gauge for battery monitoring.
|
||||
// I2C init must come AFTER gpio.begin() so early hardware detection/probes are finished.
|
||||
Wire.begin(X3_I2C_SDA, X3_I2C_SCL, X3_I2C_FREQ);
|
||||
Wire.setTimeOut(4);
|
||||
_batteryUseI2C = true;
|
||||
} else {
|
||||
pinMode(BAT_GPIO0, INPUT);
|
||||
if (BoardConfig::ACTIVE.batteryAdc >= 0) {
|
||||
pinMode(BoardConfig::ACTIVE.batteryAdc, INPUT);
|
||||
}
|
||||
normalFreq = getCpuFrequencyMhz();
|
||||
modeMutex = xSemaphoreCreateMutex();
|
||||
@@ -61,12 +58,6 @@ void HalPowerManager::setPowerSaving(bool enabled) {
|
||||
}
|
||||
|
||||
void HalPowerManager::startDeepSleep(HalGPIO& gpio) const {
|
||||
// Ensure that the power button has been released to avoid immediately turning back on if you're holding it
|
||||
while (gpio.isPressed(HalGPIO::BTN_POWER)) {
|
||||
delay(50);
|
||||
gpio.update();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SERIAL_LOG
|
||||
// Tear down HWCDC so the host sees a clean disconnect and the peripheral
|
||||
// doesn't hold power domains that interfere with USB-powered GPIO wake.
|
||||
@@ -75,53 +66,47 @@ void HalPowerManager::startDeepSleep(HalGPIO& gpio) const {
|
||||
logSerial.end();
|
||||
#endif
|
||||
|
||||
// Pre-sleep routines from the original firmware
|
||||
// GPIO13 is connected to battery latch MOSFET, we need to make sure it's low during sleep
|
||||
// Note that this means the MCU will be completely powered off during sleep, including RTC
|
||||
constexpr gpio_num_t GPIO_SPIWP = GPIO_NUM_13;
|
||||
gpio_set_direction(GPIO_SPIWP, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(GPIO_SPIWP, 0);
|
||||
esp_sleep_config_gpio_isolate();
|
||||
gpio_deep_sleep_hold_en();
|
||||
gpio_hold_en(GPIO_SPIWP);
|
||||
pinMode(InputManager::POWER_BUTTON_PIN, INPUT_PULLUP);
|
||||
// Arm the wakeup trigger *after* the button is released
|
||||
// Note: this is only useful for waking up on USB power. On battery, the MCU will be completely powered off, so the
|
||||
// power button is hard-wired to briefly provide power to the MCU, waking it up regardless of the wakeup source
|
||||
// configuration
|
||||
esp_deep_sleep_enable_gpio_wakeup(1ULL << InputManager::POWER_BUTTON_PIN, ESP_GPIO_WAKEUP_GPIO_LOW);
|
||||
// Enter Deep Sleep
|
||||
esp_deep_sleep_start();
|
||||
#if !SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||
if (gpio.isXteinkDevice() && !gpio.deviceIsX3()) {
|
||||
// X4 GPIO13 is connected to the battery latch MOSFET. Keeping it low powers
|
||||
// the MCU off on battery, while the SDK wake source still handles USB power.
|
||||
constexpr gpio_num_t GPIO_SPIWP = GPIO_NUM_13;
|
||||
gpio_set_direction(GPIO_SPIWP, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(GPIO_SPIWP, 0);
|
||||
gpio_hold_en(GPIO_SPIWP);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Cut the gated peripheral rails (touch/SD/EPD on boards like the Sticky) and
|
||||
// hold the enables off through deep sleep — otherwise the GT911 and SD card
|
||||
// stay powered all through "off" and drain the battery. No-op on boards with
|
||||
// no switched rails (X4/X3). Trade-off: no touch-to-wake; wake is the power
|
||||
// button. Must run after display.deepSleep() so the panel controller gets its
|
||||
// deep-sleep command while its rail is still up (enterDeepSleep() in main.cpp
|
||||
// guarantees that ordering).
|
||||
freeink::PowerManager::powerDownRailsForSleep();
|
||||
|
||||
// Waits for the power button to be physically released (so holding it doesn't
|
||||
// immediately wake the device again), then arms the wake source and sleeps.
|
||||
freeink::PowerManager::deepSleepUntilPowerButton();
|
||||
}
|
||||
|
||||
uint16_t HalPowerManager::getBatteryPercentage() const {
|
||||
if (_batteryUseI2C) {
|
||||
static const BatteryMonitor battery;
|
||||
if (BoardConfig::ACTIVE.batteryGauge.gaugeAddr != 0) {
|
||||
const unsigned long now = millis();
|
||||
if (_batteryLastPollMs != 0 && (now - _batteryLastPollMs) < BATTERY_POLL_MS) {
|
||||
return _batteryCachedPercent;
|
||||
}
|
||||
|
||||
// Read SOC directly from I2C fuel gauge (16-bit LE register).
|
||||
// On I2C error, keep last known value to avoid UI jitter/slowdowns.
|
||||
Wire.beginTransmission(I2C_ADDR_BQ27220);
|
||||
Wire.write(BQ27220_SOC_REG);
|
||||
if (Wire.endTransmission(false) != 0) {
|
||||
_batteryLastPollMs = now;
|
||||
return _batteryCachedPercent;
|
||||
}
|
||||
Wire.requestFrom(I2C_ADDR_BQ27220, (uint8_t)2);
|
||||
if (Wire.available() < 2) {
|
||||
_batteryLastPollMs = now;
|
||||
return _batteryCachedPercent;
|
||||
}
|
||||
const uint8_t lo = Wire.read();
|
||||
const uint8_t hi = Wire.read();
|
||||
const uint16_t soc = (hi << 8) | lo;
|
||||
_batteryCachedPercent = soc > 100 ? 100 : soc;
|
||||
_batteryLastPollMs = now;
|
||||
uint16_t percent = 0;
|
||||
if (!battery.readPercentageChecked(percent)) {
|
||||
return _batteryCachedPercent;
|
||||
}
|
||||
_batteryCachedPercent = percent;
|
||||
return _batteryCachedPercent;
|
||||
}
|
||||
static const BatteryMonitor battery = BatteryMonitor(BAT_GPIO0);
|
||||
|
||||
// smooth the battery %.
|
||||
if (_batteryCachedPercent == 0) {
|
||||
|
||||
Reference in New Issue
Block a user