diff options
author | Tristan Honscheid <honscheid@google.com> | 2023-04-12 15:00:13 -0600 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-04-21 07:25:40 +0000 |
commit | b5e2ea8b0dfa7a190783978153bcafb1ae87a3d0 (patch) | |
tree | fc686f17ba43c1cb4e48cb499dc19e011630adb3 | |
parent | 7380b56e8cdbcb8516e767d65eb05330bedbaf60 (diff) | |
download | chrome-ec-b5e2ea8b0dfa7a190783978153bcafb1ae87a3d0.tar.gz |
zephyr: test: Set up OCPC test project and check console commands
Add a new test binary that has a Nissa-style Kconfig and devicetree,
complete with chargers. Use this configuration to run OCPC
(common/ocpc.c) and test this module, which has never previously been
used in our tests.
This CL contains tests for ocpc.c's console commands.
BRANCH=None
BUG=b:276805061
TEST=./twister -T zephyr/test/ocpc
Change-Id: I34dbe1abcae98d8ca9aa9613dddf3b4ba2838792
Signed-off-by: Tristan Honscheid <honscheid@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4438529
Commit-Queue: Peter Marheine <pmarheine@chromium.org>
Reviewed-by: Peter Marheine <pmarheine@chromium.org>
-rw-r--r-- | common/ocpc.c | 13 | ||||
-rw-r--r-- | include/ocpc.h | 22 | ||||
-rw-r--r-- | zephyr/emul/emul_isl923x.c | 12 | ||||
-rw-r--r-- | zephyr/test/ocpc/CMakeLists.txt | 14 | ||||
-rw-r--r-- | zephyr/test/ocpc/boards/native_posix.overlay | 171 | ||||
-rw-r--r-- | zephyr/test/ocpc/prj.conf | 40 | ||||
-rw-r--r-- | zephyr/test/ocpc/src/fakes.c | 43 | ||||
-rw-r--r-- | zephyr/test/ocpc/src/main.c | 23 | ||||
-rw-r--r-- | zephyr/test/ocpc/src/ocpc.c | 151 | ||||
-rw-r--r-- | zephyr/test/ocpc/testcase.yaml | 4 |
10 files changed, 492 insertions, 1 deletions
diff --git a/common/ocpc.c b/common/ocpc.c index a176eea075..6ed15b1b1b 100644 --- a/common/ocpc.c +++ b/common/ocpc.c @@ -701,7 +701,7 @@ void ocpc_reset(struct ocpc_data *ocpc) ocpc_precharge_enable(false); } -static void ocpc_set_pid_constants(void) +test_export_static void ocpc_set_pid_constants(void) { ocpc_get_pid_constants(&k_p, &k_p_div, &k_i, &k_i_div, &k_d, &k_d_div); } @@ -800,3 +800,14 @@ static int command_ocpcdrvlmt(int argc, const char **argv) } DECLARE_SAFE_CONSOLE_COMMAND(ocpcdrvlmt, command_ocpcdrvlmt, "[<drive_limit>]", "Show/Set drive limit for OCPC PID loop"); + +#ifdef TEST_BUILD +int test_ocpc_get_viz_output(void) +{ + return viz_output; +} +int test_ocpc_get_debug_output(void) +{ + return debug_output; +} +#endif diff --git a/include/ocpc.h b/include/ocpc.h index 20ec35c797..3b95556fc1 100644 --- a/include/ocpc.h +++ b/include/ocpc.h @@ -86,4 +86,26 @@ void ocpc_reset(struct ocpc_data *ocpc); * @param ocpc: Pointer to OCPC data */ __override_proto void board_ocpc_init(struct ocpc_data *ocpc); + +#ifdef TEST_BUILD +/** + * @brief Force a reload of PID constants by calling ocpc_get_pid_constants(). + */ +void ocpc_set_pid_constants(void); + +/** + * @brief Return the value of viz_output + * + * @return int + */ +int test_ocpc_get_viz_output(void); + +/** + * @brief Return the value of debug_output + * + * @return int + */ +int test_ocpc_get_debug_output(void); +#endif + #endif /* __CROS_EC_OCPC_H */ diff --git a/zephyr/emul/emul_isl923x.c b/zephyr/emul/emul_isl923x.c index bd7b8b54f5..e934da1660 100644 --- a/zephyr/emul/emul_isl923x.c +++ b/zephyr/emul/emul_isl923x.c @@ -58,6 +58,9 @@ LOG_MODULE_REGISTER(isl923x_emul, CONFIG_ISL923X_EMUL_LOG_LEVEL); /** Mask used for the control 8 register */ #define REG_CONTROL8_MASK GENMASK(15, 0) +/** Mask used for the control 10 register */ +#define REG_CONTROL10_MASK GENMASK(15, 0) + /** Mask used for the AC PROCHOT register */ #define REG_PROCHOT_AC_MASK GENMASK(12, 7) @@ -100,6 +103,8 @@ struct isl923x_emul_data { uint16_t control_4_reg; /** Emulated control 8 register (RAA489000-only) */ uint16_t control_8_reg; + /** Emulated control 10 register (RAA48900-only) */ + uint16_t control_10_reg; /** Emulated info 2 reg */ uint16_t info_2_reg; /** Emulated AC PROCHOT register */ @@ -267,6 +272,9 @@ static int isl923x_emul_read_byte(const struct emul *emul, int reg, case RAA489000_REG_CONTROL8: READ_REG_16(data->control_8_reg, bytes, val); break; + case RAA489000_REG_CONTROL10: + READ_REG_16(data->control_10_reg, bytes, val); + break; case ISL9238_REG_INFO2: READ_REG_16(data->info_2_reg, bytes, val); break; @@ -360,6 +368,10 @@ static int isl923x_emul_write_byte(const struct emul *emul, int reg, WRITE_REG_16(data->control_8_reg, bytes, val, REG_CONTROL8_MASK); break; + case RAA489000_REG_CONTROL10: + WRITE_REG_16(data->control_10_reg, bytes, val, + REG_CONTROL10_MASK); + break; case ISL9238_REG_INFO2: __ASSERT(false, "Write to read-only reg ISL9238_REG_INFO2"); break; diff --git a/zephyr/test/ocpc/CMakeLists.txt b/zephyr/test/ocpc/CMakeLists.txt new file mode 100644 index 0000000000..2a46e14245 --- /dev/null +++ b/zephyr/test/ocpc/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +cmake_minimum_required(VERSION 3.13.1) +find_package(Zephyr REQUIRED HINTS "${ZEPHYR_BASE}") +project(ocpc) + +# Include FFF fakes +add_subdirectory(${PLATFORM_EC}/zephyr/test/test_utils test_utils) + +target_sources(app PRIVATE src/fakes.c) +target_sources(app PRIVATE src/main.c) +target_sources(app PRIVATE src/ocpc.c) diff --git a/zephyr/test/ocpc/boards/native_posix.overlay b/zephyr/test/ocpc/boards/native_posix.overlay new file mode 100644 index 0000000000..d581c38af1 --- /dev/null +++ b/zephyr/test/ocpc/boards/native_posix.overlay @@ -0,0 +1,171 @@ +/* Copyright 2020 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <board-overlays/native_posix.dts> +#include <npcx_emul.dts> +#include <dt-bindings/usb_pd_tcpm.h> +#include <dt-bindings/usbc_mux.h> + +/ { + batteries { + default_battery: lgc { + compatible = "lgc,ac17a8m", "battery-smart"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c_ctrl3>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c_ctrl5>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c_ctrl7>; + enum-names = "I2C_PORT_BATTERY", "I2C_PORT_VIRTUAL_BATTERY"; + }; + }; + + named-adc-channels { + compatible = "named-adc-channels"; + + vbus { + enum-name = "ADC_VBUS"; + io-channels = <&adc0 1>; + /* Measure VBUS through a 1/10 voltage divider */ + mul = <10>; + }; + }; + + aliases { + gpio-wp = &gpio_wp; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_wp: ec-flash-wp-odl { + gpios = <&gpio0 0 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpio0 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpio0 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_lid_open: lid_open { + gpios = <&gpio0 3 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + chg = <&isl923x_emul_0>; + tcpc = <&tcpci_emul_0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + chg = <&isl923x_emul_1>; + tcpc = <&tcpci_emul_1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + }; + + adc0: adc { + compatible = "zephyr,adc-emul"; + nchannels = <6>; + ref-internal-mv = <3300>; + #io-channel-cells = <1>; + status = "okay"; + }; +}; + +&i2c_ctrl7 { + battery: sb@b { + compatible = "zephyr,smart-battery-emul"; + reg = <0xb>; + cycle-count = <99>; + version = "BATTERY_SPEC_VER_1_1_WITH_PEC"; + /* Real battery voltages are multiples of 4.4V. */ + desired-charg-volt = <5000>; + desired-charg-cur = <1000>; + mf-name = "LGC"; + dev-name = "AC17A8M"; + }; +}; + +&i2c_ctrl3 { + tcpci_emul_0: tcpci_emul@82 { + compatible = "renesas,raa489000", "cros,i2c-mock"; + status = "okay"; + reg = <0x82>; + }; + isl923x_emul_0: isl923x@9 { + compatible = "cros,isl923x-emul"; + status = "okay"; + reg = <0x9>; + battery = <&battery>; + }; +}; + +&i2c_ctrl5 { + tcpci_emul_1: tcpci_emul@82 { + compatible = "renesas,raa489000", "cros,i2c-mock"; + status = "okay"; + reg = <0x82>; + }; + isl923x_emul_1: isl923x@9 { + compatible = "cros,isl923x-emul"; + status = "okay"; + reg = <0x9>; + battery = <&battery>; + }; +};
\ No newline at end of file diff --git a/zephyr/test/ocpc/prj.conf b/zephyr/test/ocpc/prj.conf new file mode 100644 index 0000000000..adfb4b5fae --- /dev/null +++ b/zephyr/test/ocpc/prj.conf @@ -0,0 +1,40 @@ +# Copyright 2023 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +# Basic EC functions +CONFIG_SHIMMED_TASKS=y +CONFIG_CROS_EC=y +CONFIG_PLATFORM_EC=y +CONFIG_PLATFORM_EC_HOOKS=y +CONFIG_PLATFORM_EC_HOSTCMD=y + +# Unwanted features +CONFIG_PLATFORM_EC_VBOOT_HASH=n +CONFIG_PLATFORM_EC_BACKLIGHT_LID=n +CONFIG_PLATFORM_EC_USBC_PPC=n +CONFIG_PLATFORM_EC_USB_CHARGER=n + +# Power and charger-related +CONFIG_PLATFORM_EC_POWER_BUTTON=y +CONFIG_PLATFORM_EC_CHARGER=y +CONFIG_PLATFORM_EC_OCPC=y +CONFIG_PLATFORM_EC_OCPC_DEF_RBATT_MOHMS=22 +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR=10 +CONFIG_PLATFORM_EC_CHARGER_SENSE_RESISTOR_AC=10 +CONFIG_PLATFORM_EC_USB_PD_DISCHARGE=n +CONFIG_PLATFORM_EC_USB_PD_5V_EN_CUSTOM=y +CONFIG_PLATFORM_EC_OCPC_DEF_DRIVELIMIT_MILLIVOLTS=200 +CONFIG_PLATFORM_EC_I2C_VIRTUAL_BATTERY=y +CONFIG_PLATFORM_EC_CHARGER_RAA489000=y +CONFIG_PLATFORM_EC_USB_PD_TCPM_RAA489000=y +CONFIG_PLATFORM_EC_BATTERY_FUEL_GAUGE=y + +# Console +CONFIG_SHELL_BACKEND_DUMMY=y +CONFIG_SHELL_BACKEND_SERIAL=n +CONFIG_SERIAL=y +CONFIG_RING_BUFFER=y diff --git a/zephyr/test/ocpc/src/fakes.c b/zephyr/test/ocpc/src/fakes.c new file mode 100644 index 0000000000..0ff17ecddc --- /dev/null +++ b/zephyr/test/ocpc/src/fakes.c @@ -0,0 +1,43 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +int battery_is_present(void) +{ + return 1; +} + +int board_set_active_charge_port(int port) +{ + return 0; +} + +int pd_set_power_supply_ready(int port) +{ + return 0; +} + +void pd_power_supply_reset(int port) +{ +} + +int board_is_sourcing_vbus(int port) +{ + return 0; +} + +int pd_check_vconn_swap(int port) +{ + return 0; +} + +int extpower_is_present(void) +{ + return 0; +} + +int lid_is_open(void) +{ + return 0; +} diff --git a/zephyr/test/ocpc/src/main.c b/zephyr/test/ocpc/src/main.c new file mode 100644 index 0000000000..5fa0a3b080 --- /dev/null +++ b/zephyr/test/ocpc/src/main.c @@ -0,0 +1,23 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_app_main.h" +#include "hooks.h" + +#include <zephyr/kernel.h> +#include <zephyr/ztest.h> + +void test_main(void) +{ + ec_app_main(); + + k_sleep(K_MSEC(1000)); + + /* Run all the suites that depend on main being called */ + ztest_run_test_suites(NULL); + + /* Check that every suite ran */ + ztest_verify_all_test_suites_ran(); +} diff --git a/zephyr/test/ocpc/src/ocpc.c b/zephyr/test/ocpc/src/ocpc.c new file mode 100644 index 0000000000..004d0c2408 --- /dev/null +++ b/zephyr/test/ocpc/src/ocpc.c @@ -0,0 +1,151 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "console.h" +#include "host_command.h" +#include "ocpc.h" + +#include <string.h> + +#include <zephyr/drivers/emul.h> +#include <zephyr/fff.h> +#include <zephyr/shell/shell_dummy.h> +#include <zephyr/ztest.h> + +FAKE_VOID_FUNC(ocpc_get_pid_constants, int *, int *, int *, int *, int *, + int *); + +static int test_kp, test_kp_div, test_ki, test_ki_div, test_kd, test_kd_div; + +static void get_pid_constants_custom_fake(int *kp, int *kp_div, int *ki, + int *ki_div, int *kd, int *kd_div) +{ + *kp = test_kp; + *kp_div = test_kp_div; + *ki = test_ki; + *ki_div = test_ki_div; + *kd = test_kd; + *kd_div = test_kd_div; +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcpid__read) +{ + const char *outbuffer; + size_t buffer_size; + + /* With no args, print current state */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcpid")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + /* Check for some expected lines */ + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "Kp = 1 / 4"), "Output was: `%s`", + outbuffer); + zassert_ok(!strstr(outbuffer, "Ki = 1 / 15"), "Output was: `%s`", + outbuffer); + zassert_ok(!strstr(outbuffer, "Kd = 1 / 10"), "Output was: `%s`", + outbuffer); +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcpid__write) +{ + const char *outbuffer; + size_t buffer_size; + + /* Call a few times to change each parameter and examine output of final + * command. + */ + + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcpid p 2 3")); + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcpid i 4 5")); + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcpid d 6 7")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "Kp = 2 / 3"), "Output was: `%s`", + outbuffer); + zassert_ok(!strstr(outbuffer, "Ki = 4 / 5"), "Output was: `%s`", + outbuffer); + zassert_ok(!strstr(outbuffer, "Kd = 6 / 7"), "Output was: `%s`", + outbuffer); +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcpid__bad_param) +{ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(get_ec_shell(), "ocpcpid y 0 0")); +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcdrvlmt) +{ + const char *outbuffer; + size_t buffer_size; + + /* Set to 100mV */ + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdrvlmt 100")); + + /* Read back and verify */ + shell_backend_dummy_clear_output(get_ec_shell()); + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdrvlmt")); + outbuffer = + shell_backend_dummy_get_output(get_ec_shell(), &buffer_size); + + zassert_true(buffer_size > 0); + zassert_ok(!strstr(outbuffer, "Drive Limit = 100"), "Output was: `%s`", + outbuffer); +} + +ZTEST_USER(ocpc, test_consolecmd_ocpcdebug) +{ + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdebug ena")); + zassert_true(test_ocpc_get_debug_output()); + zassert_false(test_ocpc_get_viz_output()); + + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdebug dis")); + zassert_false(test_ocpc_get_debug_output()); + zassert_false(test_ocpc_get_viz_output()); + + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdebug viz")); + zassert_false(test_ocpc_get_debug_output()); + zassert_true(test_ocpc_get_viz_output()); + + zassert_ok(shell_execute_cmd(get_ec_shell(), "ocpcdebug all")); + zassert_true(test_ocpc_get_debug_output()); + zassert_true(test_ocpc_get_viz_output()); + + /* Bad param */ + zassert_equal(EC_ERROR_PARAM1, + shell_execute_cmd(get_ec_shell(), "ocpcdebug foo")); + + /* Missing param */ + zassert_equal(EC_ERROR_PARAM_COUNT, + shell_execute_cmd(get_ec_shell(), "ocpcdebug")); +} + +static void reset(void *fixture) +{ + ARG_UNUSED(fixture); + + /* Reset */ + RESET_FAKE(ocpc_get_pid_constants); + + /* Load values that match ocpc.c's defaults */ + test_kp = 1; + test_kp_div = 4; + test_ki = 1; + test_ki_div = 15; + test_kd = 1; + test_kd_div = 10; + + ocpc_get_pid_constants_fake.custom_fake = get_pid_constants_custom_fake; + + /* Force an update which will use the above parameters. */ + ocpc_set_pid_constants(); +} + +ZTEST_SUITE(ocpc, NULL, NULL, reset, reset, NULL); diff --git a/zephyr/test/ocpc/testcase.yaml b/zephyr/test/ocpc/testcase.yaml new file mode 100644 index 0000000000..31fa165ef1 --- /dev/null +++ b/zephyr/test/ocpc/testcase.yaml @@ -0,0 +1,4 @@ +common: + platform_allow: native_posix +tests: + ocpc.default: {} |