summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Michalec <tm@semihalf.com>2021-05-17 20:49:14 +0200
committerCommit Bot <commit-bot@chromium.org>2021-05-18 20:59:55 +0000
commit91d99a5e66ddc882c5d5a623882ab3d66bba444e (patch)
tree77eb56da52454ee7dcaec89ba96865046773828e
parent4698c8c20a44c5519d4ddabc3f409e0d9f9f5c68 (diff)
downloadchrome-ec-91d99a5e66ddc882c5d5a623882ab3d66bba444e.tar.gz
zephyr: drivers: add smart battery test suite
Add tests for functions from driver/battery/smart.c To test them, Smart Battery emulator is used. BUG=b:184855975 BRANCH=none TEST=run zmake drivers test Signed-off-by: Tomasz Michalec <tm@semihalf.com> Change-Id: I51bdcc2a18c7f30f037b0273ca1ae584312a574b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2903207 Reviewed-by: Jeremy Bettis <jbettis@chromium.org> Commit-Queue: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org>
-rw-r--r--zephyr/test/drivers/overlay.dts8
-rw-r--r--zephyr/test/drivers/prj.conf2
-rw-r--r--zephyr/test/drivers/src/main.c2
-rw-r--r--zephyr/test/drivers/src/smart.c309
4 files changed, 321 insertions, 0 deletions
diff --git a/zephyr/test/drivers/overlay.dts b/zephyr/test/drivers/overlay.dts
index 6f25844438..86cef81435 100644
--- a/zephyr/test/drivers/overlay.dts
+++ b/zephyr/test/drivers/overlay.dts
@@ -84,4 +84,12 @@
timeout = <5>;
wp-gpios = <&gpio_wp_l>;
};
+
+ battery: sb@b {
+ compatible = "zephyr,smart-battery";
+ reg = <0xb>;
+ label = "BATTERY";
+ cycle-count = <99>;
+ version = "BATTERY_SPEC_VER_1_1_WITH_PEC";
+ };
};
diff --git a/zephyr/test/drivers/prj.conf b/zephyr/test/drivers/prj.conf
index 12df68d8e6..e9674907e3 100644
--- a/zephyr/test/drivers/prj.conf
+++ b/zephyr/test/drivers/prj.conf
@@ -12,6 +12,7 @@ CONFIG_I2C_EMUL=y
CONFIG_GPIO=y
CONFIG_GPIO_EMUL=y
CONFIG_EMUL_EEPROM_AT2X=y
+CONFIG_EMUL_SMART_BATTERY=y
CONFIG_PLATFORM_EC_BATTERY_PRESENT_GPIO=y
CONFIG_PLATFORM_EC_EXTPOWER_GPIO=y
@@ -24,6 +25,7 @@ CONFIG_PLATFORM_EC_USB_POWER_DELIVERY=y
CONFIG_PLATFORM_EC_USB_PD_5V_EN_CUSTOM=y
CONFIG_PLATFORM_EC_I2C=y
CONFIG_PLATFORM_EC_BATTERY=y
+CONFIG_PLATFORM_EC_BATTERY_SMART=y
CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR=10
CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR_AC=10
CONFIG_PLATFORM_EC_CHARGER_ISL9241=y
diff --git a/zephyr/test/drivers/src/main.c b/zephyr/test/drivers/src/main.c
index 04f6f55f0a..f16dcbd3f1 100644
--- a/zephyr/test/drivers/src/main.c
+++ b/zephyr/test/drivers/src/main.c
@@ -9,6 +9,7 @@
extern void test_suite_battery(void);
extern void test_suite_cbi(void);
+extern void test_suite_smart_battery(void);
void test_main(void)
{
@@ -19,4 +20,5 @@ void test_main(void)
/* Test suites to run after ec_app_main.*/
test_suite_battery();
test_suite_cbi();
+ test_suite_smart_battery();
}
diff --git a/zephyr/test/drivers/src/smart.c b/zephyr/test/drivers/src/smart.c
new file mode 100644
index 0000000000..5f5c4f52fc
--- /dev/null
+++ b/zephyr/test/drivers/src/smart.c
@@ -0,0 +1,309 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <zephyr.h>
+#include <ztest.h>
+
+#include "common.h"
+#include "i2c.h"
+#include "emul/emul_smart_battery.h"
+
+#include "battery.h"
+#include "battery_smart.h"
+
+#define BATTERY_ORD DT_DEP_ORD(DT_NODELABEL(battery))
+
+/** Test all simple getters */
+static void test_battery_getters(void)
+{
+ struct sbat_emul_bat_data *bat;
+ struct i2c_emul *emul;
+ char block[32];
+ int expected;
+ int word;
+
+ emul = sbat_emul_get_ptr(BATTERY_ORD);
+ bat = sbat_emul_get_bat_data(emul);
+
+ zassert_equal(EC_SUCCESS, battery_get_mode(&word), NULL);
+ zassert_equal(bat->mode, word, "%d != %d", bat->mode, word);
+
+ expected = 100 * bat->cap / bat->design_cap;
+ zassert_equal(EC_SUCCESS, battery_state_of_charge_abs(&word), NULL);
+ zassert_equal(expected, word, "%d != %d", expected, word);
+
+ zassert_equal(EC_SUCCESS, battery_remaining_capacity(&word), NULL);
+ zassert_equal(bat->cap, word, "%d != %d", bat->cap, word);
+ zassert_equal(EC_SUCCESS, battery_full_charge_capacity(&word), NULL);
+ zassert_equal(bat->full_cap, word, "%d != %d", bat->full_cap, word);
+ zassert_equal(EC_SUCCESS, battery_cycle_count(&word), NULL);
+ zassert_equal(bat->cycle_count, word, "%d != %d",
+ bat->cycle_count, word);
+ zassert_equal(EC_SUCCESS, battery_design_capacity(&word), NULL);
+ zassert_equal(bat->design_cap, word, "%d != %d", bat->design_cap, word);
+ zassert_equal(EC_SUCCESS, battery_design_voltage(&word), NULL);
+ zassert_equal(bat->design_mv, word, "%d != %d", bat->design_mv, word);
+ zassert_equal(EC_SUCCESS, battery_serial_number(&word), NULL);
+ zassert_equal(bat->sn, word, "%d != %d", bat->sn, word);
+ zassert_equal(EC_SUCCESS, get_battery_manufacturer_name(block, 32),
+ NULL);
+ zassert_mem_equal(block, bat->mf_name, bat->mf_name_len,
+ "%s != %s", block, bat->mf_name);
+ zassert_equal(EC_SUCCESS, battery_device_name(block, 32), NULL);
+ zassert_mem_equal(block, bat->dev_name, bat->dev_name_len,
+ "%s != %s", block, bat->dev_name);
+ zassert_equal(EC_SUCCESS, battery_device_chemistry(block, 32), NULL);
+ zassert_mem_equal(block, bat->dev_chem, bat->dev_chem_len,
+ "%s != %s", block, bat->dev_chem);
+ word = battery_get_avg_current();
+ zassert_equal(bat->avg_cur, word, "%d != %d", bat->avg_cur, word);
+
+ bat->avg_cur = 200;
+ expected = (bat->full_cap - bat->cap) * 60 / bat->avg_cur;
+ zassert_equal(EC_SUCCESS, battery_time_to_full(&word), NULL);
+ zassert_equal(expected, word, "%d != %d", expected, word);
+
+ bat->cur = -200;
+ expected = bat->cap * 60 / (-bat->cur);
+ zassert_equal(EC_SUCCESS, battery_run_time_to_empty(&word), NULL);
+ zassert_equal(expected, word, "%d != %d", expected, word);
+
+ bat->avg_cur = -200;
+ expected = bat->cap * 60 / (-bat->avg_cur);
+ zassert_equal(EC_SUCCESS, battery_time_to_empty(&word), NULL);
+ zassert_equal(expected, word, "%d != %d", expected, word);
+}
+
+/** Test battery status */
+static void test_battery_status(void)
+{
+ struct sbat_emul_bat_data *bat;
+ struct i2c_emul *emul;
+ int expected;
+ int status;
+
+ emul = sbat_emul_get_ptr(BATTERY_ORD);
+ bat = sbat_emul_get_bat_data(emul);
+
+ bat->status = 0;
+ bat->cur = -200;
+ bat->cap_alarm = 0;
+ bat->time_alarm = 0;
+ bat->cap = bat->full_cap / 2;
+ bat->error_code = STATUS_CODE_OVERUNDERFLOW;
+
+ expected = 0;
+ expected |= STATUS_DISCHARGING;
+ expected |= STATUS_CODE_OVERUNDERFLOW;
+
+ zassert_equal(EC_SUCCESS, battery_status(&status), NULL);
+ zassert_equal(expected, status, "%d != %d", expected, status);
+}
+
+/** Custom battery function which always fail */
+int fail_func(struct i2c_emul *emul, uint8_t *buf, int *len, int cmd,
+ void *data)
+{
+ return -EINVAL;
+}
+
+/** Test wait for stable function */
+static void test_battery_wait_for_stable(void)
+{
+ struct i2c_emul *emul;
+
+ emul = sbat_emul_get_ptr(BATTERY_ORD);
+
+ /* Should fail when read function always fail */
+ sbat_emul_set_custom_read_func(emul, fail_func, NULL);
+ zassert_equal(EC_ERROR_NOT_POWERED, battery_wait_for_stable(), NULL);
+
+ /* Should be ok with default handler */
+ sbat_emul_set_custom_read_func(emul, NULL, NULL);
+ zassert_equal(EC_SUCCESS, battery_wait_for_stable(), NULL);
+}
+
+/** Test manufacture date */
+static void test_battery_manufacture_date(void)
+{
+ struct sbat_emul_bat_data *bat;
+ struct i2c_emul *emul;
+ int day, month, year;
+ int exp_month = 5;
+ int exp_year = 2018;
+ int exp_day = 19;
+ uint16_t date;
+
+ emul = sbat_emul_get_ptr(BATTERY_ORD);
+ bat = sbat_emul_get_bat_data(emul);
+
+ date = sbat_emul_date_to_word(exp_day, exp_month, exp_year);
+ bat->mf_date = date;
+
+ zassert_equal(EC_SUCCESS, battery_manufacture_date(&year, &month, &day),
+ NULL);
+ zassert_equal(exp_day, day, "%d != %d", exp_day, day);
+ zassert_equal(exp_month, month, "%d != %d", exp_month, month);
+ zassert_equal(exp_year, year, "%d != %d", exp_year, year);
+}
+
+/** Test time at rate */
+static void test_battery_time_at_rate(void)
+{
+ struct sbat_emul_bat_data *bat;
+ struct i2c_emul *emul;
+ int expect_time;
+ int minutes;
+ int rate;
+
+ emul = sbat_emul_get_ptr(BATTERY_ORD);
+ bat = sbat_emul_get_bat_data(emul);
+
+ /* 3000mAh at rate 300mA will be discharged in 10h */
+ bat->cap = 3000;
+ rate = -300;
+ expect_time = 600;
+
+ zassert_equal(EC_SUCCESS, battery_time_at_rate(rate, &minutes), NULL);
+ zassert_equal(expect_time, minutes, "%d != %d", expect_time, minutes);
+
+ /* 1000mAh at rate 1000mA will be charged in 1h */
+ bat->cap = bat->full_cap - 1000;
+ rate = 1000;
+ /* battery_time_at_rate report time to full as negative number */
+ expect_time = -60;
+
+ zassert_equal(EC_SUCCESS, battery_time_at_rate(rate, &minutes), NULL);
+ zassert_equal(expect_time, minutes, "%d != %d", expect_time, minutes);
+}
+
+/** Parameter for fail_cmd_func */
+struct fail_cmd_data {
+ int cmd;
+};
+
+/** Custom battery function which fail on specific command */
+int fail_cmd_func(struct i2c_emul *emul, uint8_t *buf, int *len, int cmd,
+ void *data)
+{
+ struct fail_cmd_data *p = data;
+
+ if (p->cmd == cmd)
+ return -EINVAL;
+
+ /* Use default handler */
+ return 1;
+}
+
+/** Test battery get params */
+static void test_battery_get_params(void)
+{
+ struct sbat_emul_bat_data *bat;
+ struct fail_cmd_data func_data;
+ struct batt_params batt;
+ struct i2c_emul *emul;
+ int flags;
+
+ emul = sbat_emul_get_ptr(BATTERY_ORD);
+ bat = sbat_emul_get_bat_data(emul);
+
+ /* Battery wants to charge */
+ bat->desired_charg_cur = 1000;
+ bat->desired_charg_volt = 5000;
+
+ /* Use function which allows to fail for specific command */
+ sbat_emul_set_custom_read_func(emul, fail_cmd_func, &func_data);
+
+ /* Fail temperature read */
+ func_data.cmd = SB_TEMPERATURE;
+ flags = BATT_FLAG_WANT_CHARGE | BATT_FLAG_RESPONSIVE |
+ BATT_FLAG_BAD_TEMPERATURE;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail state of charge read; want charge cannot be set */
+ func_data.cmd = SB_RELATIVE_STATE_OF_CHARGE;
+ flags = BATT_FLAG_RESPONSIVE | BATT_FLAG_BAD_STATE_OF_CHARGE;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail voltage read */
+ func_data.cmd = SB_VOLTAGE;
+ flags = BATT_FLAG_WANT_CHARGE | BATT_FLAG_RESPONSIVE |
+ BATT_FLAG_BAD_VOLTAGE;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail current read */
+ func_data.cmd = SB_CURRENT;
+ flags = BATT_FLAG_WANT_CHARGE | BATT_FLAG_RESPONSIVE |
+ BATT_FLAG_BAD_CURRENT;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail average current read */
+ func_data.cmd = SB_AVERAGE_CURRENT;
+ flags = BATT_FLAG_WANT_CHARGE | BATT_FLAG_RESPONSIVE |
+ BATT_FLAG_BAD_AVERAGE_CURRENT;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail charging voltage read; want charge cannot be set */
+ func_data.cmd = SB_CHARGING_VOLTAGE;
+ flags = BATT_FLAG_RESPONSIVE | BATT_FLAG_BAD_DESIRED_VOLTAGE;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail charging voltage read; want charge cannot be set */
+ func_data.cmd = SB_CHARGING_CURRENT;
+ flags = BATT_FLAG_RESPONSIVE | BATT_FLAG_BAD_DESIRED_CURRENT;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail remaining capacity read */
+ func_data.cmd = SB_REMAINING_CAPACITY;
+ flags = BATT_FLAG_WANT_CHARGE | BATT_FLAG_RESPONSIVE |
+ BATT_FLAG_BAD_REMAINING_CAPACITY;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail full capacity read */
+ func_data.cmd = SB_FULL_CHARGE_CAPACITY;
+ flags = BATT_FLAG_WANT_CHARGE | BATT_FLAG_RESPONSIVE |
+ BATT_FLAG_BAD_FULL_CAPACITY;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail status read */
+ func_data.cmd = SB_BATTERY_STATUS;
+ flags = BATT_FLAG_WANT_CHARGE | BATT_FLAG_RESPONSIVE |
+ BATT_FLAG_BAD_STATUS;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Fail all */
+ sbat_emul_set_custom_read_func(emul, fail_func, NULL);
+ flags = BATT_FLAG_BAD_ANY;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+
+ /* Use default handler, everything should be ok */
+ sbat_emul_set_custom_read_func(emul, NULL, NULL);
+ flags = BATT_FLAG_WANT_CHARGE | BATT_FLAG_RESPONSIVE;
+ battery_get_params(&batt);
+ zassert_equal(flags, batt.flags, "0x%x != 0x%x", flags, batt.flags);
+}
+
+void test_suite_smart_battery(void)
+{
+ ztest_test_suite(smart_battery,
+ ztest_user_unit_test(test_battery_getters),
+ ztest_user_unit_test(test_battery_status),
+ ztest_user_unit_test(test_battery_wait_for_stable),
+ ztest_user_unit_test(test_battery_manufacture_date),
+ ztest_user_unit_test(test_battery_time_at_rate),
+ ztest_user_unit_test(test_battery_get_params));
+ ztest_run_test_suite(smart_battery);
+}