Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
.pio.nosync
.pio-core/
.dummy/
managed_components/
sdkconfig.defaults
sdkconfig.esp32s3
sdkconfig.*
.vscode/c_cpp_properties.json
.vscode/extensions.json
.vscode/launch.json
Expand All @@ -16,3 +21,8 @@ dist/
build/

/web_apps/**/*.gz

# PDF text extraction (intermediate)
docs/9.0.5/extracted/

.pio/
102 changes: 102 additions & 0 deletions docs/9.0.5/BQ27427_Notes_EN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# BQ27427 Quick Reference (English)

Sources: TI datasheet SLUSEBSA (`bq27427_datasheet.pdf`) and Technical
Reference Manual SLUUCD5 (`bq27427_trm_sluucd5.pdf`). Raw extracted text in
`extracted/`. All protocol details verified on hardware (see
`tools/probe_9.0.5/`).

## Device

Single-cell Li-ion system-side Impedance Track fuel gauge with integrated
7 mOhm sense resistor. I2C up to 400 kHz, **fixed 7-bit address 0x55**
(write byte 0xAA, read byte 0xAB). Chem profiles: 3230 (4.35 V default),
1202 (4.2 V), 3142 (4.4 V). NORMAL 50 uA / SLEEP 9 uA. Package 9-ball DSBGA (YZF).

## I2C protocol

```
write: S 0xAA CMD DATA... P
read: S 0xAA CMD Sr 0xAB DATA[7:0] DATA[7:0] N P
```

- Standard commands return 2 bytes, little-endian; address pointer
auto-increments after each ack; reads above 0x6B are NACKed.
- Standard-command results update at least every 2 s; read-only commands at
most twice per second. t(BUF) >= 66 us between packets at 400 kHz.
- The I2C engine releases SDA/SCL if held low for 2 s.

## Standard Commands (TRM Table 5-1)

| Command | Code | Unit | Access |
|---|---|---|---|
| Control() | 0x00-0x01 | - | R/W |
| Temperature() | 0x02-0x03 | 0.1 K | R/W |
| Voltage() | 0x04-0x05 | mV | R |
| Flags() | 0x06-0x07 | - | R |
| NominalAvailableCapacity() | 0x08-0x09 | mAh | R |
| FullAvailableCapacity() | 0x0A-0x0B | mAh | R |
| RemainingCapacity() | 0x0C-0x0D | mAh | R |
| FullChargeCapacity() | 0x0E-0x0F | mAh | R |
| AverageCurrent() | 0x10-0x11 | mA | R |
| StandbyCurrent() | 0x12-0x13 | mA | R |
| MaxLoadCurrent() | 0x14-0x15 | mA | R |
| AveragePower() | 0x18-0x19 | mW | R |
| StateOfCharge() | 0x1C-0x1D | % | R |
| InternalTemperature() | 0x1E-0x1F | 0.1 K | R |
| **StateOfHealth()** | **0x20-0x21** | % | R |
| RemainingCapacityUnfiltered() | 0x28-0x29 | mAh | R |
| RemainingCapacityFiltered() | 0x2A-0x2B | mAh | R |
| FullChargeCapacityUnfiltered() | 0x2C-0x2D | mAh | R |
| FullChargeCapacityFiltered() | 0x2E-0x2F | mAh | R |
| StateOfChargeUnfiltered() | 0x30-0x31 | % | R |

Notes: StateOfHealth is at 0x20 (TRM 5.13), not 0x2E; BQ27427 has **no**
CycleCount standard command (tables found online mix in BQ27441 info).
Verified live: SOH @0x20 reads 94%.

## Control() Subcommands (TRM Table 5-2)

Write CONTROL (0x00) + 2-byte little-endian subcommand, re-point to 0x00,
read 2 bytes.

| Subcommand | Value | Sealed | Description |
|---|---|---|---|
| CONTROL_STATUS | 0x0000 | yes | status word (bit13 SS = sealed) |
| DEVICE_TYPE | 0x0001 | yes | **0x0427 for BQ27427** |
| FW_VERSION | 0x0002 | yes | 0x0202 (current ROM) |
| DM_CODE | 0x0004 | yes | data memory config code |
| PREV_MACWRITE | 0x0007 | yes | previous MAC command |
| CHEM_ID | 0x0008 | yes | hex-nibble chem id (0x1202 = "1202") |
| BAT_INSERT / BAT_REMOVE | 0x000C/0x000D | yes | force BAT_DET flag |
| SET_CFGUPDATE | 0x0013 | no | enter CONFIG UPDATE mode |
| SMOOTH_SYNC | 0x0019 | yes | sync smoothed capacity |
| SHUTDOWN_ENABLE / SHUTDOWN | 0x001B/0x001C | no | shutdown mode |
| SEALED | 0x0020 | no | enter sealed mode |
| PULSE_SOC_INT | 0x0023 | yes | 1 ms GPOUT pulse |
| CHEM_A/B/C | 0x0030-0x0032 | no | switch chem 3230/1202/3142 |
| RESET | 0x0041 | no | full device reset |
| SOFT_RESET | 0x0042 | no | exit CONFIG UPDATE, resume gauging |

UNSEAL key: 0x8000, written twice.

## Chem switch to 1202 (4.2 V cell, verified)

```
1. (if sealed) UNSEAL 0x8000 x2
2. SET_CFGUPDATE 0x0013
3. wait 1 s
4. CHEM_B 0x0031
5. wait 100 ms
6. SOFT_RESET 0x0042
7. wait 2 s
8. verify CHEM_ID == 0x1202
```

Persists in NVM.

## Data timing

- Voltage/current: immediate.
- SOC: valid ~2 s after reset or chem switch.
- FCC / SOH: converge after ~1-2 full charge/discharge cycles (new cell or
right after a chem switch).
150 changes: 150 additions & 0 deletions docs/9.0.5/BQ27427_中文手册.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# BQ27427 中文技术手册(摘要翻译)

> 来源:TI 数据手册 SLUSEBSA(bq27427.pdf)+ 技术参考手册 SLUUCD5(sluucd5.pdf)
> 原始 PDF 见本目录。整理:2026-08-14,用于 HDS 9.0.5 固件开发
> 所有协议细节均经真机验证(见 tools/probe_9.0.5/)

## 1. 芯片概述

BQ27427 是 TI 的**单节锂电池系统侧电量计(fuel gauge)**,采用专利 Impedance Track™ 阻抗跟踪算法:

- 内置 7 mΩ 集成采样电阻(无需外部检流电阻)
- 板上供电:直接由电池供电,内置 LDO
- 预编程三种化学特性配置(Chem ID):**3230(4.35 V 默认)**、1202(4.2 V)、3142(4.4 V)
- 极低功耗:NORMAL 50 µA / SLEEP 9 µA
- 自动适应电池老化、自放电、温度与负载变化
- 报告:剩余容量(mAh)、电量百分比 SOC(%)、电池电压(mV)、健康度 SOH(%)
- 封装:9-ball DSBGA(YZF),1.62 × 1.58 mm

## 2. 接口

| 项目 | 值 |
|---|---|
| 通信接口 | I2C,最高 400 kHz |
| I2C 7-bit 地址 | **固定 0x55**(1010101,不可更改)|
| 写地址字节 | 0xAA |
| 读地址字节 | 0xAB |
| 上拉电阻 | SCL/SDA 需外部 10 kΩ 上拉(典型)|

## 3. I2C 通信协议

```
写(1 字节命令): S 0xAA CMD[7:0] DATA[7:0] P
读(2 字节数据): S 0xAA CMD[7:0] Sr 0xAB DATA[7:0] DATA[7:0] N P
```

- 标准命令 = 2 字节数据,需两次连续 I2C 传输;多字节数据**低字节在前(Little-Endian)**
- 地址指针在每次应答后自动 +1;超过 0x6B 的地址读取被 NACK
- I2C 引擎在总线被拉低 2 秒后释放 SDA/SCL
- 标准命令结果 ≥2 秒更新;只读命令每秒最多发起 2 次
- 400 kHz 下两次传输间需 t(BUF) ≥ 66 µs

## 4. 标准命令表(TRM Table 5-1)

| 命令 | 命令码 | 单位 | 访问 |
|---|---|---|---|
| Control() | 0x00-0x01 | - | 读写 |
| Temperature() | 0x02-0x03 | 0.1 K | 读写 |
| Voltage() | 0x04-0x05 | mV | 只读 |
| Flags() | 0x06-0x07 | - | 只读 |
| NominalAvailableCapacity() | 0x08-0x09 | mAh | 只读 |
| FullAvailableCapacity() | 0x0A-0x0B | mAh | 只读 |
| RemainingCapacity() | 0x0C-0x0D | mAh | 只读 |
| FullChargeCapacity() | 0x0E-0x0F | mAh | 只读 |
| AverageCurrent() | 0x10-0x11 | mA | 只读 |
| StandbyCurrent() | 0x12-0x13 | mA | 只读 |
| MaxLoadCurrent() | 0x14-0x15 | mA | 只读 |
| AveragePower() | 0x18-0x19 | mW | 只读 |
| StateOfCharge() | 0x1C-0x1D | % | 只读 |
| InternalTemperature() | 0x1E-0x1F | 0.1 K | 只读 |
| **StateOfHealth()** | **0x20-0x21** | % | 只读 |
| RemainingCapacityUnfiltered() | 0x28-0x29 | mAh | 只读 |
| RemainingCapacityFiltered() | 0x2A-0x2B | mAh | 只读 |
| FullChargeCapacityUnfiltered() | 0x2C-0x2D | mAh | 只读 |
| FullChargeCapacityFiltered() | 0x2E-0x2F | mAh | 只读 |
| StateOfChargeUnfiltered() | 0x30-0x31 | % | 只读 |

**注意**:
- **StateOfHealth() = 0x20**(TRM 5.13 节):SOH = 预测 FCC(25°C, SOH LoadI)÷ DesignCapacity,
返回 0-100%。网上有些表写 SOH 在 0x2E / CycleCount 在 0x20,那是 BQ27441 等老芯片的;
**BQ27427 没有 CycleCount 标准命令**(整本 TRM 无 Cycle)。真机验证:SOH@0x20 读出 94%。
- 温度 0.1 K 分辨率:°C = raw × 0.1 - 273.15

## 5. Control() 子命令(TRM Table 5-2)

使用方式:向 0x00 写入 2 字节子命令(低字节在前),**重新指向 0x00**,再读 2 字节结果。

| 子命令 | 值 | SEALED 可访问 | 说明 |
|---|---|---|---|
| CONTROL_STATUS | 0x0000 | ✓ | 状态字(bit13 SS=密封)|
| **DEVICE_TYPE** | **0x0001** | ✓ | 设备类型,**BQ27427 返回 0x0427** |
| FW_VERSION | 0x0002 | ✓ | 固件版本(当前 ROM 0x0202)|
| DM_CODE | 0x0004 | ✓ | Data Memory 配置码 |
| PREV_MACWRITE | 0x0007 | ✓ | 上一条 MAC 命令码 |
| CHEM_ID | 0x0008 | ✓ | 化学特性 ID(十六进制字符编码:0x3230="3230")|
| BAT_INSERT / BAT_REMOVE | 0x000C/0x000D | ✓ | 强制电池在位标志 |
| SET_CFGUPDATE | 0x0013 | ✗ | 进入 CONFIG UPDATE 模式 |
| SMOOTH_SYNC | 0x0019 | ✓ | 平滑容量同步 |
| SHUTDOWN_ENABLE / SHUTDOWN | 0x001B/0x001C | ✗ | 关机模式 |
| SEALED | 0x0020 | ✗ | 进入密封模式 |
| PULSE_SOC_INT | 0x0023 | ✓ | GPOUT 1 ms 脉冲 |
| CHEM_A/B/C | 0x0030-0x0032 | ✗ | 切换化学特性 3230/1202/3142 |
| RESET | 0x0041 | ✗ | 全器件复位 |
| SOFT_RESET | 0x0042 | ✗ | 退出 CONFIG UPDATE,恢复计量 |

**UNSEAL 密钥:0x8000,需连续写两次。**

## 6. 开发要点(实测确认)

### 6.1 开机检测

1. 扫描 I2C 地址 0x55;
2. CONTROL + DEVICE_TYPE(0x0001)返回 **0x0427** → 确认;
3. 无应答或类型不符 → 判定无电量计,全部相关功能禁用。

### 6.2 化学特性切换(4.2 V 电池 → Chem 1202)

芯片出厂默认 3230(4.35 V)。切换流程(TRM 5.1.15 + 应用示例,真机验证):

```
1. (若密封)UNSEAL 0x8000 ×2
2. SET_CFGUPDATE 0x0013
3. 等 1 s(IT 处理停止)
4. CHEM_B 0x0031(→ 1202)
5. 等 100 ms
6. SOFT_RESET 0x0042
7. 等 2 s(SOC 重新有效)
8. 读 CHEM_ID 验证 = 0x1202
```

切换结果持久化在 NVM,重启无需重复。

### 6.3 读取示例

```c
// 电压(mV)
Wire.beginTransmission(0x55); Wire.write(0x04); Wire.endTransmission(true);
Wire.requestFrom(0x55, 2); // 低字节在前,0x42 0x10 → 4162 mV

// 电流(AverageCurrent 0x10,有符号 int16 mA,>0 = 流入电池 = 充电)
Wire.beginTransmission(0x55); Wire.write(0x10); Wire.endTransmission(true);
Wire.requestFrom(0x55, 2);

// Control 子命令:写 CONTROL+子命令(带 STOP)→ 重新指向 0x00 → 读 2 字节
Wire.beginTransmission(0x55);
Wire.write(0x00); Wire.write(0x01); Wire.write(0x00); // DEVICE_TYPE
Wire.endTransmission(true);
delay(2);
Wire.beginTransmission(0x55); Wire.write(0x00); Wire.endTransmission(true);
Wire.requestFrom(0x55, 2); // 0x27 0x04 → 0x0427
```

**实测提示**:所有写操作必须带 STOP(`endTransmission(true)`),否则 CONTROL
子命令不执行;地址指针不会自动回 0,读前必须重新指向 0x00。

### 6.4 数据时效

- 电压/电流:即时
- SOC:复位/化学切换后约 2 秒有效
- FCC(满充容量)/SOH(健康度):需要电池经历**约 1-2 个完整充放电循环**学习收敛
(新电池或刚切换化学特性后)
Loading