diff options
-rw-r--r-- | common/battery_precharge.c | 248 | ||||
-rw-r--r-- | common/build.mk | 2 | ||||
-rw-r--r-- | common/charge_state.c | 37 | ||||
-rw-r--r-- | include/battery.h | 6 |
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. |