Files
Crosspoint/lib/hal/HalPowerManager.h
T
Justin Mitchell c308520f9c Add touch tap gesture for back navigation
Implements a reusable touch tap gesture in the top-left corner that maps to the Back button. The gesture is automatically integrated into wasPressed/wasReleased for Back button, making it available across all screens without per-activity code. Also fixes low-power CPU frequency floor to 80 MHz on PSRAM boards to prevent SD write and PSRAM instability caused by APB clock dropping below safe threshold.
2026-06-08 14:01:30 -04:00

74 lines
2.5 KiB
C++

#pragma once
#include <Arduino.h>
#include <BatteryMonitor.h>
#include <InputManager.h>
#include <Logging.h>
#include <Wire.h>
#include <freertos/semphr.h>
#include <cassert>
#include "HalGPIO.h"
class HalPowerManager;
extern HalPowerManager powerManager; // Singleton
class HalPowerManager {
int normalFreq = 0; // MHz
bool isLowPower = false;
// I2C fuel gauge configuration for X3 battery monitoring
bool _batteryUseI2C = false; // True if using I2C fuel gauge (X3), false for ADC (X4)
mutable int _batteryCachedPercent = 0; // Last read battery percentage (0-100)
mutable unsigned long _batteryLastPollMs = 0; // Timestamp of last battery read in milliseconds
enum LockMode { None, NormalSpeed };
LockMode currentLockMode = None;
SemaphoreHandle_t modeMutex = nullptr; // Protect access to currentLockMode
public:
// On PSRAM boards (classic ESP32 / M5Paper) the APB clock follows the CPU below
// 80 MHz, and APB clocks both the SD SPI bus and the 80 MHz PSRAM (which holds
// the framebuffer). Dropping to 10 MHz breaks SD writes and PSRAM, so floor the
// low-power CPU at 80 MHz (APB stays pinned at 80 for CPU 80/160/240, so power
// still drops from the 240 MHz default while SD/PSRAM stay stable).
#if defined(BOARD_HAS_PSRAM)
static constexpr int LOW_POWER_FREQ = 80; // MHz (APB-safe floor for PSRAM/SD)
#else
static constexpr int LOW_POWER_FREQ = 10; // MHz
#endif
static constexpr unsigned long IDLE_POWER_SAVING_MS = 3000; // ms
static constexpr unsigned long BATTERY_POLL_MS = 1500; // ms
void begin();
// Control CPU frequency for power saving
void setPowerSaving(bool enabled);
// Setup wake up GPIO and enter deep sleep
// Should be called inside main loop() to handle the currentLockMode
void startDeepSleep(HalGPIO& gpio) const;
// Get battery percentage (range 0-100)
uint16_t getBatteryPercentage() const;
// RAII helper class to manage power saving locks
// Usage: create an instance of Lock in a scope to disable power saving, for example when running a task that needs
// full performance. When the Lock instance is destroyed (goes out of scope), power saving will be re-enabled.
class Lock {
friend class HalPowerManager;
bool valid = false;
public:
explicit Lock();
~Lock();
// Non-copyable and non-movable
Lock(const Lock&) = delete;
Lock& operator=(const Lock&) = delete;
Lock(Lock&&) = delete;
Lock& operator=(Lock&&) = delete;
};
};