kevincoooool/sgm41542s

0.2.1

Latest
uploaded 18 hours ago
ESP-IDF I2C driver for the SGM41542S single-cell battery charger

Readme

# SGM41542S 电源管理驱动

适用于 ESP-IDF 的 SGM41542S 单节锂电池充电和电源路径管理驱动。组件通过 ESP-IDF 新版 I²C Master 总线访问芯片,使用应用已有的 I²C 总线,设备 **7 位地址为 `0x6B`**。本驱动面向 **SGM41542S**;SGM41542、SGM41513 等相似型号的地址、引脚或寄存器不一定相同。

> 组件提供寄存器访问和基础功能,不会自动设置电池参数、估算电量百分比或实现 USB 电源角色切换。接入电池前,应根据电池规格、充电器、硬件接线和芯片手册确定参数。

## 功能

- 识别芯片型号和版本;复用应用创建的 I²C 主机总线。
- 设置快速充电电流、电池充电电压、输入电流限制;控制充电使能及终止。
- 读取电池电压、系统电压、VBUS 电压、TS 电压比例、充电电流和输入电流。
- 通过命名字段配置输入电压动态管理、充电定时、看门狗、JEITA、温度保护、BATFET、过压及过流保护。
- 控制运输模式、OTG 升压、PumpX 和 DP/DM;读取充电状态、输入状态和故障。
- 提供原始寄存器读取及命名字段访问,保留底层位操作接口。

## 安装

在 ESP-IDF 工程目录执行:

```bash
idf.py add-dependency "kevincoooool/sgm41542s^0.2.1"
```

或在使用组件的 `main/idf_component.yml` 中添加:

```yaml
dependencies:
  kevincoooool/sgm41542s: "^0.2.1"
```

需要 **ESP-IDF 5.3 或更高版本**及 `driver/i2c_master.h`。在代码中包含:

```c
#include "sgm41542s.h"
```

## 硬件连接

| SGM41542S 引脚 | 作用 | 连接说明 |
| --- | --- | --- |
| 5:SCL | I²C 时钟 | 接 ESP I²C SCL,并按硬件设计提供上拉 |
| 6:SDA | I²C 数据 | 接 ESP I²C SDA,并按硬件设计提供上拉 |
| 1:VBUS | 输入 / OTG 输出 | 连接合适的 USB 输入及符合设计的 OTG 路径 |
| 13、14:BAT | 电池端 | 接单节电池正极,外围器件按手册设计 |
| 15、16:SYS | 系统电源 | 连接系统负载或后级稳压器输入 |
| 8:OTG | 升压使能 | 升压时需要高电平,同时设置 `OTG_CONFIG` |
| 10:ILIM | 输入电流硬件限制 | 按手册设计;悬空可能导致输入限流为零 |
| 11:TS | 电池温度检测 | 按手册接 NTC 和分压网络 |
| 12:nQON | BATFET 唤醒 | 可连接到地的常开按键以退出运输模式 |

同时按手册连接 GND、散热焊盘、SW、BTST、REGN、PMID、电感和电容。I²C 电平、上拉电源和芯片电气参数需与板级电路匹配。[查看 SGM41542S 官方手册](https://www.sg-micro.com/rect/assets/45f58ecb-468f-46a0-b44e-d6d5fdefe983/SGM41542S.pdf)。

## 初始化和资源释放

组件不创建总线。若 BSP 已创建共享总线,直接将该总线句柄传给 `sgm41542s_init()`,不要对同一组引脚重复创建总线。示例中的 GPIO 仅作演示,请按实际硬件修改:

```c
#include "driver/i2c_master.h"
#include "esp_log.h"
#include "sgm41542s.h"

static const char *TAG = "power";
static i2c_master_bus_handle_t bus;

void power_init(void)
{
    i2c_master_bus_config_t bus_cfg = {
        .i2c_port = I2C_NUM_0,
        .sda_io_num = GPIO_NUM_17,
        .scl_io_num = GPIO_NUM_18,
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .glitch_ignore_cnt = 7,
        .flags.enable_internal_pullup = true,
    };
    esp_err_t err = i2c_new_master_bus(&bus_cfg, &bus);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "创建 I2C 总线失败: %s", esp_err_to_name(err));
        return;
    }
    err = sgm41542s_init(bus);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "SGM41542S 初始化失败: %s", esp_err_to_name(err));
        i2c_del_master_bus(bus);
        bus = NULL;
        return;
    }
    ESP_LOGI(TAG, "SGM41542S 已就绪");
}
```

本组件是**单实例**:在创建其他使用该驱动的任务之前初始化一次。操作内部使用互斥锁;不要通过其他 I²C 设备句柄并发修改同一芯片寄存器,否则无法保证读改写的原子性。销毁前先停止所有使用该驱动的任务:

```c
esp_err_t err = sgm41542s_deinit();
if (err == ESP_OK) {
    /* 只有总线由本应用创建且没有其他设备使用时才删除总线。 */
    err = i2c_del_master_bus(bus);
    if (err == ESP_OK) bus = NULL;
}
```

`sgm41542s_deinit()` 只移除芯片设备句柄,不负责删除应用的总线。初始化及反初始化不支持与其他驱动调用并发执行。

## 充电配置

| 接口 | 单位及有效范围 | 说明 |
| --- | --- | --- |
| `sgm41542s_set_charge_current_ma(ma)` | 0~5100 mA,步进 60 mA | 设为 0 会禁用充电电流;范围或步进不合法返回 `ESP_ERR_INVALID_ARG` |
| `sgm41542s_set_input_current_limit_ma(ma)` | 100~3300 mA,步进 100 mA | 设置输入电流上限,电源检测可能重新设置该值 |
| `sgm41542s_set_charge_voltage_mv(mv)` | 3500~4770 mV,步进 10 mV | 设置电池充电电压,必须与电池规格一致 |

例如,快速充电目标设为不超过 2A 的 1.98A,电池充电电压设为 4.20V:

```c
esp_err_t err = sgm41542s_set_charge_current_ma(1980);
if (err == ESP_OK) err = sgm41542s_set_charge_voltage_mv(4200);
if (err != ESP_OK) {
    ESP_LOGE(TAG, "设置充电参数失败: %s", esp_err_to_name(err));
}
```

芯片电流步进为 60mA,无法精确设置 2000mA:`1980mA` 是不超过 2A 的档位,`2040mA` 是下一档。实际电池充电电流还受输入电流限制、电池状态、恒压阶段、温度和系统负载影响。

**输入电流与电池充电电流不是同一个参数。**例如输入检测为 USB 500mA 时,即使充电目标设置为 1.98A,实际电流也可能受限。仅在确认输入电源、线材和接口允许时修改输入限值:

```c
/* 仅用于已确认能提供 2A 的输入电源。 */
esp_err_t err = sgm41542s_set_input_current_limit_ma(2000);
```

输入检测可能覆盖输入限值;如需在重新检测后恢复,应用应根据电源能力自行管理。组件不会自动识别用户电源的额定能力,也不会在后台自动喂狗或持续写入设置。设置充电电流前请确认电池允许的最大充电电流。使用固定电阻代替 TS 的 NTC 时,不具备对电池本体温度的实际监测能力。

## 看门狗和定时器

看门狗配置字段为 `SGM41542S_F_WATCHDOG`:`0` 关闭、`1` 约 40 秒、`2` 约 80 秒、`3` 约 160 秒。应用应按照配置周期调用 `sgm41542s_feed_watchdog()`,或根据应用要求关闭看门狗。超时后芯片可能恢复部分寄存器默认值;组件不会自行恢复应用参数。

```c
esp_err_t err = sgm41542s_set_field(SGM41542S_F_WATCHDOG, 1);
if (err == ESP_OK) err = sgm41542s_feed_watchdog();
```

喂狗需在应用任务中持续、定期执行,上面只展示单次调用。`SGM41542S_F_EN_TIMER`、`SGM41542S_F_CHG_TIMER`、`SGM41542S_F_EN_TMR2X` 和 `SGM41542S_F_TOPOFF_TIMER` 分别用于充电安全定时及其相关配置;可选编码见数据手册。

## 读取电压和电流

最常用的电池电压接口:

```c
uint32_t battery_mv = 0;
esp_err_t err = sgm41542s_read_battery_mv(&battery_mv);
if (err == ESP_OK) {
    ESP_LOGI(TAG, "电池电压: %lu mV", (unsigned long)battery_mv);
} else {
    ESP_LOGW(TAG, "读取电池电压失败: %s", esp_err_to_name(err));
}
```

通用 ADC 接口 `sgm41542s_read_adc(channel, &value)` 支持:

| 通道 | 含义 | 返回单位 |
| --- | --- | --- |
| `SGM41542S_ADC_VBAT` | 电池电压 | mV |
| `SGM41542S_ADC_VSYS` | 系统电压 | mV |
| `SGM41542S_ADC_TS` | TS 电压占 REGN 的百分比 | 百分比的千分之一;`50000` 表示 50% |
| `SGM41542S_ADC_VBUS` | 输入 / OTG VBUS 电压 | mV |
| `SGM41542S_ADC_IBAT` | 充电电流 | mA |
| `SGM41542S_ADC_IBUS` | 输入电流 | mA |

```c
uint32_t input_ma = 0;
esp_err_t err = sgm41542s_read_adc(SGM41542S_ADC_IBUS, &input_ma);
if (err == ESP_OK) {
    ESP_LOGI(TAG, "输入电流: %lu mA", (unsigned long)input_ma);
}
```

单次转换模式下,驱动对使能的通道发起转换并等待完成;连续转换模式下读取最近的结果。`REG19` 可禁用单次转换中的各通道,连续模式和不同供电状态下各通道的有效性依手册而定。返回成功只说明寄存器读取成功,不保证芯片当时正在测量该通道或结果足够新鲜。IBAT 是**充电电流**,不是带符号的电池放电电流。

数据手册的 I²C 描述称读取超过 `0x0F` 的地址会返回 `0xFF`,但其寄存器表又定义了 `0x10–0x1C`。本项目的实物日志已读取到有效扩展寄存器;驱动会拒绝部分保留 ADC 编码,仍应使用万用表在目标板上核对读数。

**电池电压不是准确的剩余电量百分比。**电量受电芯曲线、温度、充放电状态和负载影响;需要电池曲线校准或专用电量计才能得到更可靠的 SOC。

## 读取状态与故障

使用命名字段读取,返回的是数据手册中的**未移位编码**:

```c
uint8_t state = 0;
esp_err_t err = sgm41542s_get_field(SGM41542S_F_CHRG_STAT, &state);
if (err == ESP_OK) {
    /* 0:未充电,1:预充,2:快速充电,3:充电终止 */
    ESP_LOGI(TAG, "充电状态码: %u", state);
}
```

常用状态字段:

| 字段 | 含义 |
| --- | --- |
| `SGM41542S_F_VBUS_STAT` | 输入类型 / OTG 状态;`7` 表示 OTG |
| `SGM41542S_F_PG_STAT` | 输入电源是否良好 |
| `SGM41542S_F_CHRG_STAT` | 充电阶段 |
| `SGM41542S_F_THERM_STAT` | 芯片是否进入热调节 |
| `SGM41542S_F_VINDPM_STAT` | 输入电压动态管理状态 |
| `SGM41542S_F_IINDPM_STAT` | 输入电流动态管理状态 |
| `SGM41542S_F_WATCHDOG_FAULT` | 看门狗故障 |
| `SGM41542S_F_BOOST_FAULT` | 升压故障 |
| `SGM41542S_F_CHRG_FAULT` | 充电故障编码 |
| `SGM41542S_F_BAT_FAULT` / `SGM41542S_F_NTC_FAULT` | 电池过压 / 温度故障 |

**故障及标志寄存器的读取可能清除锁存事件。**需要保存完整故障快照时,优先一次读取 `REG09`,再在应用中解析;不要为读取多个故障字段反复触发读取:

```c
uint8_t fault_reg = 0;
esp_err_t err = sgm41542s_read(0x09, &fault_reg);
if (err == ESP_OK) {
    ESP_LOGI(TAG, "故障寄存器 REG09=0x%02X", fault_reg);
}
```

## 运输模式与开机

```c
esp_err_t err = sgm41542s_enter_ship_mode();
```

该接口请求 BATFET 延迟断开,手册典型延迟约 12.3 秒。命令发送成功不等于整个板子已断电:VBUS 或其他电源路径可能继续供电。仅电池供电时,断开后 ESP 无法靠自己再发出开机命令,需通过 nQON 或接入有效输入电源退出运输模式。nQON 按键、下游稳压器 EN 和整板供电路径应按实际原理图设计。

若由 nQON 退出运输模式,芯片可能进入 HIZ;应用可通过 `SGM41542S_F_EN_HIZ` 控制退出 HIZ,具体恢复策略由应用决定。

## OTG 5V 升压

```c
/* 仅在 OTG 引脚和板级电源路径准备好时调用。 */
esp_err_t err = sgm41542s_set_otg(true);   /* 请求 5.00V 升压 */
if (err != ESP_OK) {
    ESP_LOGW(TAG, "OTG 请求失败: %s", esp_err_to_name(err));
}
/* 停止升压:sgm41542s_set_otg(false); */
```

使能接口会检查输入电源状态、处理 HIZ、设置目标 5.00V 并写入 OTG 使能;需要 OTG 引脚、电池电压及 TS 条件满足手册要求。I²C 写入成功不等于升压已经启动,可读取 `SGM41542S_F_VBUS_STAT`,状态为 `7` 时芯片报告处于 OTG,再用仪表测量输出。

组件**不自动完成 USB 插拔角色切换**。升压后 VBUS 也为高电平,单看 VBUS 电压无法可靠判断外部 USB 电源是否重新接入;需要应用和硬件共同实现电源角色管理。

## 命名字段和原始寄存器

所有命名字段列在 `sgm41542s_fields.h`。`sgm41542s_get_field()` 返回未移位的字段值,`sgm41542s_set_field()` 接收未移位的字段值:

```c
/* 以下是编码示例,须确认实际应用满足芯片手册的使用条件。 */
esp_err_t err = sgm41542s_set_field(SGM41542S_F_EN_TERM, 1);
if (err == ESP_OK) err = sgm41542s_set_field(SGM41542S_F_BOOST_LIM, 0); /* 0: 500mA */
if (err == ESP_OK) err = sgm41542s_set_field(SGM41542S_F_BC12, 1);
```

字段分组包括:

| 分类 | 常用字段 |
| --- | --- |
| 充电及电池 | `CHG_CONFIG`、`ICHG`、`IPRECHG`、`ITERM`、`VREG`、`VRECHG`、`BATLOWV` |
| 输入及限流 | `IINDPM`、`EN_ILIM`、`VINDPM`、`VINDPM_OS`、`VDPM_BAT_TRACK`、`EN_IINDET`、`BC12` |
| 保护及温度 | `OVP`、`IBATOCP`、`IBATOCP_TIME`、`TREG`、`JEITA_SET`、`JEITA_VT2`、`JEITA_VT3` |
| 运输及升压 | `BATFET_DIS`、`BATFET_DLY`、`EN_BATFET_RST`、`OTG_CONFIG`、`BOOSTV`、`BOOST_LIM`、`OTGF` |
| ADC | `CONV_START`、`CONV_RATE`、`VBAT_ADC_DIS`、`VSYS_ADC_DIS`、`VBUS_ADC_DIS`、`IBAT_ADC_DIS`、`IBUS_ADC_DIS`、`TS_ADC_DIS` |
| 补偿与适配器 | `BAT_COMP`、`VCLAMP`、`EN_PUMPX`、`PUMPX_UP`、`PUMPX_DN`、`EN_DPDM`、`DP_VSET`、`DM_VSET` |

上表字段名前均加 `SGM41542S_F_`;完整列表及位掩码见头文件。字段接口拒绝未列入的字段和只读字段写入,并避免重复写入无关的自清除命令位,但**不保证数值编码对硬件安全,也不检查所有保留编码或字段间依赖**。例如 PumpX、DP/DM、保护阈值和复位操作应先按手册确认电源与线路条件。

`sgm41542s_read(reg, &value)` 可读取 `0x00–0x1C` 的原始字节;原有 `sgm41542s_update_bits()` 仅覆盖其文档规定的低地址控制寄存器。读取或修改前请确认只读位、保留位、看门狗、自清除命令和读清除副作用。

## 常见问题

- **扫描不到 `0x6B`**:检查供电、SDA/SCL、上拉、芯片型号和实际使用的 I²C 总线。7 位地址是 `0x6B`,不是把读写位算进去的 8 位地址。
- **电压显示无效或 `0xFF`**:检查扩展寄存器访问、ADC 通道使能、转换模式及当前供电状态;比较 BAT 引脚万用表实测值。
- **设定 1.98A 但输入电流只有约 0.5A**:检查 `IINDPM`、输入检测结果、电源容量及 `IINDPM_STAT`。USB 电流表测量的是输入电流。
- **发送关机命令后板子仍亮**:检查 USB 或其他电源是否继续供电,以及 SYS 和后级使能的接线。
- **OTG 请求成功但没有 5V**:检查 OTG 引脚、HIZ、电池电压、TS、芯片状态和输出电路;读取 `VBUS_STAT` 与故障状态辅助判断。
- **参数过一段时间恢复默认**:检查看门狗配置与喂狗周期,以及是否发生芯片复位。

## 版本与验证范围

`0.2.1` 为中文文档更新,驱动行为与 `0.2.0` 相同。早期驱动的基础充电设置、电池电压读取和运输模式已在用户板上使用;新增字段、六通道 ADC、OTG 及各保护 / DPDM 配置尚未逐项实板验证。按用户要求,组件整理和文档更新期间没有执行固件编译。

许可证:MIT。芯片参数和完整编码请以 [SGM41542S 官方数据手册](https://www.sg-micro.com/rect/assets/45f58ecb-468f-46a0-b44e-d6d5fdefe983/SGM41542S.pdf)及目标板实测为准。

Links

Supports all targets

To add this component to your project, run:

idf.py add-dependency "kevincoooool/sgm41542s^0.2.1"

download archive

Stats

  • Archive size
    Archive size ~ 14.31 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

kevincoooool/sgm41542s version: 0.2.1
|