Skip to content

Commit 0a872b7

Browse files
dnojirikiram9
authored andcommitted
chgstv2: Add battery sustainer
This patch adds the battery sustainer. Given a target SoC by the host, the sustainer will try to keep the SoC stay close within the range near the target. The diagram below shows how the sustainer uses the charge mode to charge or discharge the battery as the SoC moves near the target: T-d% T% ----------|----------------------|----------- charge normally charge normally/slowly (mode=NORMAL) ... ----> +---------------------> | | <----------------------+ <----- ... discharge naturally discharge normally (mode=IDLE) (mode=DISCHARGE) When AC is unplugged, the sustainer is disabled. Currently, the sustainer requires CONFIG_CHARGER_DISCHARGE_ON_AC. > chgstate state_of_charge = 69% chg_ctl_mode = NORMAL manual_voltage = -1 manual_current = -1 Battery sustainer = off (-1% ~ -1%) > chgstate sustain 70 72 state_of_charge = 69% chg_ctl_mode = NORMAL manual_voltage = -1 manual_current = -1 Battery sustainer = on (70% ~ 72%) > battfake 71 > chgstate state_of_charge = 71% chg_ctl_mode = NORMAL > battfake 73 > chgstate state_of_charge = 73% chg_ctl_mode = DISCHARGE manual_voltage = -1 manual_current = -1 > battfake 71 > chgstate state_of_charge = 71% chg_ctl_mode = IDLE manual_voltage = 0 manual_current = 0 Unplug AC and EC keeps running. > chgstate state_of_charge = 73% chg_ctl_mode = DISCHARGE manual_voltage = -1 manual_current = -1 Replug AC. > chgstate state_of_charge = 73% chg_ctl_mode = DISCHARGE manual_voltage = 0 manual_current = 0 BUG=b:188457962 BRANCH=None TEST=Atlas. See the description above. Change-Id: I62b4e8bc9517900a5a32d2f35369c645fa8a60c3 Signed-off-by: Daisuke Nojiri <[email protected]> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2929347 Reviewed-by: Vincent Palatin <[email protected]>
1 parent 7d875de commit 0a872b7

File tree

1 file changed

+47
-35
lines changed

1 file changed

+47
-35
lines changed

common/charge_state_v2.c

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
#include "chipset.h"
1515
#include "common.h"
1616
#include "console.h"
17-
#include "ec_ec_comm_master.h"
18-
#include "ec_ec_comm_slave.h"
17+
#include "ec_commands.h"
18+
#include "ec_ec_comm_client.h"
19+
#include "ec_ec_comm_server.h"
1920
#include "extpower.h"
2021
#include "gpio.h"
2122
#include "hooks.h"
@@ -1120,6 +1121,9 @@ static const char * const batt_pres[] = {
11201121
"NO", "YES", "NOT_SURE",
11211122
};
11221123

1124+
const char *mode_text[] = EC_CHARGE_MODE_TEXT;
1125+
BUILD_ASSERT(ARRAY_SIZE(mode_text) == CHARGE_CONTROL_COUNT);
1126+
11231127
static void dump_charge_state(void)
11241128
{
11251129
#define DUMP(FLD, FMT) ccprintf(#FLD " = " FMT "\n", curr.FLD)
@@ -1180,7 +1184,9 @@ static void dump_charge_state(void)
11801184
#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER
11811185
DUMP(input_voltage, "%dmV");
11821186
#endif
1183-
ccprintf("chg_ctl_mode = %d\n", chg_ctl_mode);
1187+
ccprintf("chg_ctl_mode = %s (%d)\n",
1188+
chg_ctl_mode < CHARGE_CONTROL_COUNT
1189+
? mode_text[chg_ctl_mode] : "UNDEF", chg_ctl_mode);
11841190
ccprintf("manual_voltage = %d\n", manual_voltage);
11851191
ccprintf("manual_current = %d\n", manual_current);
11861192
ccprintf("user_current_limit = %dmA\n", user_current_limit);
@@ -1667,41 +1673,47 @@ static int battery_outside_charging_temperature(void)
16671673
}
16681674
#endif
16691675

1670-
static void sustain_soc_disable(void)
1676+
static void sustain_battery_soc(void)
16711677
{
1672-
sustain_soc.lower = -1;
1673-
sustain_soc.upper = -1;
1674-
}
1678+
enum ec_charge_control_mode mode = chg_ctl_mode;
1679+
int soc;
1680+
int rv;
16751681

1676-
static int sustain_soc_set(int16_t lower, int16_t upper)
1677-
{
1678-
if (sustain_soc.lower < sustain_soc.upper
1679-
&& 0 <= sustain_soc.lower && sustain_soc.upper <= 100) {
1680-
sustain_soc.lower = lower;
1681-
sustain_soc.upper = upper;
1682-
return EC_SUCCESS;
1683-
}
1682+
/* If either AC or battery is not present, nothing to do. */
1683+
if (!curr.ac || curr.batt.is_present != BP_YES
1684+
|| !battery_sustainer_enabled())
1685+
return;
16841686

1685-
CPRINTS("Invalid param: %s(%d, %d)", __func__, lower, upper);
1686-
return EC_ERROR_INVAL;
1687-
}
1687+
soc = charge_get_display_charge() / 10;
16881688

1689-
static bool sustain_soc_enabled(void)
1690-
{
1691-
return sustain_soc.lower != -1 && sustain_soc.upper != -1;
1692-
}
1689+
switch (chg_ctl_mode) {
1690+
case CHARGE_CONTROL_NORMAL:
1691+
/* Going up */
1692+
if (sustain_soc.upper < soc)
1693+
mode = CHARGE_CONTROL_DISCHARGE;
1694+
break;
1695+
case CHARGE_CONTROL_IDLE:
1696+
/* discharging naturally */
1697+
if (soc < sustain_soc.lower)
1698+
/* TODO: Charge slowly */
1699+
mode = CHARGE_CONTROL_NORMAL;
1700+
break;
1701+
case CHARGE_CONTROL_DISCHARGE:
1702+
/* discharging rapidly (discharge_on_ac) */
1703+
if (soc < sustain_soc.upper)
1704+
mode = CHARGE_CONTROL_IDLE;
1705+
break;
1706+
default:
1707+
return;
1708+
}
16931709

1694-
static void sustain_battery_soc(void)
1695-
{
1696-
/* If both of AC and battery aren't present, nothing to do. */
1697-
if (!curr.ac || curr.batt.is_present != BP_YES
1698-
|| !sustain_soc_enabled())
1710+
if (mode == chg_ctl_mode)
16991711
return;
17001712

1701-
if (curr.batt.state_of_charge < sustain_soc.lower)
1702-
set_chg_ctrl_mode(CHARGE_CONTROL_NORMAL);
1703-
else if (sustain_soc.upper < curr.batt.state_of_charge)
1704-
set_chg_ctrl_mode(CHARGE_CONTROL_DISCHARGE);
1713+
rv = set_chg_ctrl_mode(mode);
1714+
CPRINTS("%s: %s control mode to %s",
1715+
__func__, rv == EC_SUCCESS ? "Switched" : "Failed to switch",
1716+
mode_text[mode]);
17051717
}
17061718

17071719
/*****************************************************************************/
@@ -1720,7 +1732,7 @@ void charger_init(void)
17201732
*/
17211733
battery_get_params(&curr.batt);
17221734

1723-
sustain_soc_disable();
1735+
battery_sustainer_disable();
17241736
}
17251737
DECLARE_HOOK(HOOK_INIT, charger_init, HOOK_PRIO_DEFAULT);
17261738

@@ -1865,7 +1877,7 @@ void charger_task(void *u)
18651877
}
18661878
} else {
18671879
/* Some things are only meaningful on AC */
1868-
chg_ctl_mode = CHARGE_CONTROL_NORMAL;
1880+
set_chg_ctrl_mode(CHARGE_CONTROL_NORMAL);
18691881
battery_seems_to_be_dead = 0;
18701882
prev_ac = curr.ac;
18711883
}
@@ -2988,7 +3000,7 @@ static int command_chgstate(int argc, char **argv)
29883000
upper = strtoi(argv[3], &e, 0);
29893001
if (*e)
29903002
return EC_ERROR_PARAM3;
2991-
rv = sustain_soc_set(lower, upper);
3003+
rv = battery_sustainer_set(lower, upper);
29923004
if (rv)
29933005
return EC_ERROR_INVAL;
29943006
} else {
@@ -3001,7 +3013,7 @@ static int command_chgstate(int argc, char **argv)
30013013
}
30023014
DECLARE_CONSOLE_COMMAND(chgstate, command_chgstate,
30033015
"[idle|discharge|debug on|off]"
3004-
"\n[sustain lower upper]",
3016+
"\n[sustain <lower> <upper>]",
30053017
"Get/set charge state machine status");
30063018

30073019
#ifdef CONFIG_EC_EC_COMM_BATTERY_MASTER

0 commit comments

Comments
 (0)