# ES3C28P Battery Debug — Why Battery Level Was N/A (2026-07-11 Session) ## Symptom Statusbar battery icon + `%` missing, WiFi tab `Battery: N/A`, even though statusbar code in `Statusbar.cpp` and `View.cpp` battery logic were implemented. ## Root Cause `Devices/es3c28p/Source/Configuration.cpp` `createDevices()` only returned `createDisplay()`. No PowerDevice → `hal::findFirstDevice` returns null → all battery code paths hit N/A fallback. - `generic-esp32s3` module.cpp is empty (no devices at all) - `es3c28p` originally had only display in `createDevices()` — audio (ES8311 on I2C 15/16, I2S 4-8), display (SPI), backlight (GPIO45), FM8002E amp enable GPIO1, SDMMC 38-41/47/48, but no power driver. ## Official Pin Research (Downloads) User keeps official board docs in `~/Downloads/2.8inch_IPS_ESP32-S3_ILI9341V_ES3C28P_ES3N28P_V1.0/`: - `5-原理图_Schematic/2.8inch_ESP32-S3_Display_Schematic.pdf` — BAT_ADC net, TP4054 charger IC U2 CHRG 1 -> R12 3.3K -> LED -> GND (NOT to ESP32), R14/R15 200K/200K divider, Q3 SL2305 power path - `1-示例程序_Demo/Arduino/Demo/Example_13_Get_Battery_Voltage/GetBatteryVoltage/GetBatteryVoltage.ino` → ADC_UNIT_1 CH8 GPIO9 12dB 12-bit vol*2 (v-2500)/17 - `ESP32-S3芯片IO资源分配表.xlsx` - Pattern: `ls ~/Downloads/ | grep -i es3c` → folder → Schematic + Example_13 Matches MicroPython `/Users/adolforeyna/Projects/MicroPython/test1/Screen/lib/battery_util.py` Pin 9. ## Fix Implemented (flashed & verified 2026-07-11 Final) ### 1. Power.h/cpp — Direct HAL PowerDevice **File:** `Devices/es3c28p/Source/devices/Power.{h,cpp}` - Uses `esp_adc` oneshot ADC1 CH8 GPIO9, 12dB, 12-bit, curve-fitting cali `adc_cali_create_scheme_curve_fitting`, `vbat = mv *2` - Supports BatteryVoltage, ChargeLevel (2500-4200/17), IsCharging heuristic - IsCharging heuristic (since TP4054 CHRG not wired): <500 or >5000 wall -> charging true; >=4150 high-voltage CV hold -> charging true; rising +10mV/2s twice -> charging true; falling 3x -> not charging. Tracked via FreeRTOS ticks `last_vbat_mv`, `last_read_ms`, `rising_count`, `is_charging_trend`. - Free GPIOs: 0,2,3,9,13,14,19,20,21,42-44 (ES3C28P BCLK=5 leaves GPIO9 free; RLCD BCLK=9 conflicts) - No exceptions: ESP-IDF -fno-exceptions ### 2. Wiring into build - `Devices/es3c28p/CMakeLists.txt`: REQUIRES `esp_adc` - `Source/Configuration.cpp`: #include Power.h, createDevices { createDisplay(), createPower() } ### 3. Build error ``` Power.cpp:30:18: error: exception handling disabled ``` Fix: remove try/catch. ### 4. Build artifacts - ES3C28P: 2.87-2.88 MB, 31% free, partitions-16mb-with-sd.csv, port `/dev/cu.usbmodem101` ### 5. TP4054 HW Limitation — No True IsCharging (Key Lesson) - CHRG pin NOT to ESP32 GPIO, only LED. No VBUS detect GPIO. - Therefore cannot hardware-detect charging; only voltage. - Initial >4350 threshold too high → bolt never appeared → "charging state not recognized properly". Fixed with >=4150 + trend. - For accurate: HW mod solder CHRG pin1 to free GPIO (GPIO3/21) 10K pull-up to 3.3V. - Answer to "no way to know charging?": No true way without mod; heuristic ~80% best-effort. ### 6. Board ID Trap & User Preference Corrections - Color vs RLCD mismatch: check `grep CONFIG_TT_DEVICE_ID sdkconfig` + git log + board_compilation_learnings.md - WiFi tab battery reverted: user said "I don't need the battery level on the wifi, that makes no sense. I wanted on the overall status bar" — battery belongs in statusbar native icon only. - "Remove any custom battery logic (not board config)" → delete other custom Power drivers, but official board support Power driver matching docs IS allowed. - Downloads search pattern: `ls ~/Downloads/ | grep es3c` → Example_13 + schematic