From b02c7b461740c457c6904a5d9d9f445afaa849cb Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Sun, 5 May 2013 14:31:53 +0800 Subject: Add test for keyboard MKBP protocol A test that check keyboard MKBP module using keyboard scanning module and host commands. BUG=chrome-os-partner:19236 TEST=Pass the test BRANCH=None Change-Id: Ic22a2c8f3069d8e72c1222882073d428b733bca3 Signed-off-by: Vic Yang Reviewed-on: https://gerrit.chromium.org/gerrit/50132 --- test/build.mk | 1 + test/kb_mkbp.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/kb_mkbp.tasklist | 19 ++++ 3 files changed, 265 insertions(+) create mode 100644 test/kb_mkbp.c create mode 100644 test/kb_mkbp.tasklist diff --git a/test/build.mk b/test/build.mk index ead4deab75..7adf96f441 100644 --- a/test/build.mk +++ b/test/build.mk @@ -25,6 +25,7 @@ test-list-$(BOARD_link)= test-list-$(BOARD_slippy)= flash-y=flash.o +kb_mkbp-y=kb_mkbp.o kb_scan-y=kb_scan.o mutex-y=mutex.o pingpong-y=pingpong.o diff --git a/test/kb_mkbp.c b/test/kb_mkbp.c new file mode 100644 index 0000000000..57a4d9cc67 --- /dev/null +++ b/test/kb_mkbp.c @@ -0,0 +1,245 @@ +/* Copyright (c) 2013 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. + * + * Tests for keyboard MKBP protocol + */ + +#include "common.h" +#include "console.h" +#include "ec_commands.h" +#include "gpio.h" +#include "host_command.h" +#include "keyboard_mkbp.h" +#include "keyboard_protocol.h" +#include "keyboard_scan.h" +#include "util.h" + +static int error_count; + +static uint8_t state[KEYBOARD_COLS]; +static int ec_int_level; + +static const char *action[2] = {"release", "press"}; + +/*****************************************************************************/ +/* Mock functions */ + +void host_send_response(struct host_cmd_handler_args *args) +{ + /* Do nothing */ +} + +void gpio_set_level(enum gpio_signal signal, int level) +{ + if (signal == GPIO_EC_INT) + ec_int_level = !!level; +} + +/*****************************************************************************/ +/* Test utilities */ + +#define RUN_TEST(n) \ + do { \ + ccprintf("Running %s...", #n); \ + cflush(); \ + if (n() == EC_SUCCESS) { \ + ccputs("OK\n"); \ + } else { \ + ccputs("Fail\n"); \ + error_count++; \ + } \ + } while (0) + +#define TEST_ASSERT(n) \ + do { \ + if (!(n)) \ + return EC_ERROR_UNKNOWN; \ + } while (0) + +#define FIFO_EMPTY() (ec_int_level == 1) +#define FIFO_NOT_EMPTY() (ec_int_level == 0) + +void clear_state(void) +{ + memset(state, 0xff, KEYBOARD_COLS); +} + +void set_state(int c, int r, int pressed) +{ + uint8_t mask = (1 << r); + + if (pressed) + state[c] &= ~mask; + else + state[c] |= mask; +} + +int press_key(int c, int r, int pressed) +{ + ccprintf("Input %s (%d, %d)\n", action[pressed], c, r); + set_state(c, r, pressed); + return keyboard_fifo_add(state); +} + +int verify_key(int c, int r, int pressed) +{ + struct host_cmd_handler_args args; + uint8_t mkbp_out[KEYBOARD_COLS]; + int i; + + if (c >= 0 && r >= 0) { + ccprintf("Verify %s (%d, %d)\n", action[pressed], c, r); + set_state(c, r, pressed); + } else { + ccprintf("Verify last state\n"); + } + + args.version = 0; + args.command = EC_CMD_MKBP_STATE; + args.params = NULL; + args.params_size = 0; + args.response = mkbp_out; + args.response_max = sizeof(mkbp_out); + args.response_size = 0; + + if (host_command_process(&args) != EC_RES_SUCCESS) + return 0; + + for (i = 0; i < KEYBOARD_COLS; ++i) + if (mkbp_out[i] != state[i]) + return 0; + + return 1; +} + +int mkbp_config(struct ec_params_mkbp_set_config params) +{ + struct host_cmd_handler_args args; + + args.version = 0; + args.command = EC_CMD_MKBP_SET_CONFIG; + args.params = ¶ms; + args.params_size = sizeof(params); + args.response = NULL; + args.response_max = 0; + args.response_size = 0; + + return host_command_process(&args) == EC_RES_SUCCESS; +} + +int set_fifo_size(int sz) +{ + struct ec_params_mkbp_set_config params; + + params.config.valid_mask = EC_MKBP_VALID_FIFO_MAX_DEPTH; + params.config.valid_flags = 0; + params.config.fifo_max_depth = sz; + + return mkbp_config(params); +} + +int set_kb_scan_enabled(int enabled) +{ + struct ec_params_mkbp_set_config params; + + params.config.valid_mask = 0; + params.config.valid_flags = EC_MKBP_FLAGS_ENABLE; + params.config.flags = (enabled ? EC_MKBP_FLAGS_ENABLE : 0); + + return mkbp_config(params); +} + +/*****************************************************************************/ +/* Tests */ + +int single_key_press(void) +{ + keyboard_clear_buffer(); + clear_state(); + TEST_ASSERT(press_key(0, 0, 1) == EC_SUCCESS); + TEST_ASSERT(FIFO_NOT_EMPTY()); + TEST_ASSERT(press_key(0, 0, 0) == EC_SUCCESS); + TEST_ASSERT(FIFO_NOT_EMPTY()); + + clear_state(); + TEST_ASSERT(verify_key(0, 0, 1)); + TEST_ASSERT(FIFO_NOT_EMPTY()); + TEST_ASSERT(verify_key(0, 0, 0)); + TEST_ASSERT(FIFO_EMPTY()); + + return EC_SUCCESS; +} + +int test_fifo_size(void) +{ + keyboard_clear_buffer(); + clear_state(); + TEST_ASSERT(set_fifo_size(1)); + TEST_ASSERT(press_key(0, 0, 1) == EC_SUCCESS); + TEST_ASSERT(press_key(0, 0, 0) == EC_ERROR_OVERFLOW); + + clear_state(); + TEST_ASSERT(verify_key(0, 0, 1)); + TEST_ASSERT(FIFO_EMPTY()); + + /* Restore FIFO size */ + TEST_ASSERT(set_fifo_size(100)); + + return EC_SUCCESS; +} + +int test_enable(void) +{ + keyboard_clear_buffer(); + clear_state(); + TEST_ASSERT(set_kb_scan_enabled(0)); + TEST_ASSERT(press_key(0, 0, 1) == EC_SUCCESS); + TEST_ASSERT(FIFO_EMPTY()); + + TEST_ASSERT(set_kb_scan_enabled(1)); + TEST_ASSERT(press_key(0, 0, 1) == EC_SUCCESS); + TEST_ASSERT(FIFO_NOT_EMPTY()); + TEST_ASSERT(verify_key(0, 0, 1)); + + return EC_SUCCESS; +} + +int fifo_underrun(void) +{ + keyboard_clear_buffer(); + clear_state(); + TEST_ASSERT(press_key(0, 0, 1) == EC_SUCCESS); + + clear_state(); + TEST_ASSERT(verify_key(0, 0, 1)); + + /* When FIFO under run, host command reutns last known state */ + TEST_ASSERT(verify_key(-1, -1, -1)); + + return EC_SUCCESS; +} + +void run_test(void) +{ + error_count = 0; + ec_int_level = 1; + + RUN_TEST(single_key_press); + RUN_TEST(test_fifo_size); + RUN_TEST(test_enable); + RUN_TEST(fifo_underrun); + + if (error_count == 0) + ccprintf("Pass!\n"); + else + ccprintf("Fail!\n"); +} + +static int command_run_test(int argc, char **argv) +{ + run_test(); + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(runtest, command_run_test, + NULL, NULL, NULL); diff --git a/test/kb_mkbp.tasklist b/test/kb_mkbp.tasklist new file mode 100644 index 0000000000..2368d7bc52 --- /dev/null +++ b/test/kb_mkbp.tasklist @@ -0,0 +1,19 @@ +/* Copyright (c) 2013 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. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_TEST(n, r, d, s) where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + * 's' is the stack size in bytes; must be a multiple of 8 + */ +#define CONFIG_TEST_TASK_LIST \ + TASK_TEST(KEYSCAN, keyboard_scan_task, NULL, 256) \ + TASK_TEST(CHIPSET, chipset_task, NULL, TASK_STACK_SIZE) -- cgit v1.2.1