summaryrefslogtreecommitdiff
path: root/common/charge_state_v2.c
diff options
context:
space:
mode:
authorPhilip Chen <philipchen@google.com>2018-04-03 15:10:01 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-10 19:41:04 -0700
commitbf62593ebd4dead8553ca5615290fe372198e846 (patch)
tree31a56e78ac8201ef2f3001c438881ea9120df7e2 /common/charge_state_v2.c
parentec1428f96dd750d20047b6b1c4a72e270d71682e (diff)
downloadchrome-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/charge_state_v2.c')
-rw-r--r--common/charge_state_v2.c44
1 files changed, 44 insertions, 0 deletions
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