$npx -y skills add easyzoom/aix-skills --skill battery-charger-fuel-gauge-integrationUse when integrating or debugging Li-ion charger/fuel gauge ICs (BQ24295, BQ27441, MAX17048) over I2C, covering charge start, watchdog host mode, NTC/JEITA faults, and SOC jumps
| 1 | # Battery Charger and Fuel Gauge Integration |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | Use this skill to bring up a Li-ion/LiPo charger IC (TI `BQ24xxx`/`BQ25xxx`) and a fuel gauge (TI `BQ27xxx` Impedance Track, or Maxim/Analog `MAX1704x` ModelGauge, e.g. `MAX17048`) over I2C. The hard parts are keeping the charger in host mode past its watchdog, and getting an accurate SOC before the gauge has a matching battery profile. |
| 6 | |
| 7 | ## When To Use |
| 8 | |
| 9 | Use this skill when: |
| 10 | |
| 11 | - Charging never starts or restarts in a loop: check input current limit (`IINLIM`, `REG00[2:0]`), `EN_HIZ`, the `CE` pin, and the I2C watchdog resetting registers to default. |
| 12 | - The charger reports faults: `REG09` latched faults, `NTC_FAULT` (`REG09[2:0]`, with a real thermistor such as `103AT` on the `TS` pin), safety timer expiration, or JEITA temperature de-rating. |
| 13 | - SOC from `BQ27441`/`MAX17048` is wrong or jumps at power-up: profile not loaded, no learning cycle, or bad OCV calibration. |
| 14 | - I2C reads to the charger/gauge fail or the wrong 7-bit address is used. |
| 15 | |
| 16 | Do not use this skill when the I2C bus itself is dead (no ACK on any address) or the board rails are wrong; debug the bus and power tree first with `hardware-interface-debug`. |
| 17 | |
| 18 | ## First Questions |
| 19 | |
| 20 | Ask for: |
| 21 | |
| 22 | - Exact charger and gauge part numbers, cell count/chemistry, pack capacity (mAh), and charge voltage (4.2 V vs 4.35 V — picks `BQ27441-G1A` vs `-G1B`). |
| 23 | - 7-bit I2C addresses, bus speed, and pull-up values; whether `INT`/`GPOUT` is wired. |
| 24 | - NTC/thermistor part and TS resistor network (`RT1`/`RT2`), plus target charge/discharge temperature window. |
| 25 | - Whether a battery profile (TI golden image `.gm.fs`/`.df.fs`, or a Maxim `RCOMP`/custom-model INI) exists, or a golden image must be created. |
| 26 | - Current symptom: register dump, fault code, measured `VBAT`/`ICHG`, or reported SOC vs true SOC. |
| 27 | |
| 28 | ## Integration Checklist |
| 29 | |
| 30 | 1. Confirm the device on the bus. |
| 31 | ACK the charger and gauge 7-bit addresses; read a known register (charger `REG0A` Vendor/Part/Revision, or gauge `Control()` `DEVICE_TYPE` subcommand) before writing anything. |
| 32 | |
| 33 | 1. Take and hold host mode on the charger. |
| 34 | Set `IINLIM` in `REG00[2:0]`, clear `EN_HIZ` (`REG00[7]`), enable charging via `CE`/`CHG_CONFIG` (`REG01[4]`), then feed the I2C watchdog (write `REG01[6]`) on a timer, or disable it (`WATCHDOG` = `REG05[5:4]` = 00), so registers do not reset to default and drop charging. |
| 35 | |
| 36 | 1. Configure charge parameters and protection. |
| 37 | Program fast-charge current (`ICHG`, `REG02`), pre-charge/termination current (`REG03`), charge voltage (`VREG`, `REG04`), and enable NTC/JEITA limits; confirm the thermistor scaling (e.g. `103AT`) on the `TS` pin. |
| 38 | |
| 39 | 1. Load the fuel gauge battery profile. |
| 40 | For `BQ27441`: `UNSEAL` via `Control()`, enter `CFGUPDATE`, poll `Flags()` until bit 4 is set, write `Design Capacity`/`Design Energy`/`Terminate Voltage`/`Taper Rate` in the data-memory block, fix `BlockDataChecksum` (`255 - x`, where `x` is the byte-wise sum of the block), then `SOFT_RESET`. For `MAX17048`: load a custom model / set `RCOMP0` (`CONFIG` default `0x97`) or accept EZ defaults. |
| 41 | |
| 42 | 1. Calibrate SOC at first power-up. |
| 43 | Let the pack rest for a valid OCV read, then issue `MAX17048` `QuickStart` (`MODE` = `0x4000`) or check `BQ27441` `Flags()` `ITPOR` cleared; do not `QuickStart` under load. |
| 44 | |
| 45 | 1. Run temperature compensation and status polling. |
| 46 | Update `MAX17048` `RCOMP` from measured temperature at least once/minute; on `BQ27441` feed `Temperature()` if host-reported. Poll charger `CHRG_STAT` (`REG08[5:4]`) and read `REG09` twice to get fresh faults (it latches, clears on read). |
| 47 | |
| 48 | ## Common Failures |
| 49 | |
| 50 | - Charging restarts every ~40 s: I2C watchdog expired (default 40 s), resetting the writable control registers to defaults; feed it or disable `WATCHDOG`. |
| 51 | - No current with valid adapter: `IINLIM` too low, `EN_HIZ` set, `ILIM` pin resistor, or `CE` held high disabling charge. |
| 52 | - Charge stuck in pre-charge or never terminating: `BATLOWV` threshold (`REG04[1]`), wrong termination current, or safety timer expiring (`REG09` charge safety timer fault). |
| 53 | - `NTC_FAULT` / no charge in a comfortable room: TS resistor network wrong, floating `TS` pin, or JEITA cold/hot fold-back. |
| 54 | - SOC reads 0/100 % or jumps tens of percent: profile (`Design Capacity`) not written, `BlockDataChecksum` wrong so writes silently rejected, or `ITPOR` still set. |
| 55 | - Gauge writes ignored: device still `SEALED`, or not in `CFGUPDATE` mode before writing the data-memory block. |
| 56 | - I2C NAK: wrong 7-bit vs 8-bit address, missing pull-ups, or gauge in hibernate/shutdown. |
| 57 | |
| 58 | ## Verification |
| 59 | |
| 60 | Before claiming charging and gauging work: |
| 61 | |
| 62 | - Dump charger `REG00`–`REG0A`; confirm `IINLIM`, `VREG`, `ICHG`, watchdog state, and `CHRG_STAT` transitions Not Charging → Fast Charging → Terminat |