fixes battery reading on x3

This commit is contained in:
Justin Mitchell
2026-02-12 16:55:27 -05:00
parent cbea838f91
commit 9a1548189c
6 changed files with 28 additions and 9 deletions
+2 -3
View File
@@ -44,11 +44,10 @@ void HalGPIO::startDeepSleep() {
int HalGPIO::getBatteryPercentage() const {
if (_deviceType == DeviceType::X3) {
// X3 battery telemetry is not on ADC in stock fw; avoid fighting EPD DC on GPIO4.
return 0;
}
static const BatteryMonitor battery = BatteryMonitor(BAT_GPIO0);
return battery.readPercentage();
static const BatteryMonitor bat(BAT_GPIO0);
return bat.readPercentage();
}
bool HalGPIO::isUsbConnected() const {
+9
View File
@@ -0,0 +1,9 @@
#include "Battery.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);
return instance;
}
+7 -2
View File
@@ -1,6 +1,11 @@
#pragma once
#include <BatteryMonitor.h>
#define BAT_GPIO0 0 // Battery voltage
#define BAT_GPIO0 0 // Battery voltage (X4 ADC pin)
static BatteryMonitor battery(BAT_GPIO0);
// 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();
+2 -2
View File
@@ -22,7 +22,7 @@ constexpr int homeMarginTop = 30;
void BaseTheme::drawBattery(const GfxRenderer& renderer, Rect rect, const bool showPercentage) const {
// Left aligned battery icon and percentage
// TODO refactor this so the percentage doesnt change after we position it
const uint16_t percentage = battery.readPercentage();
const uint16_t percentage = battery().readPercentage();
if (showPercentage) {
const auto percentageText = std::to_string(percentage) + "%";
renderer.drawText(SMALL_FONT_ID, rect.x + batteryPercentSpacing + BaseMetrics::values.batteryWidth, rect.y,
@@ -232,7 +232,7 @@ void BaseTheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* t
SETTINGS.hideBatteryPercentage != CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_ALWAYS;
int batteryX = rect.x + rect.width - BaseMetrics::values.contentSidePadding - BaseMetrics::values.batteryWidth;
if (showBatteryPercentage) {
const uint16_t percentage = battery.readPercentage();
const uint16_t percentage = battery().readPercentage();
const auto percentageText = std::to_string(percentage) + "%";
batteryX -= renderer.getTextWidth(SMALL_FONT_ID, percentageText.c_str());
}
+2 -2
View File
@@ -22,7 +22,7 @@ constexpr int topHintButtonY = 345;
void LyraTheme::drawBattery(const GfxRenderer& renderer, Rect rect, const bool showPercentage) const {
// Left aligned battery icon and percentage
const uint16_t percentage = battery.readPercentage();
const uint16_t percentage = battery().readPercentage();
if (showPercentage) {
const auto percentageText = std::to_string(percentage) + "%";
renderer.drawText(SMALL_FONT_ID, rect.x + batteryPercentSpacing + LyraMetrics::values.batteryWidth, rect.y,
@@ -64,7 +64,7 @@ void LyraTheme::drawHeader(const GfxRenderer& renderer, Rect rect, const char* t
SETTINGS.hideBatteryPercentage != CrossPointSettings::HIDE_BATTERY_PERCENTAGE::HIDE_ALWAYS;
int batteryX = rect.x + rect.width - LyraMetrics::values.contentSidePadding - LyraMetrics::values.batteryWidth;
if (showBatteryPercentage) {
const uint16_t percentage = battery.readPercentage();
const uint16_t percentage = battery().readPercentage();
const auto percentageText = std::to_string(percentage) + "%";
batteryX -= renderer.getTextWidth(SMALL_FONT_ID, percentageText.c_str());
}
+6
View File
@@ -5,6 +5,7 @@
#include <HalGPIO.h>
#include <HalStorage.h>
#include <SPI.h>
#include <Wire.h>
#include <builtinFonts/all.h>
#include <cstring>
@@ -259,6 +260,11 @@ void setupDisplayAndFonts() {
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.
// I2C bus: SDA=GPIO20, SCL=GPIO0, 400kHz (matches stock X3 firmware).
Wire.begin(20, 0, 400000);
battery().setI2CFuelGauge(0x55, 0x2C);
}
display.begin();
renderer.begin();