Skip to content

Commit 70194c6

Browse files
3rdIterationclaude
andcommitted
fix: tdeck battery meter accuracy and usb/charging detection
- Average 8 adc samples and use a 2.11 divider multiplier (2.0 nominal plus ~10% load correction, matching other t-deck firmwares) instead of a single noisy sample scaled by 2. - usb/charging detection used tud_mounted(), which is always false on the debug (usb-serial-jtag) build where TinyUSB is never initialised; infer usb connection from usb_serial_jtag_is_connected() there. - Report charging as usb present while below 4300mV - with no charger status line, a higher reading means the charger is holding up the sense node with the battery full. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent e4c56a9 commit 70194c6

1 file changed

Lines changed: 44 additions & 16 deletions

File tree

main/power/tdeck.inc

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
#include <esp_adc/adc_oneshot.h>
88
#include <esp_sleep.h>
99

10+
#ifdef CONFIG_JADE_USE_USB_JTAG_SERIAL
11+
#include <driver/usb_serial_jtag.h>
12+
#else
1013
#include "tusb.h"
14+
#endif
1115

1216
#define BOARD_POWERON_GPIO 10
1317
#define BACKLIGHT_GPIO 42
@@ -18,8 +22,29 @@ void tdeck_set_keyboard_backlight(uint8_t value);
1822

1923
#define BATTERY_ADC_CHANNEL ADC_CHANNEL_3
2024
#define BATTERY_ADC_ATTEN ADC_ATTEN_DB_12
25+
#define BATTERY_ADC_SAMPLES 8
2126
#define BATTERY_EMA_ALPHA 0.3f
2227

28+
// Voltage divider ratio is 2.0 (100k/100k) plus ~10% correction for
29+
// undervoltage while the display loads the rail (as per other t-deck
30+
// firmwares, eg. meshtastic)
31+
#define BATTERY_VDIV_MULTIPLIER 2.11f
32+
33+
// Above this the sense node is being held up by the charger with the
34+
// battery full (charge terminated) rather than actively charging
35+
#define BATTERY_CHARGED_MILLIVOLTS 4300
36+
37+
static bool usb_connected(void)
38+
{
39+
#ifdef CONFIG_JADE_USE_USB_JTAG_SERIAL
40+
// TinyUSB is not initialised in this mode - infer usb connection
41+
// from the usb-serial-jtag peripheral instead
42+
return usb_serial_jtag_is_connected();
43+
#else
44+
return tud_mounted() && !tud_suspended();
45+
#endif
46+
}
47+
2348
static adc_oneshot_unit_handle_t adc1_handle = NULL;
2449
static adc_cali_handle_t adc1_cali_chan0_handle = NULL;
2550
static float ema_voltage = 0.0f;
@@ -121,16 +146,26 @@ esp_err_t power_camera_off(void) { return ESP_OK; }
121146
uint16_t power_get_vbat(void)
122147
{
123148
JADE_ASSERT(adc1_handle);
124-
int raw_adc, voltage;
125-
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, BATTERY_ADC_CHANNEL, &raw_adc));
149+
150+
// Average several samples to smooth adc noise
151+
int raw_sum = 0;
152+
for (int i = 0; i < BATTERY_ADC_SAMPLES; ++i) {
153+
int raw_adc;
154+
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, BATTERY_ADC_CHANNEL, &raw_adc));
155+
raw_sum += raw_adc;
156+
}
157+
158+
int voltage;
159+
const int raw_avg = raw_sum / BATTERY_ADC_SAMPLES;
126160
if (adc1_cali_chan0_handle) {
127-
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, raw_adc, &voltage));
161+
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, raw_avg, &voltage));
128162
} else {
129-
voltage = (raw_adc * 3300) / 4095;
163+
voltage = (raw_avg * 3300) / 4095;
130164
}
165+
131166
const float ema_v = (ema_voltage > 0) ? ema_voltage : (float)voltage;
132167
ema_voltage = (BATTERY_EMA_ALPHA * voltage) + ((1.0f - BATTERY_EMA_ALPHA) * ema_v);
133-
return (uint16_t)(ema_voltage * 2);
168+
return (uint16_t)(ema_voltage * BATTERY_VDIV_MULTIPLIER);
134169
}
135170

136171
uint8_t power_get_battery_status(void)
@@ -146,7 +181,9 @@ uint8_t power_get_battery_status(void)
146181

147182
bool power_get_battery_charging(void)
148183
{
149-
return tud_mounted() && !tud_suspended();
184+
// No charger status line on the t-deck - infer charging from usb
185+
// power being present while the battery is not yet full
186+
return usb_connected() && power_get_vbat() < BATTERY_CHARGED_MILLIVOLTS;
150187
}
151188

152189
uint16_t power_get_ibat_charge(void) { return 0; }
@@ -158,13 +195,4 @@ uint16_t power_get_temp(void) { return 0; }
158195
void disable_usb_host(void) {}
159196
void enable_usb_host(void) {}
160197

161-
bool usb_is_powered(void)
162-
{
163-
if (tud_mounted() && !tud_suspended()) {
164-
return true;
165-
}
166-
if (power_get_vbat() < 1000) {
167-
return true;
168-
}
169-
return false;
170-
}
198+
bool usb_is_powered(void) { return usb_connected(); }

0 commit comments

Comments
 (0)