summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-09-21 14:48:47 -0700
committerGerrit <chrome-bot@google.com>2012-09-24 10:56:50 -0700
commit8b592052cea122105996f13a8cb2e44ea22449fc (patch)
tree10f1bcdb051a403141f1c072f37ce72e8049d8b4
parent3c4f66648d74fea0937478042c26c4e729d47e58 (diff)
downloadchrome-ec-8b592052cea122105996f13a8cb2e44ea22449fc.tar.gz
Only ask the charger for current steps it can supply
This reduces oscillations in the charging algorithm. This change also adds more debug output so it's easier to see what the charging state machine is doing. BUG=chrome-os-partner:9572 BRANCH=link TEST=discharge battery; charge battery; note infrequent but useful debug output Change-Id: I4c8609c2ca8a6cab3eae151ecf2bb1520103fece Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/33811 Reviewed-by: Rong Chang <rongchang@chromium.org>
-rw-r--r--common/charge_state.c29
-rw-r--r--common/charger_bq24725.c25
-rw-r--r--include/charger.h9
3 files changed, 51 insertions, 12 deletions
diff --git a/common/charge_state.c b/common/charge_state.c
index e907d5e90a..468eb92adb 100644
--- a/common/charge_state.c
+++ b/common/charge_state.c
@@ -346,8 +346,14 @@ static enum power_state state_idle(struct power_state_context *ctx)
ctx->trickle_charging_time = get_time();
} else {
/* Normal charging */
+ int want_current =
+ charger_closest_current(batt->desired_current);
+
+ CPRINTF("[%T Charge start %dmV %dmA]\n",
+ batt->desired_voltage, want_current);
+
if (charger_set_voltage(batt->desired_voltage) ||
- charger_set_current(batt->desired_current))
+ charger_set_current(want_current))
return PWR_STATE_ERROR;
}
update_charger_time(ctx, get_time());
@@ -367,6 +373,7 @@ static enum power_state state_charge(struct power_state_context *ctx)
struct batt_params *batt = &ctx->curr.batt;
const struct charger_info *c_info = ctx->charger;
int debounce = 0;
+ int want_current;
timestamp_t now;
if (curr->error)
@@ -394,24 +401,36 @@ static enum power_state state_charge(struct power_state_context *ctx)
now = get_time();
if (batt->desired_voltage != curr->charging_voltage) {
+ CPRINTF("[%T Charge voltage %dmV]\n", batt->desired_voltage);
if (charger_set_voltage(batt->desired_voltage))
return PWR_STATE_ERROR;
update_charger_time(ctx, now);
}
- if (batt->desired_current == curr->charging_current) {
+ /*
+ * Adjust desired current to one the charger can actually supply before
+ * we do debouncing, or else we'll keep asking for a current the
+ * charger can't actually supply.
+ */
+ want_current = charger_closest_current(batt->desired_current);
+
+ if (want_current == curr->charging_current) {
/* Tick charger watchdog */
if (!is_charger_expired(ctx, now))
return PWR_STATE_UNCHANGE;
- } else if (batt->desired_current > curr->charging_current) {
+ } else if (want_current > curr->charging_current) {
if (!timestamp_expired(ctx->voltage_debounce_time, &now))
return PWR_STATE_UNCHANGE;
} else {
- /* Debounce charging current on falling edge */
debounce = 1;
}
- if (charger_set_current(batt->desired_current))
+ if (want_current != curr->charging_current) {
+ CPRINTF("[%T Charge current %dmA @ %dmV]\n",
+ want_current, batt->desired_voltage);
+ }
+
+ if (charger_set_current(want_current))
return PWR_STATE_ERROR;
/* Update charger watchdog timer and debounce timer */
diff --git a/common/charger_bq24725.c b/common/charger_bq24725.c
index 84dc8897a2..11077301a7 100644
--- a/common/charger_bq24725.c
+++ b/common/charger_bq24725.c
@@ -134,17 +134,28 @@ int charger_get_current(int *current)
return EC_SUCCESS;
}
-int charger_set_current(int current)
+int charger_closest_current(int current)
{
- const struct charger_info *info = charger_get_info();
+ const struct charger_info * const info = charger_get_info();
- /* Clip the charge current to the range the charger can supply. This
- * is a temporary workaround for the battery requesting a very small
- * current for trickle-charging. See crosbug.com/p/8662. */
+ /*
+ * If the requested current is non-zero but below our minimum,
+ * return the minimum. See crosbug.com/p/8662.
+ */
if (current > 0 && current < info->current_min)
- current = info->current_min;
+ return info->current_min;
+
+ /* Clip to max */
if (current > info->current_max)
- current = info->current_max;
+ return info->current_max;
+
+ /* Otherwise round down to nearest current step */
+ return current - (current % info->current_step);
+}
+
+int charger_set_current(int current)
+{
+ current = charger_closest_current(current);
return sbc_write(SB_CHARGING_CURRENT, CURRENT_TO_REG(current, R_SNS));
}
diff --git a/include/charger.h b/include/charger.h
index 899dbd4883..572ae51aea 100644
--- a/include/charger.h
+++ b/include/charger.h
@@ -44,6 +44,15 @@ int charger_get_status(int *status);
*/
int charger_set_mode(int mode);
+/**
+ * Return the closest match the charger can supply to the requested current.
+ *
+ * @param current Requested current in mA.
+ *
+ * @return Current the charger will actually supply if <current> is requested.
+ */
+int charger_closest_current(int current);
+
/* Get/set charge current limit in mA */
int charger_get_current(int *current);
int charger_set_current(int current);