diff options
-rw-r--r-- | common/battery_precharge.c | 9 | ||||
-rw-r--r-- | common/charge_state.c | 51 | ||||
-rw-r--r-- | include/charge_state.h | 2 |
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 |