summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2012-07-12 16:33:10 +0800
committerGerrit <chrome-bot@google.com>2012-07-18 09:31:27 -0700
commitf322e1b96a5a7400d283b2a6397e020e6200522c (patch)
tree82c4f47bf2af9fb654a502c037b051e9007dfdbf
parent9c289eda9f4fc9d14ea334cf57bc94f789c890e9 (diff)
downloadchrome-ec-f322e1b96a5a7400d283b2a6397e020e6200522c.tar.gz
Set power LED to green when we are trickle charging nearly full
When battery is nearly full, battery sometimes demands for very low current and we are actually trickle charging. This causes the last part of charging process very long, but the actual charged amount is only few mAh. Let's set power LED to green in this case so that user doesn't feel the device is charging forever. BUG=chrome-os-partner:11248 TEST=Charge the battery to nearly full. Disconnect and connect AC power. Check the power LED is green when we are trickle charging. Change-Id: Ide108778232e9f1d3abe6b61af7518af25040d10 Reviewed-on: https://gerrit.chromium.org/gerrit/27264 Commit-Ready: Vic Yang <victoryang@chromium.org> Tested-by: Vic Yang <victoryang@chromium.org> Reviewed-by: Vic Yang <victoryang@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--common/battery_precharge.c9
-rw-r--r--common/charge_state.c51
-rw-r--r--include/charge_state.h2
3 files changed, 34 insertions, 28 deletions
diff --git a/common/battery_precharge.c b/common/battery_precharge.c
index 22c60d878f..9f9f46de95 100644
--- a/common/battery_precharge.c
+++ b/common/battery_precharge.c
@@ -9,6 +9,7 @@
#include "battery_pack.h"
#include "charge_state.h"
#include "charger.h"
+#include "power_led.h"
#include "smart_battery.h"
#include "timer.h"
#include "uart.h"
@@ -17,6 +18,9 @@
/* Buffer size for charging resistance calculation */
#define LOG_BUFFER_SIZE 16
+/* Threshold for power led to turn green */
+#define POWERLED_GREEN_THRESHOLD 90
+
static int log_index;
static short log_volt[LOG_BUFFER_SIZE];
static short log_curr[LOG_BUFFER_SIZE];
@@ -100,6 +104,11 @@ enum power_state trickle_charge(struct power_state_context *ctx)
const struct charger_info *cinfo = ctx->charger;
const struct battery_info *binfo = ctx->battery;
+ /* If battery is nearly full and we are trickle charging, we should
+ * change the power led to green. */
+ if (batt->state_of_charge >= POWERLED_GREEN_THRESHOLD)
+ curr->led_color = POWERLED_GREEN;
+
/* Clear trickle charging duration on AC change */
if (curr->ac != ctx->prev.ac) {
ctx->trickle_charging_time.val = 0;
diff --git a/common/charge_state.c b/common/charge_state.c
index 4cc7b16251..ef54d71b70 100644
--- a/common/charge_state.c
+++ b/common/charge_state.c
@@ -271,6 +271,9 @@ static int state_common(struct power_state_context *ctx)
*/
static enum power_state state_init(struct power_state_context *ctx)
{
+ /* Set LED to green first, other states should change it as desired. */
+ ctx->curr.led_color = POWERLED_GREEN;
+
/* Stop charger, unconditionally */
charger_set_current(0);
charger_set_voltage(0);
@@ -303,8 +306,14 @@ static enum power_state state_idle(struct power_state_context *ctx)
const struct charger_info *c_info = ctx->charger;
/* If we are forcing idle mode, then just stay in IDLE. */
- if (state_machine_force_idle)
+ if (state_machine_force_idle) {
+ if (ctx->prev.led_color == POWERLED_GREEN)
+ ctx->curr.led_color = POWERLED_OFF;
+ else
+ ctx->curr.led_color = POWERLED_GREEN;
return PWR_STATE_UNCHANGE;
+ }
+ ctx->curr.led_color = POWERLED_GREEN;
if (!ctx->curr.ac)
return PWR_STATE_INIT;
@@ -355,6 +364,8 @@ static enum power_state state_charge(struct power_state_context *ctx)
int debounce = 0;
timestamp_t now;
+ curr->led_color = POWERLED_YELLOW;
+
if (curr->error)
return PWR_STATE_ERROR;
@@ -414,6 +425,9 @@ static enum power_state state_charge(struct power_state_context *ctx)
static enum power_state state_discharge(struct power_state_context *ctx)
{
struct batt_params *batt = &ctx->curr.batt;
+
+ ctx->curr.led_color = POWERLED_OFF;
+
if (ctx->curr.ac)
return PWR_STATE_INIT;
@@ -439,6 +453,8 @@ static enum power_state state_error(struct power_state_context *ctx)
{
static int logged_error;
+ ctx->curr.led_color = POWERLED_RED;
+
if (!ctx->curr.error) {
logged_error = 0;
return PWR_STATE_INIT;
@@ -503,16 +519,6 @@ static int enter_force_idle_mode(void)
return EC_SUCCESS;
}
-static enum powerled_color force_idle_led_blink(void)
-{
- static enum powerled_color last = POWERLED_GREEN;
- if (last == POWERLED_GREEN)
- last = POWERLED_OFF;
- else
- last = POWERLED_GREEN;
- return last;
-}
-
/* Battery charging task */
void charge_state_machine_task(void)
{
@@ -521,11 +527,12 @@ void charge_state_machine_task(void)
int sleep_usec = POLL_PERIOD_SHORT, diff_usec, sleep_next;
enum power_state new_state;
uint8_t batt_flags;
- enum powerled_color led_color = POWERLED_OFF;
int rv_setled = 0;
ctx.prev.state = PWR_STATE_INIT;
ctx.curr.state = PWR_STATE_INIT;
+ ctx.prev.led_color = POWERLED_OFF;
+ ctx.curr.led_color = POWERLED_OFF;
ctx.trickle_charging_time.val = 0;
ctx.battery = battery_get_info();
ctx.charger = charger_get_info();
@@ -578,6 +585,10 @@ void charge_state_machine_task(void)
state_name[new_state]);
}
+ if ((ctx.curr.led_color != ctx.prev.led_color || rv_setled) &&
+ new_state != PWR_STATE_DISCHARGE)
+ rv_setled = powerled_set(ctx.curr.led_color);
+
switch (new_state) {
case PWR_STATE_IDLE:
batt_flags = *ctx.memmap_batt_flags;
@@ -585,10 +596,6 @@ void charge_state_machine_task(void)
batt_flags &= ~EC_BATT_FLAG_DISCHARGING;
*ctx.memmap_batt_flags = batt_flags;
- /* Charge done */
- led_color = POWERLED_GREEN;
- rv_setled = powerled_set(POWERLED_GREEN);
-
sleep_usec = POLL_PERIOD_LONG;
break;
case PWR_STATE_DISCHARGE:
@@ -604,25 +611,13 @@ void charge_state_machine_task(void)
batt_flags &= ~EC_BATT_FLAG_DISCHARGING;
*ctx.memmap_batt_flags = batt_flags;
- /* Charging */
- led_color = POWERLED_YELLOW;
- rv_setled = powerled_set(POWERLED_YELLOW);
-
sleep_usec = POLL_PERIOD_CHARGE;
break;
case PWR_STATE_ERROR:
- /* Error */
- led_color = POWERLED_RED;
- rv_setled = powerled_set(POWERLED_RED);
-
sleep_usec = POLL_PERIOD_CHARGE;
break;
case PWR_STATE_UNCHANGE:
/* Don't change sleep duration */
- if (state_machine_force_idle)
- powerled_set(force_idle_led_blink());
- else if (rv_setled)
- rv_setled = powerled_set(led_color);
break;
default:
/* Other state; poll quickly and hope it goes away */
diff --git a/include/charge_state.h b/include/charge_state.h
index c9129c03a5..dc05ba188e 100644
--- a/include/charge_state.h
+++ b/include/charge_state.h
@@ -4,6 +4,7 @@
*
*/
+#include "power_led.h"
#include "timer.h"
#ifndef __CROS_EC_CHARGE_STATE_H
@@ -80,6 +81,7 @@ struct power_state_data {
enum power_state state;
uint32_t error;
timestamp_t ts;
+ enum powerled_color led_color;
};
/* State context