Add a test of charging state machine

This test checks charging state machine works correctly:
  - Charge when AC plugged. Discharge when AC unplugged.
  - Shutdown when over/under-temperature during discharging.
  - Stop charging when over/under-temperature during charging.

BUG=chrome-os-partner:10270
TEST=Test passed

Change-Id: I460645c70f5dcd30e258c43956ffe416c8bce906
Reviewed-on: https://gerrit.chromium.org/gerrit/26383
Reviewed-by: Rong Chang <rongchang@chromium.org>
Commit-Ready: Vic Yang <victoryang@chromium.org>
Tested-by: Vic Yang <victoryang@chromium.org>
This commit is contained in:
Vic Yang
2012-06-28 13:57:33 +08:00
committed by Gerrit
parent e4df521df5
commit d6086835e3
6 changed files with 322 additions and 1 deletions

102
common/mock_charger.c Normal file
View File

@@ -0,0 +1,102 @@
/* Copyright (c) 2012 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.
*
* Mock battery charger driver.
*/
#include "board.h"
#include "charger.h"
#include "console.h"
#include "common.h"
#include "smart_battery.h"
#include "uart.h"
#include "util.h"
static const struct charger_info mock_charger_info = {
.name = "MockCharger",
.voltage_max = 19200,
.voltage_min = 1024,
.voltage_step = 16,
.current_max = 8192,
.current_min = 128,
.current_step = 128,
.input_current_max = 8064,
.input_current_min = 128,
.input_current_step = 128,
};
#define OPTION_CHARGE_INHIBIT (1 << 0)
static uint32_t mock_option = 0;
static uint32_t mock_current = 0;
static uint32_t mock_voltage = 0;
const struct charger_info *charger_get_info(void)
{
return &mock_charger_info;
}
int charger_get_status(int *status)
{
*status = CHARGER_LEVEL_2;
if (mock_option & CHARGE_FLAG_INHIBIT_CHARGE)
*status |= CHARGER_CHARGE_INHIBITED;
return EC_SUCCESS;
}
int charger_set_mode(int mode)
{
if (mode & CHARGE_FLAG_INHIBIT_CHARGE)
mock_option |= OPTION_CHARGE_INHIBIT;
else
mock_option &= ~OPTION_CHARGE_INHIBIT;
return EC_SUCCESS;
}
int charger_get_current(int *current)
{
*current = mock_current;
return EC_SUCCESS;
}
int charger_set_current(int current)
{
const struct charger_info *info = charger_get_info();
if (current > 0 && current < info->current_min)
current = info->current_min;
if (current > info->current_max)
current = info->current_max;
mock_current = current;
uart_printf("Charger set current: %d\n", current);
return EC_SUCCESS;
}
int charger_get_voltage(int *voltage)
{
*voltage = mock_voltage;
return EC_SUCCESS;
}
int charger_set_voltage(int voltage)
{
mock_voltage = voltage;
uart_printf("Charger set voltage: %d\n", voltage);
return EC_SUCCESS;
}
int charger_post_init(void)
{
mock_current = CONFIG_CHARGER_INPUT_CURRENT;
return EC_SUCCESS;
}

View File

@@ -0,0 +1,105 @@
#include "console.h"
#include "smart_battery.h"
#include "smart_battery_stub.h"
#include "uart.h"
#include "util.h"
static int mock_temperature = 2981;
static int mock_desire_voltage = 7000;
static int mock_desire_current = 3000;
static int mock_voltage = 6000;
static int mock_current = 3000;
int sb_read(int cmd, int *param)
{
switch (cmd)
{
case SB_TEMPERATURE:
*param = mock_temperature;
break;
case SB_VOLTAGE:
*param = mock_voltage;
break;
case SB_CURRENT:
*param = mock_current;
break;
case SB_RELATIVE_STATE_OF_CHARGE:
case SB_ABSOLUTE_STATE_OF_CHARGE:
*param = 70; /* 70% charged */
break;
case SB_REMAINING_CAPACITY:
*param = 7000; /* 7000 mAh */
break;
case SB_FULL_CHARGE_CAPACITY:
case SB_DESIGN_CAPACITY:
*param = 10000; /* 10000 mAh */
break;
case SB_AVERAGE_TIME_TO_EMPTY:
case SB_RUN_TIME_TO_EMPTY:
*param = 60; /* 60 min to empty */
break;
case SB_AVERAGE_TIME_TO_FULL:
*param = 30; /* 30 min to full */
break;
case SB_CHARGING_CURRENT:
*param = mock_desire_current;
break;
case SB_CHARGING_VOLTAGE:
*param = mock_desire_voltage;
break;
case SB_CYCLE_COUNT:
*param = 10;
break;
case SB_DESIGN_VOLTAGE:
*param = 7400; /* 7.4 V */
break;
case SB_SERIAL_NUMBER:
*param = 112233;
break;
default:
*param = 0;
break;
}
return EC_SUCCESS;
}
int sb_write(int cmd, int param)
{
uart_printf("sb_write: cmd = %d, param = %d\n", cmd, param);
return EC_SUCCESS;
}
static int command_sb_mock(int argc, char **argv)
{
char *e;
int v;
if (argc < 3)
return EC_ERROR_PARAM_COUNT;
v = strtoi(argv[2], &e, 0);
if (*e)
return EC_ERROR_PARAM2;
if (!strcasecmp(argv[1], "temperature"))
mock_temperature = v;
else if (!strcasecmp(argv[1], "desire_voltage"))
mock_desire_voltage = v;
else if (!strcasecmp(argv[1], "desire_current"))
mock_desire_current = v;
else if (!strcasecmp(argv[1], "voltage"))
mock_voltage = v;
else if (!strcasecmp(argv[1], "current"))
mock_current = v;
else
return EC_ERROR_PARAM1;
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(sbmock, command_sb_mock,
"name value",
"Mock smart battery attribute",
NULL);

View File

@@ -32,6 +32,7 @@ void x86_power_cpu_overheated(int too_hot)
void x86_power_force_shutdown(void)
{
uart_puts("Force shutdown\n");
mock_power_on = 0;
}

View File

@@ -7,7 +7,7 @@
#
test-list=hello pingpong timer_calib timer_dos timer_jump mutex thermal
test-list+=power_button kb_deghost kb_debounce scancode typematic
test-list+=power_button kb_deghost kb_debounce scancode typematic charging
#disable: powerdemo
pingpong-y=pingpong.o
@@ -43,3 +43,9 @@ common-mock-typematic-i8042.o=mock_i8042.o
# Mock modules for 'kb_debounce'
chip-mock-kb_debounce-keyboard_scan_stub.o=mock_keyboard_scan_stub.o
common-mock-kb_debounce-i8042.o=mock_i8042.o
# Mock modules for 'charging;
chip-mock-charging-gpio.o=mock_gpio.o
common-mock-charging-x86_power.o=mock_x86_power.o
common-mock-charging-smart_battery_stub.o=mock_smart_battery_stub.o
common-mock-charging-charger_bq24725.o=mock_charger.o

81
test/charging.py Normal file
View File

@@ -0,0 +1,81 @@
# Copyright (c) 2011 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.
#
# Charging state machine unit test
#
import time
def consume_charge_state(helper):
try:
while True:
helper.wait_output("Charge state \S+ -> \S+",
use_re=True,
timeout=1)
except:
pass
def wait_charge_state(helper, state):
helper.wait_output("Charge state \S+ -> %s" % state, use_re=True)
def test(helper):
helper.wait_output("--- UART initialized")
# Check charge when AC present
consume_charge_state(helper)
helper.ec_command("gpiomock AC_PRESENT 1")
wait_charge_state(helper, "charge")
# Check discharge when AC not present
helper.ec_command("gpiomock AC_PRESENT 0")
wait_charge_state(helper, "discharge")
# Check charge current
helper.ec_command("sbmock desire_current 2800")
helper.ec_command("gpiomock AC_PRESENT 1")
helper.wait_output("Charger set current: 2800")
# Check charger voltage
helper.ec_command("gpiomock AC_PRESENT 0")
wait_charge_state(helper, "discharge")
helper.ec_command("sbmock desire_voltage 7500")
helper.ec_command("gpiomock AC_PRESENT 1")
helper.wait_output("Charger set voltage: 7500")
# While powered on and discharging, over-temperature should trigger
# system shutdown
helper.ec_command("gpiomock AC_PRESENT 0")
wait_charge_state(helper, "discharge")
helper.ec_command("powermock on")
helper.ec_command("sbmock temperature 3700")
helper.wait_output("Force shutdown")
helper.ec_command("sbmock temperature 2981")
time.sleep(1)
# While powered on and discharging, under-temperature should trigger
# system shutdown
helper.ec_command("powermock on")
helper.ec_command("sbmock temperature 2600")
helper.wait_output("Force shutdown")
helper.ec_command("sbmock temperature 2981")
# While powered on and charging, over-temperature should stop battery
# from charging
consume_charge_state(helper)
helper.ec_command("gpiomock AC_PRESENT 1")
wait_charge_state(helper, "charge")
helper.ec_command("powermock on")
helper.ec_command("sbmock temperature 3700")
wait_charge_state(helper, "idle")
helper.ec_command("sbmock temperature 2981")
wait_charge_state(helper, "charge")
# While powered on and charging, under-temperature should stop battery
# from charging
helper.ec_command("sbmock temperature 2600")
wait_charge_state(helper, "idle")
helper.ec_command("sbmock temperature 2981")
wait_charge_state(helper, "charge")
return True # PASS !

26
test/charging.tasklist Normal file
View File

@@ -0,0 +1,26 @@
/* Copyright (c) 2012 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(n, r, d) 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
*/
#define CONFIG_TASK_LIST \
TASK(WATCHDOG, watchdog_task, NULL) \
TASK(VBOOTHASH, vboot_hash_task, NULL) \
TASK(PWM, pwm_task, NULL) \
TASK(TYPEMATIC, keyboard_typematic_task, NULL) \
TASK(POWERSTATE, charge_state_machine_task, NULL) \
TASK(X86POWER, x86_power_task, NULL) \
TASK(I8042CMD, i8042_command_task, NULL) \
TASK(KEYSCAN, keyboard_scan_task, NULL) \
TASK(POWERBTN, power_button_task, NULL) \
TASK(CONSOLE, console_task, NULL)