summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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