summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2014-04-22 16:34:12 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-04-23 20:50:48 +0000
commitfcf26a43ab1737acc873afcc1b61b4fb20389966 (patch)
tree9215d25bcf79683b9c996941410e2911d06ef3ac
parent3b36337be1e165db491bc591ae95be3577886465 (diff)
downloadchrome-ec-fcf26a43ab1737acc873afcc1b61b4fb20389966.tar.gz
charger v2: supports charger watchdog
Some chargers support a timeout mechanism that it would stop charging if no voltage/current setting comes from battery or EC. This is designed for safety. In charger v1, it always updates charger periodically. But in v2, old code only updates charger when needed. New code updates the charger periodically. Also keep the ability for debugging. A manual mode is introduced so that any requested volt/curr from host and force idle mode request would trigger this mode. To leave this mode, just disable the force idle mode. BUG=chrome-os-partner:28201,chrome-os-partner:28208 BRANCH=nyan TEST=See below. Plug AC and battery. Wait for 10 mins and the battery is charged normally. 'chgstate idle on': the charger doesn't charge the battery. 'chgstate idle off': charge again. Plug in AC and remove battery: No annoying repeated message and works fine. Plug in battery and remove AC: No annoying repeated message and works fine. Power up machine with battery only: No annoying repeated message and works fine. Power up machine with AC only: No annoying repeated message and works fine. Change-Id: I00d62f8afa2fe2627ea9259f11679ced02af897a Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/196385
-rw-r--r--common/charge_state_v2.c46
-rw-r--r--test/sbs_charging_v2.c19
2 files changed, 42 insertions, 23 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index a3f641d24a..2527d7f92a 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -35,8 +35,9 @@
*/
static const struct battery_info *batt_info;
static struct charge_state_data curr;
-static int prev_ac, prev_volt, prev_curr, prev_charge;
+static int prev_ac, prev_charge;
static int state_machine_force_idle;
+static int manual_mode; /* volt/curr are no longer maintained by charger */
static unsigned int user_current_limit = -1U;
test_export_static timestamp_t shutdown_warning_time;
static timestamp_t precharge_start_time;
@@ -241,6 +242,7 @@ static void dump_charge_state(void)
DUMP(requested_voltage, "%dmV");
DUMP(requested_current, "%dmA");
ccprintf(" force_idle = %d\n", state_machine_force_idle);
+ ccprintf(" manual_mode = %d\n", manual_mode);
ccprintf(" user_current_limit = %dmA\n", user_current_limit);
ccprintf(" battery_seems_to_be_dead = %d\n", battery_seems_to_be_dead);
#undef DUMP
@@ -277,12 +279,14 @@ static void show_charging_progress(void)
static int charge_request(int voltage, int current)
{
int r1 = EC_SUCCESS, r2 = EC_SUCCESS;
+ static int prev_volt, prev_curr;
/* TODO(crosbug.com/p/27640): should we call charger_set_mode() too? */
if (!voltage || !current)
voltage = current = 0;
- CPRINTF("[%T %s(%dmV, %dmA)]\n", __func__, voltage, current);
+ if (prev_volt != voltage || prev_curr != current)
+ CPRINTF("[%T %s(%dmV, %dmA)]\n", __func__, voltage, current);
if (voltage >= 0)
r1 = charger_set_voltage(voltage);
@@ -294,6 +298,14 @@ static int charge_request(int voltage, int current)
if (r2 != EC_SUCCESS)
problem(PR_SET_CURRENT, r2);
+ /*
+ * Only update if the request worked, so we'll keep trying on failures.
+ */
+ if (!r1 && !r2) {
+ prev_volt = voltage;
+ prev_curr = current;
+ }
+
return r1 ? r1 : r2;
}
@@ -309,6 +321,12 @@ static int charge_force_idle(int enable)
return EC_ERROR_NOT_POWERED;
state_machine_force_idle = enable;
+ if (enable) {
+ charge_request(0, 0);
+ manual_mode = 1;
+ } else {
+ manual_mode = 0;
+ }
return EC_SUCCESS;
}
@@ -415,7 +433,7 @@ void charger_task(void)
/* Initialize all the state */
memset(&curr, 0, sizeof(curr));
curr.batt.is_present = BP_NOT_SURE;
- prev_ac = prev_volt = prev_curr = prev_charge = -1;
+ prev_ac = prev_charge = -1;
state_machine_force_idle = 0;
shutdown_warning_time.val = 0UL;
battery_seems_to_be_dead = 0;
@@ -600,19 +618,15 @@ wait_for_it:
charger_closest_current(curr.requested_current);
/*
- * Only update the charger when something changes so that
- * temporary overrides are possible through console commands.
+ * As a safety feature, some chargers will stop charging if
+ * we don't communicate with it frequently enough. In manual
+ * mode, we'll just tell it what it already knows
*/
- if ((prev_volt != curr.requested_voltage ||
- prev_curr != curr.requested_current) &&
- EC_SUCCESS == charge_request(curr.requested_voltage,
- curr.requested_current)) {
- /*
- * Only update if the request worked, so we'll keep
- * trying on failures.
- */
- prev_volt = curr.requested_voltage;
- prev_curr = curr.requested_current;
+ if (manual_mode) {
+ charge_request(curr.chg.voltage, curr.chg.current);
+ } else {
+ charge_request(curr.requested_voltage,
+ curr.requested_current);
}
/* How long to sleep? */
@@ -837,11 +851,13 @@ static int charge_command_charge_state(struct host_cmd_handler_args *args)
val = charger_closest_voltage(val);
if (charge_request(val, -1))
rv = EC_RES_ERROR;
+ manual_mode = 1;
break;
case CS_PARAM_CHG_CURRENT:
val = charger_closest_current(val);
if (charge_request(-1, val))
rv = EC_RES_ERROR;
+ manual_mode = 1;
break;
case CS_PARAM_CHG_INPUT_CURRENT:
if (charger_set_input_current(val))
diff --git a/test/sbs_charging_v2.c b/test/sbs_charging_v2.c
index 095405b3bb..31dfb34e25 100644
--- a/test/sbs_charging_v2.c
+++ b/test/sbs_charging_v2.c
@@ -105,6 +105,14 @@ static int wait_charging_state(void)
return state;
}
+static int charge_control(enum ec_charge_control_mode mode)
+{
+ struct ec_params_charge_control params;
+ params.mode = mode;
+ return test_send_host_command(EC_CMD_CHARGE_CONTROL, 1, &params,
+ sizeof(params), NULL, 0);
+}
+
/* Setup init condition */
static void test_setup(int on_ac)
{
@@ -134,18 +142,13 @@ static void test_setup(int on_ac)
gpio_set_level(GPIO_AC_PRESENT, 0);
}
+ /* Reset the charger state to initial state */
+ charge_control(CHARGE_CONTROL_NORMAL);
+
/* Let things stabilize */
wait_charging_state();
}
-static int charge_control(enum ec_charge_control_mode mode)
-{
- struct ec_params_charge_control params;
- params.mode = mode;
- return test_send_host_command(EC_CMD_CHARGE_CONTROL, 1, &params,
- sizeof(params), NULL, 0);
-}
-
/* Host Event helpers */
static int ev_is_set(int event)
{