diff options
author | Philip Chen <philipchen@google.com> | 2018-04-03 15:10:01 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-05-10 19:41:04 -0700 |
commit | bf62593ebd4dead8553ca5615290fe372198e846 (patch) | |
tree | 31a56e78ac8201ef2f3001c438881ea9120df7e2 /common | |
parent | ec1428f96dd750d20047b6b1c4a72e270d71682e (diff) | |
download | chrome-ec-bf62593ebd4dead8553ca5615290fe372198e846.tar.gz |
charge_state_v2: Throttle AP in high battery discharge current
When EC sees discharge current hit BAT_MAX_DISCHG_CURRENT,
we kick off a timer and ask AP to throttle.
Then EC keeps monitoring discharge current. If the current doesn't
drop below BAT_MAX_DISCHG_CURRENT - BAT_OCP_HYSTERESIS, we restart
the timer and notify AP again, which shouldn't happen unless
AP misses or ignores the first notification.
When the timer expires, which means EC hasn't seen over-current
for BAT_OCP_TIMEOUT_US, we ask AP to stop throttling.
BUG=b:74321682, chromium:838754
BRANCH=scarlet
TEST=manually test on scarlet, confirm EC sends
EC_HOST_EVENT_THROTTLE_START and EC_HOST_EVENT_THROTTLE_STOP
host events when entering/exiting OCP.
Change-Id: I1e55fc23249596d8afec52a3885655ca9c1f2151
Signed-off-by: Philip Chen <philipchen@google.com>
Reviewed-on: https://chromium-review.googlesource.com/994188
Commit-Ready: Philip Chen <philipchen@chromium.org>
Tested-by: Philip Chen <philipchen@chromium.org>
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | common/charge_state_v2.c | 44 |
2 files changed, 45 insertions, 0 deletions
diff --git a/common/build.mk b/common/build.mk index a48880bafc..1dd7801455 100644 --- a/common/build.mk +++ b/common/build.mk @@ -107,6 +107,7 @@ common-$(CONFIG_SW_CRC)+=crc.o common-$(CONFIG_TABLET_MODE)+=tablet_mode.o common-$(CONFIG_TEMP_SENSOR)+=temp_sensor.o common-$(CONFIG_THROTTLE_AP)+=thermal.o throttle_ap.o +common-$(CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT)+=throttle_ap.o common-$(CONFIG_TPM_I2CS)+=i2cs_tpm.o common-$(CONFIG_TPM_LOGGING)+=event_log.o tpm_log.o common-$(CONFIG_U2F)+=u2f.o diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index 514e3add92..958257ea71 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -25,6 +25,7 @@ #include "printf.h" #include "system.h" #include "task.h" +#include "throttle_ap.h" #include "timer.h" #include "util.h" @@ -41,6 +42,20 @@ #define PRECHARGE_TIMEOUT_US (PRECHARGE_TIMEOUT * SECOND) #define LFCC_EVENT_THRESH 5 /* Full-capacity change reqd for host event */ +#ifdef CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT +#ifndef CONFIG_HOSTCMD_EVENTS +#error "CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT needs CONFIG_HOSTCMD_EVENTS" +#endif /* CONFIG_HOSTCMD_EVENTS */ +#define BAT_OCP_TIMEOUT_US (60 * SECOND) +/* BAT_OCP_HYSTERESIS_PCT can be optionally overridden in board.h. */ +#ifndef BAT_OCP_HYSTERESIS_PCT +#define BAT_OCP_HYSTERESIS_PCT 10 +#endif /* BAT_OCP_HYSTERESIS_PCT */ +#define BAT_OCP_HYSTERESIS \ + (BAT_MAX_DISCHG_CURRENT * BAT_OCP_HYSTERESIS_PCT / 100) /* mA */ +static timestamp_t ocp_throttle_start_time; +#endif /* CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT */ + static int charge_request(int voltage, int current); /* @@ -1326,6 +1341,33 @@ static void set_charge_state(enum charge_state_v2 state) curr.state = state; } +static void notify_host_of_over_current(struct batt_params *batt) +{ +#ifdef CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT + if (batt->flags & BATT_FLAG_BAD_CURRENT) + return; + + if ((!ocp_throttle_start_time.val && + (batt->current < -BAT_MAX_DISCHG_CURRENT)) || + (ocp_throttle_start_time.val && + (batt->current < -BAT_MAX_DISCHG_CURRENT + BAT_OCP_HYSTERESIS))) { + ocp_throttle_start_time = get_time(); + throttle_ap(THROTTLE_ON, THROTTLE_SOFT, + THROTTLE_SRC_BAT_DISCHG_CURRENT); + } else if (ocp_throttle_start_time.val && + (get_time().val > ocp_throttle_start_time.val + + BAT_OCP_TIMEOUT_US)) { + /* + * Clear the timer and notify AP to stop throttling if + * we haven't seen over current for BAT_OCP_TIMEOUT_US. + */ + ocp_throttle_start_time.val = 0; + throttle_ap(THROTTLE_OFF, THROTTLE_SOFT, + THROTTLE_SRC_BAT_DISCHG_CURRENT); + } +#endif +} + const struct batt_params *charger_current_battery_params(void) { return &curr.batt; @@ -1500,6 +1542,8 @@ void charger_task(void *u) curr.batt.flags |= BATT_FLAG_BAD_STATE_OF_CHARGE; } + notify_host_of_over_current(&curr.batt); + /* * Now decide what we want to do about it. We'll normally just * pass along whatever the battery wants to the charger. Note |