From e21db5e488259d5bcab1a8429367b5c8b35cfc27 Mon Sep 17 00:00:00 2001 From: Rong Chang Date: Mon, 10 Sep 2012 15:33:43 +0800 Subject: [PATCH] snow: Check state of charge using moving average Signed-off-by: Rong Chang BRANCH=snow BUG=chrome-os-partner:13846 TEST=manual Connect EC UART console and discharge snow device. The system should be turned off when average state of charge is lower than 2.5%. Change-Id: Iab9797d0aa6b159bedd8ce0d2fa72c6458cd14ac Reviewed-on: https://gerrit.chromium.org/gerrit/32693 Commit-Ready: Rong Chang Tested-by: Rong Chang Reviewed-by: Sameer Nanda Reviewed-by: David Hendricks --- common/pmu_tps65090_charger.c | 39 ++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/common/pmu_tps65090_charger.c b/common/pmu_tps65090_charger.c index 2bdc12c3ae..03c2d51f03 100644 --- a/common/pmu_tps65090_charger.c +++ b/common/pmu_tps65090_charger.c @@ -129,6 +129,39 @@ static int notify_battery_low(void) return ST_DISCHARGING; } +/* + * Calculate relative state of charge moving average + * + * The returned value will be rounded to the nearest integer, by set moving + * average init value to (0.5 * window_size). + * + */ +static int rsoc_moving_average(int state_of_charge) +{ + static uint8_t rsoc[4]; + static int8_t index = -1; + int moving_average = sizeof(rsoc) / 2; + int i; + + if (index < 0) { + for (i = 0; i < sizeof(rsoc); i++) + rsoc[i] = (uint8_t)state_of_charge; + index = 0; + return state_of_charge; + } + + rsoc[index] = (uint8_t)state_of_charge; + index++; + index %= sizeof(rsoc); + + for (i = 0; i < sizeof(rsoc); i++) + moving_average += (int)rsoc[i]; + moving_average /= sizeof(rsoc); + + return moving_average; +} + + static int config_low_current_charging(int charge) { /* Disable low current termination */ @@ -305,7 +338,11 @@ static int calc_next_state(int state) } /* Check remaining charge % */ if (battery_state_of_charge(&capacity) == 0) { - if (capacity < 3) { + /* + * Shutdown AP when state of charge < 2.5%. + * Moving average is rounded to integer. + */ + if (rsoc_moving_average(capacity) < 3) { system_off(); return ST_IDLE; } else if (capacity < 10) {