This commit is contained in:
Justin Mitchell
2026-02-12 18:28:47 -05:00
parent 9a1548189c
commit d4eb089e49
5 changed files with 53 additions and 27 deletions
-8
View File
@@ -9,14 +9,6 @@ HalDisplay::~HalDisplay() {}
void HalDisplay::begin() { einkDisplay.begin(); }
void HalDisplay::setDcPin(int8_t pin) { einkDisplay.setDcPin(pin); }
void HalDisplay::setBusyActiveHigh(bool activeHigh) { einkDisplay.setBusyActiveHigh(activeHigh); }
void HalDisplay::setBwOnly(bool bwOnly) { einkDisplay.setBwOnly(bwOnly); }
void HalDisplay::setControllerType(EInkDisplay::ControllerType type) { einkDisplay.setControllerType(type); }
void HalDisplay::setDisplayDimensions(uint16_t width, uint16_t height) { einkDisplay.setDisplayDimensions(width, height); }
void HalDisplay::clearScreen(uint8_t color) const { einkDisplay.clearScreen(color); }
-4
View File
@@ -21,10 +21,6 @@ class HalDisplay {
void begin();
// Pre-begin display config passthroughs (used by X3 setup path)
void setDcPin(int8_t pin);
void setBusyActiveHigh(bool activeHigh);
void setBwOnly(bool bwOnly);
void setControllerType(EInkDisplay::ControllerType type);
void setDisplayDimensions(uint16_t width, uint16_t height);
// Display dimensions
+29 -5
View File
@@ -1,9 +1,33 @@
#include "Battery.h"
#include <Wire.h>
// Meyer's singleton — guaranteed single instance across all translation units.
// Constructed with GPIO0 (X4 ADC default). For X3, main.cpp calls
// battery().setI2CFuelGauge() to switch to BQ27220 I2C reads instead.
BatteryMonitor& battery() {
static BatteryMonitor instance(BAT_GPIO0);
void BatteryProvider::setI2CFuelGauge(uint8_t i2cAddr, uint8_t socRegister) {
_useI2C = true;
_i2cAddr = i2cAddr;
_socRegister = socRegister;
}
uint16_t BatteryProvider::readPercentage() const {
if (_useI2C) {
// Read SOC directly from I2C fuel gauge (16-bit LE register).
// Returns 0 on I2C error so the UI shows 0% rather than crashing.
Wire.beginTransmission(_i2cAddr);
Wire.write(_socRegister);
if (Wire.endTransmission(false) != 0) return 0;
Wire.requestFrom(_i2cAddr, (uint8_t)2);
if (Wire.available() < 2) return 0;
const uint8_t lo = Wire.read();
const uint8_t hi = Wire.read();
const uint16_t soc = (hi << 8) | lo;
return soc > 100 ? 100 : soc;
}
// ADC path: read raw voltage, apply divider, convert via LiPo polynomial
return _adcMonitor.readPercentage();
}
// Meyer's singleton — single shared instance across all translation units.
// Defaults to X4 ADC mode. For X3, main.cpp calls setI2CFuelGauge() to switch.
BatteryProvider& battery() {
static BatteryProvider instance;
return instance;
}
+24 -6
View File
@@ -1,11 +1,29 @@
#pragma once
#include <BatteryMonitor.h>
#include <cstdint>
#define BAT_GPIO0 0 // Battery voltage (X4 ADC pin)
// Shared battery monitor singleton. Returns a single BatteryMonitor instance
// used by all callers (themes, activities, etc.).
//
// - X4: reads battery voltage via ADC on GPIO0 (default, no extra setup needed)
// - X3: reads SOC from BQ27220 fuel gauge via I2C (call setI2CFuelGauge() after Wire.begin())
BatteryMonitor& battery();
// Unified battery reader supporting two backends:
// - X4: ADC voltage divider on GPIO0 (default, no setup needed)
// - X3: BQ27220 fuel gauge via I2C at 0x55, SOC register 0x2C
// (call setI2CFuelGauge() after Wire.begin())
class BatteryProvider {
public:
// Read battery percentage (0-100). Delegates to ADC or I2C depending on mode.
uint16_t readPercentage() const;
// Switch to I2C fuel gauge mode. Wire.begin() must be called first.
// i2cAddr: fuel gauge I2C address (e.g. 0x55 for BQ27220)
// socRegister: register holding state-of-charge 0-100% (e.g. 0x2C)
void setI2CFuelGauge(uint8_t i2cAddr, uint8_t socRegister);
private:
BatteryMonitor _adcMonitor{BAT_GPIO0};
bool _useI2C = false;
uint8_t _i2cAddr = 0;
uint8_t _socRegister = 0;
};
// Shared singleton used by themes and activities.
BatteryProvider& battery();
-4
View File
@@ -255,10 +255,6 @@ void onGoHome() {
void setupDisplayAndFonts() {
if (gpio.getDeviceType() == HalGPIO::DeviceType::X3) {
display.setDcPin(4);
display.setBusyActiveHigh(false);
display.setBwOnly(true);
display.setControllerType(EInkDisplay::ControllerType::SSD1677);
display.setDisplayDimensions(792, 528);
// X3 has a BQ27220 fuel gauge on I2C (addr 0x55) instead of an ADC voltage
// divider. SOC (0-100%) is read directly from register 0x2C.