#ifndef CHARGE_IC_CONFIG_H
#define CHARGE_IC_CONFIG_H
-#define CHARGE_1C_MA_HP4570 200u
-#define CHARGE_1C_MA_SGM41562 200u /* TEMP: 41562 1C 测试 */
+#define CHARGE_1C_MA_HP4570 184u
+#define CHARGE_1C_MA_SGM41562 184u
#if defined(ENABLE_HP4570) || defined(ENABLE_SGM41562)
#define ENABLE_CC_CYCLE 1
#endif
#define BATTERY_DISABLE_CHARGE_HI_TEMP_VALUE (45.0f) //停止充电温度
#define BATTERY_DISABLE_CHARGE_LOW_TEMP_VALUE (-10.0f) //停止充电温度
+#define BATTERY_CHARGE_02C_HI_TEMP (19.0f) /* 0~18°C 用 0.2C,上界不含 19 */
#define BATTERY_VOLTAGE_DEBOUNCE 2
*/
uint8_t get_charge_stat(void)
{
- if(uapi_get_charger_plug_status())
- return 1;
- else
- return 0;
+ return charge_ic_is_adapter_present() ? 1 : 0;
}
static uint8_t bat_temp_cnt = 0;
#ifdef ENABLE_CC_CYCLE
/* 拷机放电:Hi-Z/禁充由 cc_cycle 管;拷机充电:走正常温控与 ICHG 档位 */
if (cc_cycle_is_discharge_phase()) {
+ printf("[battery] charge skip: cc_cycle discharge phase\n");
return;
}
#endif
}else{
uint16_t charge_1c_mA = charge_ic_get_1c_mA();
- if(bat_temp >= 0 && bat_temp < 15)
- {
- charge_mA = charge_1c_mA * 2u / 10u;
-
+ if (bat_temp > 0.0f && bat_temp < BATTERY_CHARGE_02C_HI_TEMP) {
+ charge_mA = charge_1c_mA * 2u / 10u; /* 0~18°C: 0.2C */
+ } else if (bat_temp >= BATTERY_CHARGE_02C_HI_TEMP &&
+ bat_temp < BATTERY_DISABLE_CHARGE_HI_TEMP_VALUE) {
+ charge_mA = charge_1c_mA; /* 19~45°C: 1C */
+ } else {
+ charge_mA = 0;
}
- else if((bat_temp >= 15 && bat_temp < 25) || (bat_temp >= 45 && bat_temp < 60))
- {
-
- charge_mA = charge_1c_mA / 2u;
-
- }
- else if(bat_temp >= 25 && bat_temp < 45)
- {
- charge_mA = charge_1c_mA;
-
- }
- else if (bat_temp >= 60)
- {
- PRINT("battery temp >= 60, disable charge !\r\n");
- charge_ic_set_charge_enable(false);
- g_chargestatus = 0;
+ if (charge_mA == 0) {
+ printf("[battery] charge skip: temp=%.1f zone=none charge_mA=0\n", bat_temp);
return;
}
- else
- {
- charge_mA = charge_1c_mA;
- }
- if (charge_mA == 0) {
- charge_mA = charge_1c_mA;
- }
+ printf("[battery] charge target: temp=%.1f 1c=%u target=%umA soc=%u%%\n",
+ bat_temp, (unsigned)charge_1c_mA, (unsigned)charge_mA, (unsigned)percent);
charge_ic_set_chrg_ichg_mA(charge_mA);
}else{
//冗余操作,理论上不必在此关闭充电IC
PRINT("charger not plugged ,disable charge !\r\n");
+ printf("[battery] unplugged: gpio=%u adapter=%u\n",
+ (unsigned)(uapi_get_charger_plug_status() ? 1U : 0U),
+ (unsigned)(charge_ic_is_adapter_present() ? 1U : 0U));
enable_charge(); //防漏电
//enable_02c(); //防漏电
#endif
}
+
+static void battery_reconcile_charge_config(const char *reason)
+{
+ const char *tag = (reason != NULL) ? reason : "unknown";
+ uint16_t hw_before = charge_ic_sync_ichg_cache_from_hw();
+
+ printf("[battery][%s] step1 sync_hw ichg=%umA stat=%u\n",
+ tag, (unsigned)hw_before, (unsigned)get_charge_stat());
+ charge_ic_log_hw_config(tag);
+
+ if (charge_ic_is_adapter_present()) {
+ printf("[battery][%s] step2 adapter OK -> prepare+invalidate\n", tag);
+ charge_ic_prepare_low_power_charge();
+ charge_ic_invalidate_ichg_cache();
+ battery_invalidate_charge_current_cache();
+ } else {
+ printf("[battery][%s] step2 no adapter -> check only\n", tag);
+ }
+ battery_check_chargement();
+
+ {
+ uint16_t hw_after = 0;
+ (void)charge_ic_read_chrg_ichg_mA(&hw_after);
+ printf("[battery][%s] step3 done stat=%u ichg_reg=%umA g_status=%d\n",
+ tag, (unsigned)get_charge_stat(), (unsigned)hw_after, g_chargestatus);
+ }
+}
+
static void battery_check_task(void *arg)
{
unused(arg);
battery_check_voltage();
}
#endif
- battery_check_chargement();
+ /** 首检由 BATTERY_CMD_FIRST_CHECK 统一 reconcile,避免与 boot_task 双跑 */
/**开机初始化电量及充电状态 End*/
while (1) {
ret = osal_msg_queue_read_copy(g_app_queue, (void *)&mail, &msgsize,
//超时交换状态
battery_check_voltage();
last_battery_charge_enable_status = true;
- // charger_plug_event_ui_sendmsg_toUI(1);
- //运行在battery_check_voltage之后,不然开始充电时电压检测值的误差会比较大
- battery_check_chargement();
+ if (get_charge_stat() == 1) {
+ battery_reconcile_charge_config("timer");
+ } else {
+ battery_check_chargement();
+ }
}
}
}else if (mail.comm.event == BATTERY_CMD_CHARGE_PLUG) {
- // PRINT("[battery][service] charger_plug_event_ui_sendmsg_toUI plugged \n");
+ printf("[battery] CHARGE_PLUG -> reset+reconcile\n");
oncharging_status = 1;
#ifdef SUPPORT_CYWEE_SERVICE
cywee_charge_status_update((uint8_t *)&oncharging_status);
#endif
- battery_check_chargement();
+ charge_ic_reset();
+ battery_reconcile_charge_config("plug");
charger_plug_event_ui_sendmsg_toUI(1);
// 记录一次充电线插入时刻的电池数据,用于后续统计充电时间
battery_save_data();
- charge_ic_reset();
- {
- char reg_buf[512];
- (void)charge_ic_dump_debug_registers(reg_buf, sizeof(reg_buf));
- printf("[battery] charge plug reg dump:\n%s", reg_buf);
- }
-
}else if (mail.comm.event == BATTERY_CMD_CHARGE_UNPLUG) {
// PRINT("[battery][service] charger_plug_event_ui_sendmsg_toUI unplugged \n");
oncharging_status = 0;
// 记录一次充电线拔出时刻的电池数据,用于后续统计充电时间
battery_save_data();
}else if (mail.comm.event == BATTERY_CMD_VBUS_ISR) {
+ printf("[battery] VBUS_ISR plugged=%u\n", (unsigned)mail.data[0]);
battery_charger_plug_event_callback((uint8_t)mail.data[0]);
}else if(mail.comm.event == BATTERY_CMD_FIRST_CHECK)
{
- battery_check_chargement();
+ battery_reconcile_charge_config("first_check");
}else if (mail.comm.event == BATTERY_CMD_CHARGE_RECONFIG) {
- battery_invalidate_charge_current_cache();
- battery_check_chargement();
+ battery_reconcile_charge_config("reconfig");
PRINT("[battery] cc_cycle charge reconfig done, ichg=%umA status=%d\r\n",
(unsigned int)last_charge_mA, g_chargestatus);
}else if(mail.comm.event == BATTERY_CMD_SAVE_PERCENT)
charge_ic_apply_1c_ichg();
g_charge_ic_inited = true;
+ (void)charge_ic_sync_ichg_cache_from_hw();
+ charge_ic_log_hw_config("init");
return ERRCODE_SUCC;
}
void charge_ic_set_chrg_ichg_mA(uint16_t current_mA)
{
+ uint16_t readback = 0;
+
if (g_charge_ic_type == CHARGE_IC_TYPE_NONE) {
return;
}
- if(current_mA != last_charge_mA)
- {
- last_charge_mA = current_mA;
- // printf("last_charge_mA : %d\n",last_charge_mA);
- }
- else
+ if (current_mA == last_charge_mA) {
+ printf("[charge_ic] set_ichg SKIP req=%umA cache=%umA (no HW write)\n",
+ (unsigned)current_mA, (unsigned)last_charge_mA);
return;
+ }
+ printf("[charge_ic] set_ichg WRITE req=%umA old_cache=%umA\n",
+ (unsigned)current_mA, (unsigned)last_charge_mA);
+ last_charge_mA = current_mA;
switch (g_charge_ic_type) {
case CHARGE_IC_TYPE_HP4570:
default:
break;
}
+
+ if (charge_ic_read_chrg_ichg_mA(&readback)) {
+ printf("[charge_ic] set_ichg READBACK=%umA\n", (unsigned)readback);
+ } else {
+ printf("[charge_ic] set_ichg READBACK failed\n");
+ }
}
uint8_t charge_ic_get_id(void)
return strlen(buf);
}
+bool charge_ic_read_chrg_ichg_mA(uint16_t *current_mA)
+{
+ if (current_mA == NULL || g_charge_ic_type == CHARGE_IC_TYPE_NONE) {
+ return false;
+ }
+
+ switch (g_charge_ic_type) {
+ case CHARGE_IC_TYPE_HP4570:
+#if defined(ENABLE_HP4570)
+ return HP4570_CC_READ_ICHG_MA(current_mA);
+#else
+ return false;
+#endif
+ case CHARGE_IC_TYPE_SGM41562:
+#if defined(ENABLE_SGM41562)
+ return SGM41562_CC_READ_ICHG_MA(current_mA);
+#else
+ return false;
+#endif
+ default:
+ return false;
+ }
+}
+
+uint16_t charge_ic_sync_ichg_cache_from_hw(void)
+{
+ uint16_t hw = 0;
+
+ if (!g_charge_ic_inited || g_charge_ic_type == CHARGE_IC_TYPE_NONE) {
+ return 0;
+ }
+ if (charge_ic_read_chrg_ichg_mA(&hw)) {
+ last_charge_mA = hw;
+ return hw;
+ }
+ return 0;
+}
+
+void charge_ic_invalidate_ichg_cache(void)
+{
+ last_charge_mA = 0;
+}
+
+static const char *charge_ic_charge_phase_str(void)
+{
+ if (!g_charge_ic_inited || g_charge_ic_type == CHARGE_IC_TYPE_NONE) {
+ return "none";
+ }
+
+ switch (g_charge_ic_type) {
+ case CHARGE_IC_TYPE_HP4570:
+#if defined(ENABLE_HP4570)
+ if (hp4570n_read_chrg_stat_chrg_done()) {
+ return "done";
+ }
+ if (hp4570n_read_chrg_stat_fast_chrg()) {
+ return "fast";
+ }
+ if (hp4570n_read_chrg_stat_pre_chrg() || hp4570n_read_chrg_stat_dead_chrg()) {
+ return "pre";
+ }
+#endif
+ return "idle";
+ case CHARGE_IC_TYPE_SGM41562:
+#if defined(ENABLE_SGM41562)
+ if (sgm41562_read_chrg_stat_chrg_done()) {
+ return "done";
+ }
+ if (sgm41562_read_chrg_stat_fast_chrg()) {
+ return "fast";
+ }
+ if (sgm41562_read_chrg_stat_pre_chrg()) {
+ return "pre";
+ }
+#endif
+ return "idle";
+ default:
+ return "unknown";
+ }
+}
+
+void charge_ic_log_hw_config(const char *tag)
+{
+ const char *t = (tag != NULL) ? tag : "unknown";
+ bool gpio = uapi_get_charger_plug_status();
+ bool ic_pg = false;
+ uint16_t ichg_reg = 0;
+ const char *phase = charge_ic_charge_phase_str();
+
+ if (g_charge_ic_inited && g_charge_ic_type != CHARGE_IC_TYPE_NONE) {
+ ic_pg = charge_ic_read_ic_vbus_pg();
+ (void)charge_ic_read_chrg_ichg_mA(&ichg_reg);
+ }
+ printf("[charge_ic][%s] gpio=%u ic_pg=%u adapter=%u ichg_reg=%umA cache=%umA phase=%s\n",
+ t, (unsigned)(gpio ? 1U : 0U), (unsigned)(ic_pg ? 1U : 0U),
+ (unsigned)(charge_ic_is_adapter_present() ? 1U : 0U),
+ (unsigned)ichg_reg, (unsigned)last_charge_mA, phase);
+
+ if (g_charge_ic_inited && g_charge_ic_type != CHARGE_IC_TYPE_NONE) {
+ char reg_buf[512];
+ (void)charge_ic_dump_debug_registers(reg_buf, sizeof(reg_buf));
+ printf("[charge_ic][%s] regs:\n%s", t, reg_buf);
+ }
+}
+
void charge_ic_shutdown_lpm(void)
{
if (g_charge_ic_type != CHARGE_IC_TYPE_SGM41562) {
}
}
-bool charge_ic_read_chrg_ichg_mA(uint16_t *current_mA)
-{
- if (current_mA == NULL || g_charge_ic_type == CHARGE_IC_TYPE_NONE) {
- return false;
- }
-
- switch (g_charge_ic_type) {
- case CHARGE_IC_TYPE_HP4570:
-#if defined(ENABLE_HP4570)
- return HP4570_CC_READ_ICHG_MA(current_mA);
-#else
- return false;
-#endif
- case CHARGE_IC_TYPE_SGM41562:
-#if defined(ENABLE_SGM41562)
- return SGM41562_CC_READ_ICHG_MA(current_mA);
-#else
- return false;
-#endif
- default:
- return false;
- }
-}
-
bool charge_ic_hw_is_actively_charging(void)
{
switch (g_charge_ic_type) {
/** @brief 导出充电 IC 调试寄存器到 buf,返回写入字节数 */
size_t charge_ic_dump_debug_registers(char *buf, size_t buf_len);
+/** @brief 读 REG 配置的快充电流(mA) */
+bool charge_ic_read_chrg_ichg_mA(uint16_t *current_mA);
+
+/** @brief 从 IC 读 FAST_ICC,刷新内部 ICHG 缓存;失败返回 0 */
+uint16_t charge_ic_sync_ichg_cache_from_hw(void);
+
+/** @brief 清零 ICHG 缓存,强制下次 set 写入硬件 */
+void charge_ic_invalidate_ichg_cache(void);
+
+/** @brief 读 PG + ICHG 缓存 + 寄存器 dump,供开机/插线诊断 */
+void charge_ic_log_hw_config(const char *tag);
+
/** @brief 关机前 41562 低功耗:禁充+HiZ,不断 BAT→SYS(保持 RTC/ULP 走时) */
void charge_ic_shutdown_lpm(void);
/** @brief 拷机充/放电路径:true=允充并退出 HiZ;false=禁充+HiZ(电池放电) */
void charge_ic_set_cycle_charge_path(bool enable_charge);
-/** @brief 读 REG 配置的快充电流(mA) */
-bool charge_ic_read_chrg_ichg_mA(uint16_t *current_mA);
-
/** @brief REG 状态:预充/快充进行中 */
bool charge_ic_hw_is_actively_charging(void);