summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-07-12 15:30:05 -0700
committerChromeBot <chrome-bot@google.com>2013-07-15 14:10:45 -0700
commit20e33095794d0a9957a3a0f768eb9560243c6063 (patch)
tree6df49c5110ae85f1855ce6bba5e305486b347fae
parent1aab26540340085cba0fdd01d495cc3ae5e6d2a8 (diff)
downloadchrome-ec-20e33095794d0a9957a3a0f768eb9560243c6063.tar.gz
Remove fancy trickle charging logic
We implemented a fancy state machine for link to try and feed almost-dead batteries smaller amounts of current than the charger could normally supply, by dithering down the voltage to less than was requested. It's a lot simpler just to give the battery the smallest non-zero amount of current we can give it at the voltage it asks for. Remove the precharge code, since we won't use it on any future platform and link has already branched. BUG=chrome-os-partner:20881 BRANCH=none TEST=find a really dead batery and try to charge it, or do what I did and just hack the battery module to lie about the requested values, and see that it always gets the minimum current step at the requested voltage. Change-Id: I30bcb62bbe215abafb3a98c52e2afed3b74ead1a Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/61789
-rw-r--r--common/battery_precharge.c248
-rw-r--r--common/build.mk2
-rw-r--r--common/charge_state.c37
-rw-r--r--include/battery.h6
4 files changed, 15 insertions, 278 deletions
diff --git a/common/battery_precharge.c b/common/battery_precharge.c
deleted file mode 100644
index 663002cfc8..0000000000
--- a/common/battery_precharge.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Battery charging task and state machine.
- */
-
-#include "battery.h"
-#include "battery_pack.h"
-#include "charge_state.h"
-#include "charger.h"
-#include "smart_battery.h"
-#include "timer.h"
-#include "uart.h"
-#include "util.h"
-
-/* Buffer size for charging resistance calculation */
-#define LOG_BUFFER_SIZE 16
-
-static int log_index;
-static short log_volt[LOG_BUFFER_SIZE];
-static short log_curr[LOG_BUFFER_SIZE];
-static int baseline_voltage;
-static int kicking_count;
-
-static inline int time_after(timestamp_t now, timestamp_t orig, uint64_t usec)
-{
- return (now.val > (orig.val + usec));
-}
-
-static inline void reset_data_log(void)
-{
- log_index = 0;
-}
-
-static inline void trickle_charging_init(void)
-{
- baseline_voltage = 0;
- kicking_count = 0;
- reset_data_log();
-}
-
-/**
- * Adjust charging voltage with voltage value range checking.
- * Reset data log and charger watchdog timer.
- */
-static int set_voltage(struct power_state_context *ctx, int voltage)
-{
- if (voltage <= ctx->curr.batt.desired_voltage && voltage > 0) {
- charger_set_voltage(voltage);
- charger_get_voltage(&ctx->curr.charging_voltage);
- ctx->charger_update_time = get_time();
- reset_data_log();
- return 0;
- }
- return -1;
-}
-
-/**
- * Increase the charging voltage one step.
- */
-static int inc_voltage(struct power_state_context *ctx)
-{
- return set_voltage(ctx, ctx->curr.charging_voltage +
- ctx->charger->voltage_step);
-}
-
-/**
- * Decrease the charging voltage one step.
- */
-static int dec_voltage(struct power_state_context *ctx)
-{
- return set_voltage(ctx, ctx->curr.charging_voltage -
- ctx->charger->voltage_step);
-}
-
-/**
- * Increase the charging voltage baseline one step.
- */
-static enum power_state go_next_level(struct power_state_context *ctx)
-{
- if (inc_voltage(ctx))
- return PWR_STATE_ERROR;
-
- /*
- * Battery chemical reaction lags behind the charging voltage
- * change. Delay the charging state machine 2 seconds.
- */
- sleep(2);
- charger_get_voltage(&baseline_voltage);
-
- return PWR_STATE_UNCHANGE;
-}
-
-/**
- * Trickle charging handler
- *
- * - check trickle charging timeout
- * - new state: INIT
- * - exit condition: when desired_current reaches current_min
- * - try to charge larger current when battery voltage reaches
- * 105% of voltage_min
- */
-enum power_state trickle_charge(struct power_state_context *ctx)
-{
- int sum_volt, sum_curr;
- int desired_volt, desired_curr;
-
- struct power_state_data *curr = &ctx->curr;
- struct batt_params *batt = &curr->batt;
- const struct charger_info *cinfo = ctx->charger;
- const struct battery_info *binfo = ctx->battery;
-
- /* Clear trickle charging duration on AC change */
- if (curr->ac != ctx->prev.ac) {
- ctx->trickle_charging_time.val = 0;
- if (!curr->ac)
- return PWR_STATE_REINIT;
- }
-
- /* Start timer */
- if (ctx->trickle_charging_time.val == 0) {
- trickle_charging_init();
- ctx->trickle_charging_time = get_time();
- }
-
- /* Check charger reset */
- if (curr->charging_voltage == 0 || curr->charging_current == 0) {
- ctx->trickle_charging_time.val = 0;
- return PWR_STATE_REINIT;
- }
-
- /*
- * 4 hours is long enough to pre-charge a large battery (8000mAh)
- * using minimal current (5mAh).
- */
- if (time_after(curr->ts, ctx->trickle_charging_time, HOUR * 4))
- return PWR_STATE_ERROR;
-
- if (curr->error & F_BATTERY_MASK)
- return PWR_STATE_UNCHANGE;
-
- /*
- * End of pre-charge condition; battery desired a current higher than
- * the minimal charging cap.
- */
- if (batt->desired_current > cinfo->current_min) {
- trickle_charging_init();
- ctx->trickle_charging_time.val = 0;
- return PWR_STATE_REINIT;
- }
-
- /*
- * If the trickle charging current drops to zero, raise charging
- * voltage baseline to next level.
- */
- if (batt->current == 0)
- return go_next_level(ctx);
-
- /*
- * When the battery voltage reaches normal charging value (105% min),
- * try kicking the current up and see if it starts normal charging.
- */
- if (kicking_count < 5 &&
- batt->voltage > (binfo->voltage_min * 105 / 100)) {
- kicking_count++;
- charger_set_voltage(batt->desired_voltage);
- sleep(5);
- desired_curr = 0;
- battery_desired_current(&desired_curr);
- if (desired_curr >= cinfo->current_min) {
- /* Exit trickle charging state */
- trickle_charging_init();
- ctx->trickle_charging_time.val = 0;
- return PWR_STATE_REINIT;
- }
- charger_set_voltage(curr->charging_voltage);
- ctx->charger_update_time = get_time();
-
- reset_data_log();
- return PWR_STATE_UNCHANGE;
- }
-
- /*
- * Over current protection. Decrease charging voltage and baseline
- * voltage.
- */
- if (batt->current > binfo->precharge_current) {
- dec_voltage(ctx);
- if (baseline_voltage > ctx->curr.charging_voltage)
- baseline_voltage = ctx->curr.charging_voltage;
- sleep(1);
- reset_data_log();
- return PWR_STATE_UNCHANGE;
- }
-
- /* Voltage and current data acquisition. */
- if (log_index < LOG_BUFFER_SIZE) {
- log_volt[log_index] = batt->voltage;
- log_curr[log_index] = batt->current;
- log_index++;
- return PWR_STATE_UNCHANGE;
- }
-
- sum_volt = 0;
- sum_curr = 0;
- for (log_index = 0; log_index < LOG_BUFFER_SIZE; log_index++) {
- sum_volt += log_volt[log_index];
- sum_curr += log_curr[log_index];
- }
-
- reset_data_log();
-
- /*
- * Estimate desired_voltage. The target current to desired voltage
- * function is a monotonic function. To simplify the calculation, use
- * linear estimation when the current delta is small.
- *
- * V_desired = I_target * ( avg(dV_batt) / avg(I_batt) ) + V_batt
- */
- desired_volt = (1 + batt->desired_current) *
- (curr->charging_voltage * LOG_BUFFER_SIZE - sum_volt) /
- sum_curr + batt->voltage;
-
- if (desired_volt > baseline_voltage) {
- if (desired_volt > curr->charging_voltage) {
- inc_voltage(ctx);
- sleep(1);
- return PWR_STATE_UNCHANGE;
- }
-
- if (desired_volt < (curr->charging_voltage -
- cinfo->voltage_step)) {
- dec_voltage(ctx);
- sleep(1);
- return PWR_STATE_UNCHANGE;
- }
- }
-
- /* Update charger watchdog periodically */
- if (time_after(curr->ts, ctx->charger_update_time,
- CHARGER_UPDATE_PERIOD)) {
- charger_set_current(curr->charging_current);
- ctx->charger_update_time = get_time();
- }
-
- return PWR_STATE_UNCHANGE;
-}
diff --git a/common/build.mk b/common/build.mk
index 858e05b7b9..0476fcb8b1 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -16,7 +16,7 @@ common-$(CONFIG_BATTERY_SLIPPY)+=battery_slippy.o
common-$(CONFIG_BATTERY_PEPPY)+=battery_peppy.o
common-$(CONFIG_BATTERY_FALCO)+=battery_falco.o
common-$(CONFIG_BATTERY_SPRING)+=battery_spring.o
-common-$(CONFIG_CHARGER)+=charge_state.o battery_precharge.o charger_common.o
+common-$(CONFIG_CHARGER)+=charge_state.o charger_common.o
common-$(CONFIG_CHARGER_BQ24715)+=charger_bq24715.o
common-$(CONFIG_CHARGER_BQ24725)+=charger_bq24725.o
common-$(CONFIG_CHARGER_BQ24707A)+=charger_bq24707a.o
diff --git a/common/charge_state.c b/common/charge_state.c
index 4810ebe8a7..83df8ad8a5 100644
--- a/common/charge_state.c
+++ b/common/charge_state.c
@@ -339,7 +339,6 @@ static enum power_state state_init(struct power_state_context *ctx)
static enum power_state state_idle(struct power_state_context *ctx)
{
struct batt_params *batt = &ctx->curr.batt;
- const struct charger_info *c_info = ctx->charger;
/* If we are forcing idle mode, then just stay in IDLE. */
if (state_machine_force_idle)
@@ -361,26 +360,16 @@ static enum power_state state_idle(struct power_state_context *ctx)
/* Configure init charger state and switch to charge state */
if (batt->desired_voltage && batt->desired_current) {
- /* Set charger output constraints */
- if (batt->desired_current < ctx->charger->current_min &&
- batt->state_of_charge < BATTERY_LEVEL_PRE_CHARGE) {
- /* Trickle charging */
- if (charger_set_current(c_info->current_min) ||
- charger_set_voltage(batt->voltage))
- return PWR_STATE_ERROR;
- 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(want_current))
- return PWR_STATE_ERROR;
- }
+ 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(want_current))
+ return PWR_STATE_ERROR;
+
update_charger_time(ctx, get_time());
if (ctx->curr.batt.state_of_charge < BATTERY_LEVEL_NEAR_FULL)
@@ -402,7 +391,6 @@ static enum power_state state_charge(struct power_state_context *ctx)
{
struct power_state_data *curr = &ctx->curr;
struct batt_params *batt = &ctx->curr.batt;
- const struct charger_info *c_info = ctx->charger;
int debounce = 0;
int want_current;
timestamp_t now;
@@ -410,11 +398,6 @@ static enum power_state state_charge(struct power_state_context *ctx)
if (curr->error)
return PWR_STATE_ERROR;
- if (batt->desired_current < c_info->current_min &&
- batt->desired_current > 0 &&
- batt->state_of_charge < BATTERY_LEVEL_PRE_CHARGE)
- return trickle_charge(ctx);
-
/* Check charger reset */
if (curr->charging_voltage == 0 ||
curr->charging_current == 0)
diff --git a/include/battery.h b/include/battery.h
index 50b4e53f7c..940187fe7f 100644
--- a/include/battery.h
+++ b/include/battery.h
@@ -10,19 +10,21 @@
/* Stop charge when charging and battery level >= this percentage */
#define BATTERY_LEVEL_FULL 100
+
/* Tell host we're charged when battery level >= this percentage */
#define BATTERY_LEVEL_NEAR_FULL 97
-/* Precharge only when charging and battery level < this level */
-#define BATTERY_LEVEL_PRE_CHARGE 25
+
/*
* Send battery-low host event when discharging and battery level <= this level
*/
#define BATTERY_LEVEL_LOW 10
+
/*
* Send battery-critical host event when discharging and battery level <= this
* level.
*/
#define BATTERY_LEVEL_CRITICAL 5
+
/*
* Shut down main processor and/or hibernate EC when discharging and battery
* level < this level.