summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2020-10-29 15:25:05 -0700
committerCommit Bot <commit-bot@chromium.org>2020-11-03 03:40:07 +0000
commit85f55eeb4c8680086241d6b33dc10ee91efaddff (patch)
treeab0eb3614ad9d4a0f82d508e13ed80a4069c0475 /common
parent5884a3b37e47b3b9a926963330b5f34e5cde3445 (diff)
downloadchrome-ec-85f55eeb4c8680086241d6b33dc10ee91efaddff.tar.gz
OCPC: Average and filter resistance calculations
It's been seen that the resistance calculations can vary quite a bit during the charging cycle. In order to reduce this variance, this CL has the OCPC module take the running mean and use that at the combined resistance value. Additionally, values that are outside of a 6 standard deviation window are discarded. BUG=b:170974274 BRANCH=None TEST=Build and flash waddledee, enable OCPC debug logging and plot combined resistance over time as DUT charges in suspend. Verify that combined resistance does not vary significantly. Signed-off-by: Aseda Aboagye <aaboagye@google.com> Change-Id: I2ccb9ccbc0b98455e78249d47f8692828f1a15e9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2508853 Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org> Commit-Queue: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/ocpc.c64
1 files changed, 59 insertions, 5 deletions
diff --git a/common/ocpc.c b/common/ocpc.c
index 647092a8ca..ff42d679a1 100644
--- a/common/ocpc.c
+++ b/common/ocpc.c
@@ -54,6 +54,16 @@ static int k_d_div = KD_DIV;
static int debug_output;
static int viz_output;
+#define NUM_RESISTANCE_SAMPLES 8
+static int resistance_tbl[NUM_RESISTANCE_SAMPLES] = {
+ CONFIG_OCPC_DEF_RBATT_MOHMS
+};
+static int resistance_tbl_idx;
+static int mean_resistance;
+static int stddev_resistance;
+static int ub;
+static int lb;
+
enum phase {
PHASE_UNKNOWN = -1,
PHASE_CC,
@@ -65,10 +75,37 @@ __overridable void board_ocpc_init(struct ocpc_data *ocpc)
{
}
+static void calc_resistance_stats(void)
+{
+ int i;
+ int sum = 0;
+
+ /* Calculate mean */
+ for (i = 0; i < NUM_RESISTANCE_SAMPLES; i++)
+ sum += resistance_tbl[i];
+
+ mean_resistance = sum / NUM_RESISTANCE_SAMPLES;
+
+ /* Calculate standard deviation */
+ sum = 0;
+ for (i = 0; i < NUM_RESISTANCE_SAMPLES; i++)
+ sum += POW2(resistance_tbl[i] - mean_resistance);
+
+ stddev_resistance = fp_sqrtf(INT_TO_FP(sum / NUM_RESISTANCE_SAMPLES));
+ stddev_resistance = FP_TO_INT(stddev_resistance);
+ CPRINTS_DBG("Rbatt+Rsys: mean: %d stddev: %d", mean_resistance,
+ stddev_resistance);
+ lb = MAX(0, mean_resistance - (3 * stddev_resistance));
+ ub = mean_resistance + (3 * stddev_resistance);
+}
+
enum ec_error_list ocpc_calc_resistances(struct ocpc_data *ocpc,
struct batt_params *battery)
{
int act_chg = ocpc->active_chg_chip;
+ static bool seeded;
+ static int initial_samples;
+ int val;
/*
* In order to actually calculate the resistance, we need to make sure
@@ -93,19 +130,36 @@ enum ec_error_list ocpc_calc_resistances(struct ocpc_data *ocpc,
* There's no provision to measure Isys, so we cannot separate
* out Rsys from Rbatt.
*/
- ocpc->combined_rsys_rbatt_mo = ((ocpc->vsys_aux_mv -
- battery->voltage) * 1000) /
- battery->current;
- CPRINTS_DBG("Rsys+Rbatt: %dmOhm", ocpc->combined_rsys_rbatt_mo);
+ val = ((ocpc->vsys_aux_mv - battery->voltage) * 1000) /
+ battery->current;
} else {
ocpc->rsys_mo = ((ocpc->vsys_aux_mv - ocpc->vsys_mv) * 1000) /
ocpc->isys_ma;
ocpc->rbatt_mo = ((ocpc->vsys_mv - battery->voltage) * 1000) /
battery->current;
- ocpc->combined_rsys_rbatt_mo = ocpc->rsys_mo + ocpc->rbatt_mo;
+ val = ocpc->rsys_mo + ocpc->rbatt_mo;
CPRINTS_DBG("Rsys: %dmOhm Rbatt: %dmOhm", ocpc->rsys_mo,
ocpc->rbatt_mo);
}
+
+ /* Discard measurements not within a 6 std dev window. */
+ if ((!seeded) ||
+ (seeded && ((val <= ub) && (val >= lb)))) {
+ resistance_tbl[resistance_tbl_idx] = val;
+ calc_resistance_stats();
+ resistance_tbl_idx = (resistance_tbl_idx + 1) %
+ NUM_RESISTANCE_SAMPLES;
+ }
+
+ if (seeded) {
+ ocpc->combined_rsys_rbatt_mo = MAX(mean_resistance,
+ CONFIG_OCPC_DEF_RBATT_MOHMS);
+ CPRINTS_DBG("Rsys+Rbatt: %dmOhm", ocpc->combined_rsys_rbatt_mo);
+ } else {
+ seeded = ++initial_samples >= (2 * NUM_RESISTANCE_SAMPLES) ?
+ true : false;
+ }
+
return EC_SUCCESS;
}