diff options
author | Aseda Aboagye <aaboagye@google.com> | 2020-10-29 15:25:05 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-11-03 03:40:07 +0000 |
commit | 85f55eeb4c8680086241d6b33dc10ee91efaddff (patch) | |
tree | ab0eb3614ad9d4a0f82d508e13ed80a4069c0475 /common | |
parent | 5884a3b37e47b3b9a926963330b5f34e5cde3445 (diff) | |
download | chrome-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.c | 64 |
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; } |