Files
OpenCellular/test/button.c
Aseda Aboagye 34a97f50d5 buttons: Make buttons[] common.
Nearly every board had a buttons array defined in which its contents had
the standard volume buttons.  This commit creates a single common
buttons array that can contain the standard volume buttons and recovery
buttons.  If a board has volume up and down buttons, they can simply
define CONFIG_VOLUME_BUTTONS and it will populate the buttons array with
the standard definition.  The buttons are active low and have a 30 ms
debounce period.  Similiarly, if a board has a dedicated recovery
button, defining CONFIG_DEDICATED_RECOVERY_BUTTON will also populate the
buttons array with a recovery button.

BUG=chromium:783371
BRANCH=None
TEST=make -j buildall.
TEST=Flash a device with CONFIG_VOLUME_BUTTONS, verify pressing volume
buttons still work.

Change-Id: Ie5d63670ca4c6b146ec8ffb64d40ea9ce437b913
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/773794
Commit-Ready: Aseda Aboagye <aaboagye@chromium.org>
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-by: Shawn N <shawnn@chromium.org>
2017-11-17 20:18:38 -08:00

182 lines
4.5 KiB
C

/* Copyright (c) 2014 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.
*
* Test non-keyboard buttons.
*
* Using GPIOS and buttons[] defined in board/host/board.c
* Volume down is active low with a debounce time of 30 mSec.
* Volume up is active high with a debounce time of 60 mSec.
*
*/
#include "button.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
#include "test_util.h"
#include "timer.h"
#include "keyboard_protocol.h"
#define UNCHANGED -1
static const struct button_config *button_vol_down =
&buttons[BUTTON_VOLUME_DOWN];
static const struct button_config *button_vol_up = &buttons[BUTTON_VOLUME_UP];
static int button_state[BUTTON_COUNT];
/*
* Callback from the button handling logic.
* This is normally implemented by a keyboard protocol handler.
*/
void keyboard_update_button(enum keyboard_button_type button, int is_pressed)
{
int i;
for (i = 0; i < BUTTON_COUNT; i++) {
if (buttons[i].type == button) {
button_state[i] = is_pressed;
break;
}
}
}
/* Test pressing a button */
static int test_button_press(void)
{
gpio_set_level(button_vol_down->gpio, 0);
msleep(100);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 1);
return EC_SUCCESS;
}
/* Test releasing a button */
static int test_button_release(void)
{
gpio_set_level(button_vol_up->gpio, 0);
msleep(100);
gpio_set_level(button_vol_up->gpio, 1);
msleep(100);
TEST_ASSERT(button_state[BUTTON_VOLUME_UP] == 0);
return EC_SUCCESS;
}
/* A press shorter than the debounce time should not trigger an update */
static int test_button_debounce_short_press(void)
{
gpio_set_level(button_vol_down->gpio, 0);
msleep(10);
gpio_set_level(button_vol_down->gpio, 1);
msleep(100);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == UNCHANGED);
return EC_SUCCESS;
}
/* A short bounce while pressing should still result in a button press */
static int test_button_debounce_short_bounce(void)
{
gpio_set_level(button_vol_down->gpio, 0);
msleep(10);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == UNCHANGED);
gpio_set_level(button_vol_down->gpio, 1);
msleep(10);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == UNCHANGED);
gpio_set_level(button_vol_down->gpio, 0);
msleep(20);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == UNCHANGED);
msleep(20);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 1);
return EC_SUCCESS;
}
/* Button level must be stable for the entire debounce interval */
static int test_button_debounce_stability(void)
{
gpio_set_level(button_vol_down->gpio, 0);
msleep(20);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == UNCHANGED);
gpio_set_level(button_vol_down->gpio, 1);
msleep(20);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == UNCHANGED);
gpio_set_level(button_vol_down->gpio, 0);
msleep(20);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == UNCHANGED);
msleep(20);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 1);
msleep(60);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 1);
gpio_set_level(button_vol_down->gpio, 1);
msleep(20);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 1);
msleep(20);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 0);
msleep(60);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 0);
return EC_SUCCESS;
}
/* Test pressing both buttons at different times */
static int test_button_press_both(void)
{
gpio_set_level(button_vol_down->gpio, 0);
msleep(10);
gpio_set_level(button_vol_up->gpio, 0);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == UNCHANGED);
TEST_ASSERT(button_state[BUTTON_VOLUME_UP] == UNCHANGED);
msleep(30);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 1);
TEST_ASSERT(button_state[BUTTON_VOLUME_UP] == UNCHANGED);
msleep(40);
TEST_ASSERT(button_state[BUTTON_VOLUME_DOWN] == 1);
TEST_ASSERT(button_state[BUTTON_VOLUME_UP] == 1);
return EC_SUCCESS;
}
static void button_test_init(void)
{
int i;
ccprintf("[%T Setting button GPIOs to inactive state.]\n");
for (i = 0; i < BUTTON_COUNT; i++)
gpio_set_level(buttons[i].gpio,
!(buttons[i].flags & BUTTON_FLAG_ACTIVE_HIGH));
msleep(100);
for (i = 0; i < BUTTON_COUNT; i++)
button_state[i] = UNCHANGED;
}
void run_test(void)
{
test_reset();
button_init();
button_test_init();
RUN_TEST(test_button_press);
button_test_init();
RUN_TEST(test_button_release);
button_test_init();
RUN_TEST(test_button_debounce_short_press);
button_test_init();
RUN_TEST(test_button_debounce_short_bounce);
button_test_init();
RUN_TEST(test_button_debounce_stability);
button_test_init();
RUN_TEST(test_button_press_both);
test_print_result();
}