增加41562关机的配置
authorcaisking <caiyqm@qq.com>
Thu, 11 Jun 2026 03:59:07 +0000 (11:59 +0800)
committercaisking <caiyqm@qq.com>
Thu, 11 Jun 2026 03:59:07 +0000 (11:59 +0800)
code/sdk/zhihui/drivers/charge/sgm41562/sgm41562.c
code/sdk/zhihui/drivers/charge/sgm41562/sgm41562.h
code/sdk/zhihui/services/battery/service/charge_ic.cpp
code/sdk/zhihui/services/battery/service/charge_ic.h
code/sdk/zhihui/utils/custom_utils.c

index e7be0aa..0ad02a7 100644 (file)
@@ -1,3 +1,10 @@
+/**
+ * @file    sgm41562.c
+ * @brief   SGM41562 充电 IC 驱动实现(I2C 寄存器读写与充电参数配置)
+ *
+ * @note    I2C 7 位从地址 0x03;BOARD_FD272/BOARD_L22 使用 I2C_BUS_0,BOARD_U8 使用 I2C_BUS_3
+ * @note    参考规格书 SGM41562 REV.A(20210413)
+ */
 
 #include <stdio.h>
 
@@ -15,6 +22,7 @@
 
 // static struct power_supply_desc sgm41562_power_supply_desc;
 
+/** @brief REG01 RST_DGL [7:6]:INT 下拉持续时间(8/12/16/20s) */
 enum SGM41562_PULLDOWN_PERIOD {
        SGM41562_PN_TIMER_8S,
        SGM41562_PN_TIMER_12S,
@@ -23,6 +31,7 @@ enum SGM41562_PULLDOWN_PERIOD {
        SGM41562_PN_TIMER_MAX = 4,
 };
 
+/** @brief REG05 WD_TIMER [6:5]:I2C 看门狗超时(禁用/40/80/160s) */
 enum SGM41562_WDT_TIMER {
        SGM41562_WDT_TIMER_DISABLE,
        SGM41562_WDT_TIMER_40S, 
@@ -31,6 +40,7 @@ enum SGM41562_WDT_TIMER {
        SGM41562_WDT_TIMER_MAX = 4,
 };
 
+/** @brief REG05 CHG_TIMER [2:1]:快充安全定时器(3/5/8/12h) */
 enum SGM41562_CHG_TIMER {
        SGM41562_CHG_TIMER_3H,  
        SGM41562_CHG_TIMER_5H,  
@@ -39,6 +49,7 @@ enum SGM41562_CHG_TIMER {
        SGM41562_CHG_TIMER_MAX = 4,
 };
 
+/** @brief NTC 温度分区(由 REG09 故障位推断) */
 enum SGM41562_TEMP_STATUS {
        SGM41562_TEMP_HOT,      
        SGM41562_TEMP_WARM,     
@@ -47,6 +58,7 @@ enum SGM41562_TEMP_STATUS {
        SGM41562_TEMP_MAX = 4,
 };
  
+/** @brief sgm41562_ctrl_setting() 可配置的寄存器位选项 */
 enum SGM41562_EN_OPTION {
        /* REG 01*/
        REG_BIT_RST_DUR,  //0=2S,1=4S
@@ -88,10 +100,9 @@ enum SGM41562_EN_OPTION {
 };
 
 /**********************************************************
- *
- *   [I2C Function For Read/Write sgm41562_device]
- *
+ * I2C 底层读写(从地址 0x03)
  *********************************************************/
+/** @brief I2C 读单字节寄存器 */
 static int __sgm41562_read_byte( uint8_t reg, uint8_t *data)
 {
     int32_t ret;
@@ -109,6 +120,7 @@ static int __sgm41562_read_byte( uint8_t reg, uint8_t *data)
     return ret;
 }
 
+/** @brief I2C 写单字节寄存器 */
 static int __sgm41562_write_byte( int reg, uint8_t val)
 {
     int32_t ret;
@@ -125,6 +137,7 @@ static int __sgm41562_write_byte( int reg, uint8_t val)
     return ret;
 }
 
+/** @brief 读寄存器(带锁封装,当前未加锁) */
 static int sgm41562_read_reg( uint8_t reg, uint8_t *data)
 {
        int ret;
@@ -136,6 +149,7 @@ static int sgm41562_read_reg( uint8_t reg, uint8_t *data)
        return ret;
 }
 
+/** @brief 写寄存器(带锁封装,当前未加锁) */
 static int sgm41562_write_reg( uint8_t reg, uint8_t val)
 {
        int ret;
@@ -150,6 +164,7 @@ static int sgm41562_write_reg( uint8_t reg, uint8_t val)
        return ret;
 }
 
+/** @brief 读-改-写寄存器位域:reg = (reg & ~mask) | (val & mask) */
 static int sgm41562_update_bits( uint8_t reg,
                                        uint8_t mask, uint8_t val)
 {
@@ -175,6 +190,7 @@ out:
        return ret;
 }
 
+/** @brief 设置 REG00 VINDPM [7:4] 输入最低电压(uV) */
 static int sgm41562_set_input_volt_lim(int vindpm)
 {
        int ret;
@@ -191,6 +207,7 @@ static int sgm41562_set_input_volt_lim(int vindpm)
     return ret;
 }
 
+/** @brief 读取 REG00 VINDPM 当前输入最低电压(uV) */
 static int sgm41562_get_input_volt_lim(void)
 {
        int ret;
@@ -206,6 +223,7 @@ static int sgm41562_get_input_volt_lim(void)
        return vlim;
 }
 
+/** @brief 设置 REG0C IINDPM [7:3] 输入限流(uA) */
 static int sgm41562_set_input_curr_lim( int iindpm)
 {
        int ret;
@@ -222,6 +240,7 @@ static int sgm41562_set_input_curr_lim( int iindpm)
     return ret;
 }
 
+/** @brief 读取 REG0C IINDPM 当前输入限流(uA) */
 static int sgm41562_get_input_curr_lim(void)
 {
        int ret;
@@ -237,6 +256,7 @@ static int sgm41562_get_input_curr_lim(void)
        return ilim;
 }
 
+/** @brief 设置 REG01 RST_DGL [7:6] INT 下拉去抖时间 */
 static int sgm41562_set_pulldown_period(enum SGM41562_PULLDOWN_PERIOD time)
 {
        int ret;
@@ -249,6 +269,7 @@ static int sgm41562_set_pulldown_period(enum SGM41562_PULLDOWN_PERIOD time)
        return ret;
 }
 
+/** @brief 设置 REG01 VBAT_UVLO [2:0] 电池欠压锁定阈值(uV) */
 static int sgm41562_set_vbat_uvlo(int volt)
 {
        int ret;
@@ -266,6 +287,7 @@ static int sgm41562_set_vbat_uvlo(int volt)
     return ret;        
 }
 
+/** @brief 设置 REG02 FAST_ICC [5:0] 快充电流(uA) */
 static int sgm41562_set_fast_cc( int curr)
 {
        int ret;
@@ -282,6 +304,7 @@ static int sgm41562_set_fast_cc( int curr)
     return ret;        
 }
 
+/** @brief 设置 REG03 DSCHG_I [7:4] 放电限流(uA,编码 0 无效) */
 static int sgm41562_set_discharge_curr_limit(int curr)
 {
        int ret;
@@ -300,6 +323,7 @@ static int sgm41562_set_discharge_curr_limit(int curr)
     return ret;        
 }
 
+/** @brief 读取 REG03 TERM_I [3:0] 截止电流(uA) */
 static int sgm41562_get_term_curr(void)
 {
        int ret;
@@ -316,6 +340,7 @@ static int sgm41562_get_term_curr(void)
        return curr;
 }
 
+/** @brief 设置 REG03 TERM_I [3:0] 截止电流(uA) */
 static int sgm41562_set_term_curr( int term_curr)
 {
     int ret = 0;
@@ -336,6 +361,7 @@ static int sgm41562_set_term_curr( int term_curr)
     return ret;
 }
 
+/** @brief 设置 REG04 VBAT_REG [7:2] 充电截止电压(uV) */
 static int sgm41562_set_chrg_volt( int chrg_volt)
 {
        int ret;
@@ -355,6 +381,7 @@ static int sgm41562_set_chrg_volt( int chrg_volt)
        return ret;
 }
 
+/** @brief 读取 REG04 VBAT_REG 当前充电截止电压(uV) */
 static int sgm41562_get_chrg_volt(void)
 {
        int ret;
@@ -371,6 +398,7 @@ static int sgm41562_get_chrg_volt(void)
        return chrg_volt;
 }
 
+/** @brief 设置 REG05 WD_TIMER [6:5] I2C 看门狗超时 */
 static int sgm41562_set_watchdog_timer( enum SGM41562_WDT_TIMER time)
 {
        int ret;
@@ -383,6 +411,7 @@ static int sgm41562_set_watchdog_timer( enum SGM41562_WDT_TIMER time)
        return ret;
 }
 
+/** @brief 设置 REG05 CHG_TIMER [2:1] 快充安全定时器时长 */
 static int sgm41562_set_chg_timer( enum SGM41562_CHG_TIMER time)
 {
        int ret;
@@ -395,6 +424,7 @@ static int sgm41562_set_chg_timer( enum SGM41562_CHG_TIMER time)
        return ret;
 }
 
+/** @brief 设置 REG07 VSYS_REG [4:0] 系统最低电压(uV) */
 static int sgm41562_set_vsys_volt( int volt)
 {
        int ret;
@@ -414,6 +444,12 @@ static int sgm41562_set_vsys_volt( int volt)
        return ret;
 }
 
+/**
+ * @brief  按 SGM41562_EN_OPTION 置位/清零对应寄存器位
+ * @param  options 位域选项(映射 REG01~REG0A/REG0C 各位)
+ * @param  en      true=置 1,false=清 0
+ * @return 0 成功,非 0 I2C 失败
+ */
 static int sgm41562_ctrl_setting(enum SGM41562_EN_OPTION options,bool en)
 {
        int ret = 0;
@@ -568,6 +604,59 @@ void sgm41562_set_batfet_dis(bool en)
        (void)sgm41562_ctrl_setting(REG_BIT_FET_DIS, en);
 }
 
+/** @brief 关机低功耗:关 WDT/NTC/定时器,SWITCH_MODE 保持 BAT→SYS(规格书 REV.A §Battery Discharge) */
+void sgm41562_entry_shutdown_lpm(void)
+{
+       int ret;
+
+       ret = sgm41562_set_watchdog_timer(SGM41562_WDT_TIMER_DISABLE);
+       if (ret)
+               printf("[%s] disable watchdog fail %d\n", __func__, ret);
+
+       ret = sgm41562_ctrl_setting(REG_BIT_EN_TIMER, false);
+       if (ret)
+               printf("[%s] disable safety timer fail %d\n", __func__, ret);
+
+       ret = sgm41562_ctrl_setting(REG_BIT_EN_TERM, false);
+       if (ret)
+               printf("[%s] disable term fail %d\n", __func__, ret);
+
+       ret = sgm41562_ctrl_setting(REG_BIT_EN_NTC, false);
+       if (ret)
+               printf("[%s] disable NTC fail %d\n", __func__, ret);
+
+       ret = sgm41562_ctrl_setting(REG_BIT_EN_PCB_OTP, true);
+       if (ret)
+               printf("[%s] disable PCB OTP fail %d\n", __func__, ret);
+
+       /* REG01 CEB=1 禁充;EN_HIZ=1 降低 VBUS 仍接入时的输入静态电流 */
+       ret = sgm41562_ctrl_setting(REG_BIT_EN_CEB, true);
+       if (ret)
+               printf("[%s] disable charge fail %d\n", __func__, ret);
+
+       ret = sgm41562_ctrl_setting(REG_BIT_EN_HIZ, true);
+       if (ret)
+               printf("[%s] enable HIZ fail %d\n", __func__, ret);
+
+       ret = sgm41562_ctrl_setting(REG_BIT_SWITCH_MODE, true);
+       if (ret)
+               printf("[%s] enable SWITCH_MODE fail %d\n", __func__, ret);
+
+       printf("[%s] shutdown lpm done\n", __func__);
+}
+
+/** @brief 船运模式或关机低功耗(见 SGM41562_USE_FET_DIS_SHIP) */
+void sgm41562_entry_shipmode(void)
+{
+#ifdef SGM41562_USE_FET_DIS_SHIP
+       (void)sgm41562_ctrl_setting(REG_BIT_EN_CEB, true);
+       (void)sgm41562_ctrl_setting(REG_BIT_EN_HIZ, true);
+       (void)sgm41562_set_batfet_dis(true);
+#else
+       sgm41562_entry_shutdown_lpm();
+#endif
+}
+
 bool sgm41562_set_chrg_ichg_mA(uint16_t current_mA)
 {
        printf("current_mA : %d\n",current_mA);
@@ -602,6 +691,7 @@ void sgm41562_reset(void)
        (void)sgm41562_hw_init();
 }
 
+/** @brief 读取 REG08/REG09 并填充 sgm41562_state */
 static int sgm41562_get_state(
                             struct sgm41562_state *state)
 {
@@ -820,6 +910,7 @@ static bool sgm41562_state_changed(
                );
 }
 #endif
+/** @brief 调试:顺序打印 REG00~REG0D */
 static void sgm41562_dump_register(void)
 {
        int i = 0;
@@ -1035,6 +1126,7 @@ static void sgm41562_dump_register(void)
 // }
 
 
+/** @brief 读 REG0B 并与 SGM41562/S/SA 已知 ID 比对 */
 static int sgm41562_hw_chipid_detect(void)
 {
        int ret = 0;
@@ -1061,11 +1153,13 @@ static int sgm41562_hw_chipid_detect(void)
        return ret;
 }
 
+/** @brief 芯片 ID 探测封装,供外部 probe 调用 */
 bool sgm41562_probe(void)
 {
        return sgm41562_hw_chipid_detect() == 0;
 }
 
+/** @brief 硬件初始化:ID 检测 + 默认充电/输入/看门狗参数,初始禁充 */
 int sgm41562_hw_init(void)
 {
        int ret = 0;
@@ -1382,6 +1476,7 @@ err_out:
 //     return 0;
 // }
 
+/** @brief 关机回调:REG01 EN_CEB=0 禁用充电 */
 static void sgm41562_charger_shutdown(void)
 {
     int ret = 0;
@@ -1394,6 +1489,7 @@ static void sgm41562_charger_shutdown(void)
     printf("sgm41562_charger_shutdown\n");
 }
 
+/** @brief 将 REG00~REG0D 格式化 dump 到 buf(NUL 结尾) */
 size_t sgm41562_dump_debug_registers(char *buf, size_t buf_len)
 {
        static const struct {
@@ -1445,6 +1541,7 @@ size_t sgm41562_dump_debug_registers(char *buf, size_t buf_len)
        return off;
 }
 
+/** @brief printf 输出全部寄存器(调用 dump_debug_registers) */
 void sgm41562_read_all_reg(void)
 {
        char buf[512];
index e5e357b..b21d3aa 100644 (file)
@@ -1,3 +1,13 @@
+/**\r
+ * @file    sgm41562.h\r
+ * @brief   SGM41562 单节锂电充电管理 IC 驱动头文件\r
+ *\r
+ * SGM41562 为 I2C 可编程、带 power path(IN/BAT/SYS)的充电管理芯片。\r
+ * 充电流程:预充 → 恒流(CC) → 恒压(CV) → 截止(EOC)。\r
+ *\r
+ * @note    I2C 7 位从地址 0x03;寄存器 0x00~0x0D(REG00~REG0D)\r
+ * @note    参考规格书 SGM41562 REV.A(20210413)\r
+ */\r
 #ifndef SGM41562_CHARGER_H\r
 #define SGM41562_CHARGER_H\r
 \r
@@ -14,7 +24,8 @@ extern "C" {
 #define GENMASK(h, l) (((uint8_t) -1 >> (7 - (h))) & ~((1U << (l)) - 1))\r
 #endif\r
 \r
-/*define register*/\r
+/** @name 寄存器地址(REG00~REG0D) */\r
+/** @{ */\r
 #define SGM41562_CHRG_REG_0    0x00\r
 #define SGM41562_CHRG_REG_1    0x01\r
 #define SGM41562_CHRG_REG_2    0x02\r
@@ -29,8 +40,11 @@ extern "C" {
 #define SGM41562_CHRG_REG_B    0x0B\r
 #define SGM41562_CHRG_REG_C    0x0C\r
 #define SGM41562_CHRG_REG_D    0x0D\r
+/** @} */\r
 \r
-/* REG00 vindpm voltage  */\r
+/** @name REG00 — 输入 DPM / 船运退出条件 */\r
+/** @{ */\r
+/* VINDPM 输入最低电压 [7:4],范围 SGM41562_VINDPM_V_MIN_uV ~ MAX,步进 SGM41562_VINDPM_STEP_uV */\r
 #define SGM41562_VINDPM_V_MASK      GENMASK(7, 4)\r
 #define SGM41562_VINDPM_V_MIN_uV    3880000\r
 #define SGM41562_VINDPM_V_MAX_uV    5080000\r
@@ -39,31 +53,36 @@ extern "C" {
 #define SGM41562_PRE_TO                                BIT(3)\r
 #define SGM41562_INT_EXIT_SHIP         BIT(2)\r
 #define SGM41562_VIN_EXIT_SHIP         BIT(1)\r
-#define SGM41562_ITERM_TIMER           BIT(0)\r
+#define SGM41562_ITERM_TIMER           BIT(0)  /* 截止电流计时使能 */\r
+/** @} */\r
 \r
-\r
-/*REG01 charge setting  */\r
+/** @name REG01 — 复位/Hi-Z/充电使能/VBAT UVLO */\r
+/** @{ */\r
 #define SGM41562_RST_DGL                       GENMASK(7, 6)\r
 #define SGM41562_RST_DUR                       BIT(5)\r
 #define SGM41562_HIZ_EN                                BIT(4)\r
-#define SGM41562_EN_CEB                                BIT(3)\r
+#define SGM41562_EN_CEB                                BIT(3)  /* 1=使能充电路径 */\r
 \r
-/*REG01 VBAT UVLO THRESHOLD */\r
+/* VBAT UVLO 欠压锁定阈值 [2:0] */\r
 #define SGM41562_VBAT_UVLO_MASK                 GENMASK(2, 0)\r
 #define SGM41562_VBAT_UVLO_MIN_uV       2400000\r
 #define SGM41562_VBAT_UVLO_MAX_uV       3030000\r
 #define SGM41562_VBAT_UVLO_STEP_uV      90000\r
 #define SGM41562_VBAT_UVLO_DEF_uV       2760000\r
+/** @} */\r
 \r
-/*REG02  */\r
+/** @name REG02 — 寄存器复位 / 快充电流 FAST_ICC */\r
+/** @{ */\r
 #define SGM41562_REG_RST                     BIT(7)\r
 #define SGM41562_FAST_ICC_MASK           GENMASK(5, 0)\r
 #define SGM41562_FAST_ICC_MIN_uA         8000\r
 #define SGM41562_FAST_ICC_MAX_uA      1024000\r
 #define SGM41562_FAST_ICC_STEP_uA     8000\r
 #define SGM41562_FAST_ICC_DEF_uA      128000\r
+/** @} */\r
 \r
-/* REG03 discharge current  */\r
+/** @name REG03 — 放电限流 DSCHG_I / 截止电流 TERM_I */\r
+/** @{ */\r
 #define SGM41562_DSCHG_I_MASK          GENMASK(7, 4)\r
 #define SGM41562_DSCHG_I_MIN_uA                400000\r
 #define SGM41562_DSCHG_I_MAX_uA                3200000\r
@@ -76,26 +95,30 @@ extern "C" {
 #define SGM41562_TERM_I_MAX_uA         31000\r
 #define SGM41562_TERM_I_STEP_uA                2000\r
 #define SGM41562_TERM_I_DEF_uA         3000\r
+/** @} */\r
 \r
-\r
-/* REG04 vbat  */\r
+/** @name REG04 — 充电截止电压 VBAT_REG / 再充电阈值 VRECH */\r
+/** @{ */\r
 #define SGM41562_VBAT_REG_MASK         GENMASK(7, 2)\r
 #define SGM41562_VBAT_REG_MIN_uV       3500000\r
 #define SGM41562_VBAT_REG_MAX_uV       4770000\r
 #define SGM41562_VBAT_REG_STEP_uV      10000\r
 #define SGM41562_VBAT_REG_DEF_uV       4550000\r
 #define SGM41562_VRECH_THRE_uV     BIT(0)\r
+/** @} */\r
 \r
-\r
-/* REG05  */\r
+/** @name REG05 — 看门狗 / 终止使能 / 安全充电定时器 */\r
+/** @{ */\r
 #define SGM41562_EN_WD_DISCHG       BIT(7)\r
 #define SGM41562_WD_TIMER_MASK       (BIT(6)| BIT(5))\r
 #define SGM41562_EN_TERM             BIT(4)\r
 #define SGM41562_EN_SATETY_TIMER     BIT(3)\r
 #define SGM41562_CHG_TIMER_MASK      (BIT(2)| BIT(1))\r
 #define SGM41562_EN_TERM_TIMER       BIT(0)\r
+/** @} */\r
 \r
-/* REG06  */\r
+/** @name REG06 — NTC / BATFET / 中断掩码 */\r
+/** @{ */\r
 #define SGM41562_EN_NTC                     BIT(7)\r
 #define SGM41562_EN_TMR2X            BIT(6)\r
 #define SGM41562_FET_DIS             BIT(5)\r
@@ -104,8 +127,10 @@ extern "C" {
 #define SGM41562_CHG_STATUS_INT_CTL  BIT(2)\r
 #define SGM41562_NTC_INT_CTL         BIT(1)\r
 #define SGM41562_BATOVP_INT_CTL      BIT(0)\r
+/** @} */\r
 \r
-/* REG07  */\r
+/** @name REG07 — VIN 环 / 结温调节 / VSYS 最低电压 */\r
+/** @{ */\r
 #define SGM41562_DIS_VINLOOP         BIT(7)\r
 #define SGM41562_TJ_REG_MASK         GENMASK(6, 5)\r
 #define SGM41562_VSYS_REG_MASK       GENMASK(4, 0)\r
@@ -113,8 +138,10 @@ extern "C" {
 #define SGM41562_VSYS_MAX_uV            5150000\r
 #define SGM41562_VSYS_STEP_uV       50000\r
 #define SGM41562_VSYS_DEF_uV            4550000\r
+/** @} */\r
 \r
-/* REG08  */\r
+/** @name REG08 — 状态:充电阶段 / PG / PPM / 热调节 / WDT 故障 */\r
+/** @{ */\r
 #define SGM41562_WTD_FAULT              BIT(7)\r
 #define SGM41562_DIS_PCB_OTP        BIT(6)\r
 #define SGM41562_VIN_OVP_SEL         BIT(5)\r
@@ -126,9 +153,10 @@ extern "C" {
 #define SGM41562_PPM_STAT            BIT(2)\r
 #define SGM41562_PG_STAT             BIT(1)\r
 #define SGM41562_THERM_STAT          BIT(0)\r
+/** @} */\r
 \r
-\r
-/* REG09  */\r
+/** @name REG09 — 故障:VIN / NTC / BAT / 安全定时器 / 船运去抖 */\r
+/** @{ */\r
 #define SGM41562_EN_SHIP_DGL_MASK       GENMASK(7, 6)\r
 #define SGM41562_VIN_FAULT           BIT(5)\r
 #define SGM41562_THEM_SD             BIT(4)\r
@@ -136,24 +164,29 @@ extern "C" {
 #define SGM41562_STMR_FAULT          BIT(2)\r
 #define SGM41562_NTC_HOT_FAULT       BIT(1)\r
 #define SGM41562_NTC_COOL_FAULT      BIT(0)\r
+/** @} */\r
 \r
-\r
-/* REG0A  */\r
+/** @name REG0A — I2C 从地址 / 船运与模式选项 */\r
+/** @{ */\r
 #define SGM41562_SLAVE_ADDR_MASK        GENMASK(7, 5)\r
 #define SGM41562_COLD_RESET          BIT(4)\r
 #define SGM41562_SWITCH_MODE         BIT(3)\r
 #define SGM41562_DIS_VDD             BIT(2)\r
 #define SGM41562_DIS_VINOVP          BIT(1)\r
 #define SGM41562_CC_FINE             BIT(0)\r
+/** @} */\r
 \r
-/* REG0B  */\r
+/** @name REG0B — Device ID(只读) */\r
+/** @{ */\r
 #define SGM41562_DEV_ID_MASK           GENMASK(7, 0)\r
 #define SGM41562S_DEV_ID                       (BIT(3) | BIT(0))\r
 #define SGM41562SA_DEV_ID                      0\r
 \r
 #define SGM41562_DEV_ID                            0x4\r
+/** @} */\r
 \r
-/* REG0C iindpm current  */\r
+/** @name REG0C — 输入限流 IINDPM / 看门狗复位 / 中断禁用 */\r
+/** @{ */\r
 #define SGM41562_IINDPM_I_MASK         GENMASK(7, 3)\r
 #define SGM41562_IINDPM_I_MIN_uA       50000\r
 #define SGM41562_IINDPM_I_MAX_uA       980000\r
@@ -161,9 +194,11 @@ extern "C" {
 #define SGM41562_IINDPM_DEF_uA     500000\r
 #define SGM41562_DIS_INT                       BIT(2)\r
 #define SGM41562_VBAT_PRE_THRE_uV      BIT(1)\r
-#define SGM41562_WD_RST                                BIT(0)\r
+#define SGM41562_WD_RST                                BIT(0)  /* 写 1 喂狗/复位看门狗计时 */\r
+/** @} */\r
 \r
-/* REG0D iprechg current  */\r
+/** @name REG0D — 预充电流 PRE_ICHG */\r
+/** @{ */\r
 #define SGM41562_PRE_ICHG_MASK         GENMASK(7, 4)\r
 #define SGM41562_PRE_ICHG_MIN_uA       1000\r
 #define SGM41562_PRE_ICHG_MAX_uA       31000\r
@@ -171,16 +206,18 @@ extern "C" {
 #define SGM41562_PRE_ICHG_DEF_uA       3000\r
 #define SGM41562_PRE_ICHG_X6           BIT(3)\r
 #define SGM41562_ITERM_X6                      BIT(2)\r
+/** @} */\r
 \r
+/** @brief 硬件初始化默认参数(单位均为 uA/uV,见各 REG 宏范围) */\r
 struct sgm41562_init_data {\r
-       uint32_t ichg;  /* charge current               */\r
-       uint32_t ilim;  /* input current                */\r
-       uint32_t vreg;  /* regulation voltage           */\r
-       uint32_t iterm; /* termination current          */\r
-       uint32_t iprechg;       /* precharge current            */\r
-       uint32_t vlim;  /* minimum system voltage limit */\r
-       uint32_t max_ichg;\r
-       uint32_t max_vreg;\r
+       uint32_t ichg;     /**< 快充电流,对应 REG02 FAST_ICC */\r
+       uint32_t ilim;     /**< 输入限流,对应 REG0C IINDPM */\r
+       uint32_t vreg;     /**< 充电截止电压,对应 REG04 VBAT_REG */\r
+       uint32_t iterm;    /**< 截止电流,对应 REG03 TERM_I */\r
+       uint32_t iprechg;  /**< 预充电流,对应 REG0D PRE_ICHG */\r
+       uint32_t vlim;     /**< 输入 VINDPM 电压,对应 REG00 VINDPM */\r
+       uint32_t max_ichg; /**< 允许的最大快充电流上限 */\r
+       uint32_t max_vreg; /**< 允许的最大充电电压上限 */\r
 };\r
 \r
 typedef enum {\r
@@ -214,20 +251,21 @@ static power_supply_property sgm41562_power_supply_props[] = {
     POWER_SUPPLY_PROP_PRESENT\r
 };\r
 \r
+/** @brief 芯片运行状态快照(主要来自 REG08/REG09) */\r
 struct sgm41562_state {\r
-       bool ppm_stat;\r
-       bool therm_stat;\r
-       bool pg_stat;   \r
-       uint8_t chrg_stat;      \r
-\r
-       bool chrg_en;\r
-       bool hiz_en;\r
-       bool term_en;\r
-       bool bat_fault;\r
-       \r
-       uint8_t health;\r
-       uint8_t ntc_fault_0;\r
-       uint8_t ntc_fault_1;    \r
+       bool ppm_stat;      /**< REG08 PPM_STAT:输入功率管理状态 */\r
+       bool therm_stat;    /**< REG08 THERM_STAT:热调节状态 */\r
+       bool pg_stat;       /**< REG08 PG_STAT:输入 Power Good */\r
+       uint8_t chrg_stat;  /**< REG08 CHG_STAT [4:3]:充电阶段 */\r
+\r
+       bool chrg_en;       /**< REG01 EN_CEB 镜像 */\r
+       bool hiz_en;        /**< REG01 HIZ_EN 镜像 */\r
+       bool term_en;       /**< REG05 EN_TERM 镜像 */\r
+       bool bat_fault;     /**< REG09 BAT_FAULT */\r
+\r
+       uint8_t health;     /**< NTC 温度分区(冷/温/热) */\r
+       uint8_t ntc_fault_0; /**< REG09 NTC_COOL_FAULT */\r
+       uint8_t ntc_fault_1; /**< REG09 NTC_HOT_FAULT */\r
 };\r
 \r
 // struct sgm41562_device {\r
@@ -261,32 +299,80 @@ struct sgm41562_state {
 //     struct wakeup_source *charger_wakelock; \r
 // };\r
 \r
+/**\r
+ * @brief  硬件初始化:读 REG0B 校验 ID,配置 ICC/VREG/VINDPM/IINDPM/WD 等,REG01 EN_CEB=0 初始禁充\r
+ * @return 0 成功,非 0 失败(ID 不匹配或寄存器写失败)\r
+ */\r
 int sgm41562_hw_init(void);\r
 \r
+/**\r
+ * @brief  探测芯片是否存在(读 REG0B 与已知 Device ID 比对)\r
+ * @return true 检测到 SGM41562/S/SA,false 未检测到\r
+ */\r
 bool sgm41562_probe(void);\r
 \r
+/** @brief 打印 REG00~REG0D 全部寄存器(printf 调试) */\r
 void sgm41562_read_all_reg(void);\r
 \r
+/**\r
+ * @brief  将 REG00~REG0D 格式化写入 buf(NUL 结尾)\r
+ * @param  buf      输出缓冲区\r
+ * @param  buf_len  缓冲区长度\r
+ * @return 写入字节数(不含 NUL)\r
+ */\r
 size_t sgm41562_dump_debug_registers(char *buf, size_t buf_len);\r
 \r
+/** @brief 看门狗喂狗,写 REG0C WD_RST=1 */\r
 void sgm41562_wdt_rst(void);\r
 \r
+/**\r
+ * @brief  充电路径使能/禁用\r
+ * @param  en true=使能(REG01 EN_CEB=1),false=禁用\r
+ * @note   REG01 bit3\r
+ */\r
 void sgm41562_set_charge_en(bool en);\r
 \r
+/**\r
+ * @brief  强制关断 BATFET(船运模式相关)\r
+ * @param  en true=关断(REG06 FET_DIS=1)\r
+ * @note   REG06 bit5\r
+ */\r
 void sgm41562_set_batfet_dis(bool en);\r
 \r
 /**\r
- * @brief 关机低功耗配置;默认仅调寄存器降压不降 Qswitch。\r
- *        定义 SGM41562_USE_FET_DIS_SHIP=1 且 nINT 有外部上拉时才置 FET_DIS 进船运。\r
+ * @brief  关机低功耗:关 WDT/NTC/充电定时器,REG0A SWITCH_MODE=1 保持 BAT→SYS\r
+ * @note   MCU 仍由电池供电时使用;规格书 I_BAT_Q 可降至 <1.2µA(IC 部分)\r
+ */\r
+void sgm41562_entry_shutdown_lpm(void);\r
+\r
+/**\r
+ * @brief  进入船运/关机低功耗配置\r
+ * @note   未定义 SGM41562_USE_FET_DIS_SHIP 时等同 sgm41562_entry_shutdown_lpm()\r
+ * @note   定义 SGM41562_USE_FET_DIS_SHIP=1 且 nINT 有外部上拉时置 REG06 FET_DIS 进船运\r
  */\r
 void sgm41562_entry_shipmode(void);\r
 \r
+/**\r
+ * @brief  设置快充电流\r
+ * @param  current_mA 充电电流(mA),内部 ×1000 写入 REG02 FAST_ICC\r
+ * @return true 写入成功,false 参数越界或 I2C 失败\r
+ * @note   范围 SGM41562_FAST_ICC_MIN_uA ~ SGM41562_FAST_ICC_MAX_uA\r
+ */\r
 bool sgm41562_set_chrg_ichg_mA(uint16_t current_mA);\r
 \r
+/**\r
+ * @brief  判断是否充电截止(EOC)\r
+ * @return true REG08 CHG_STAT 为 TERM_CHRG,false 未完成或读失败\r
+ */\r
 bool sgm41562_read_chrg_stat_chrg_done(void);\r
 \r
+/**\r
+ * @brief  读取 REG0B Device ID 原始值\r
+ * @return 寄存器值;读失败返回 0\r
+ */\r
 uint8_t sgm41562_get_id(void);\r
 \r
+/** @brief  软复位:重新执行 sgm41562_hw_init() */\r
 void sgm41562_reset(void);\r
 \r
 #ifdef __cplusplus\r
index ca89491..37ad268 100644 (file)
@@ -258,3 +258,14 @@ size_t charge_ic_dump_debug_registers(char *buf, size_t buf_len)
     (void)snprintf(buf, buf_len, "no charge IC detected\n");
     return strlen(buf);
 }
+
+void charge_ic_shutdown_lpm(void)
+{
+    if (g_charge_ic_type != CHARGE_IC_TYPE_SGM41562) {
+        return;
+    }
+
+#if defined(ENABLE_SGM41562)
+    sgm41562_entry_shutdown_lpm();
+#endif
+}
index 25cfd7e..9b6fea1 100644 (file)
@@ -43,6 +43,9 @@ charge_ic_type_t charge_ic_get_type(void);
 /** @brief 导出充电 IC 调试寄存器到 buf,返回写入字节数 */
 size_t charge_ic_dump_debug_registers(char *buf, size_t buf_len);
 
+/** @brief 关机前配置 SGM41562 进入低功耗(HP4570 无需处理) */
+void charge_ic_shutdown_lpm(void);
+
 #ifdef __cplusplus
 }
 #endif
index 3128413..d330d3e 100644 (file)
@@ -129,6 +129,7 @@ extern time_t __tm_to_secs(const struct tm *tm);
 
 #ifdef SUPPORT_BATTERY_SERVICE
 #include "battery_service.h"
+#include "charge_ic.h"
 #endif
 
 #ifdef SUPPORT_CYWEE_SERVICE
@@ -354,6 +355,16 @@ void uapi_poweroff_device(void)
     // uint32_t irq = osal_irq_lock();
     PRINT("[PWR_FLOW] uapi_poweroff_device: poweroff_bt_dsp_display\r\n");
     poweroff_bt_dsp_display();
+#ifdef SUPPORT_BATTERY_SERVICE
+    {
+        char charge_ic_dump[512];
+        (void)charge_ic_dump_debug_registers(charge_ic_dump, sizeof(charge_ic_dump));
+        PRINT("[PWR_FLOW] charge_ic before shutdown lpm:\r\n%s\r\n", charge_ic_dump);
+        charge_ic_shutdown_lpm();
+        (void)charge_ic_dump_debug_registers(charge_ic_dump, sizeof(charge_ic_dump));
+        PRINT("[PWR_FLOW] charge_ic after shutdown lpm:\r\n%s\r\n", charge_ic_dump);
+    }
+#endif
     PRINT("[PWR_FLOW] uapi_poweroff_device: mcu_poweroff\r\n");
     mcu_poweroff();
     // osal_irq_restore(irq);