144 lines
3.3 KiB
C
144 lines
3.3 KiB
C
/* Copyright 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.
|
|
*/
|
|
|
|
/* Peripheral stress tests */
|
|
|
|
#include "console.h"
|
|
#include "ec_commands.h"
|
|
#include "i2c.h"
|
|
#include "test_util.h"
|
|
#include "timer.h"
|
|
#include "util.h"
|
|
|
|
#ifdef CONFIG_ADC
|
|
#include "adc.h"
|
|
#endif
|
|
|
|
static int error_count;
|
|
|
|
/*****************************************************************************/
|
|
/* Test parameters */
|
|
|
|
/* I2C test */
|
|
#define I2C_TEST_ITERATION 2000
|
|
|
|
struct i2c_test_param_t {
|
|
int width; /* 8 or 16 bits */
|
|
int port;
|
|
int addr;
|
|
int offset;
|
|
int data; /* Non-negative represents data to write. -1 to read. */
|
|
} i2c_test_params[];
|
|
|
|
/* Disable I2C test for boards without test configuration */
|
|
#if defined(BOARD_BDS) || defined(BOARD_AURON)
|
|
#undef CONFIG_I2C
|
|
#endif
|
|
|
|
/* ADC test */
|
|
#define ADC_TEST_ITERATION 2000
|
|
|
|
/*****************************************************************************/
|
|
/* Test utilities */
|
|
|
|
/* period between 500us and 32ms */
|
|
#define RAND_US() (((prng_no_seed() % 64) + 1) * 500)
|
|
|
|
static int stress(const char *name,
|
|
int (*test_routine)(void),
|
|
const int iteration)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < iteration; ++i) {
|
|
if (i % 10 == 0) {
|
|
ccprintf("\r%s...%d/%d", name, i, iteration);
|
|
usleep(RAND_US());
|
|
}
|
|
if (test_routine() != EC_SUCCESS)
|
|
return EC_ERROR_UNKNOWN;
|
|
}
|
|
|
|
ccprintf("\r%s...%d/%d\n", name, iteration, iteration);
|
|
return EC_SUCCESS;
|
|
}
|
|
|
|
#define RUN_STRESS_TEST(n, r, iter) \
|
|
do { \
|
|
if (stress(n, r, iter) != EC_SUCCESS) { \
|
|
ccputs("Fail\n"); \
|
|
error_count++; \
|
|
} \
|
|
} while (0)
|
|
|
|
/*****************************************************************************/
|
|
/* Tests */
|
|
#ifdef CONFIG_I2C_MASTER
|
|
static int test_i2c(void)
|
|
{
|
|
int res = EC_ERROR_UNKNOWN;
|
|
int dummy_data;
|
|
struct i2c_test_param_t *param;
|
|
param = i2c_test_params + (prng_no_seed() % (sizeof(i2c_test_params) /
|
|
sizeof(struct i2c_test_param_t)));
|
|
if (param->width == 8 && param->data == -1)
|
|
res = i2c_read8(param->port, param->addr,
|
|
param->offset, &dummy_data);
|
|
else if (param->width == 8 && param->data >= 0)
|
|
res = i2c_write8(param->port, param->addr,
|
|
param->offset, param->data);
|
|
else if (param->width == 16 && param->data == -1)
|
|
res = i2c_read16(param->port, param->addr,
|
|
param->offset, &dummy_data);
|
|
else if (param->width == 16 && param->data >= 0)
|
|
res = i2c_write16(param->port, param->addr,
|
|
param->offset, param->data);
|
|
else if (param->width == 32 && param->data == -1)
|
|
res = i2c_read32(param->port, param->addr,
|
|
param->offset, &dummy_data);
|
|
else if (param->width == 32 && param->data >= 0)
|
|
res = i2c_write32(param->port, param->addr,
|
|
param->offset, param->data);
|
|
|
|
return res;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_ADC
|
|
__attribute__((weak)) int adc_read_all_channels(int *data)
|
|
{
|
|
int i;
|
|
int rv = EC_SUCCESS;
|
|
|
|
for (i = 0; i < ADC_CH_COUNT; ++i) {
|
|
data[i] = adc_read_channel(i);
|
|
if (data[i] == ADC_READ_ERROR)
|
|
rv = EC_ERROR_UNKNOWN;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
static int test_adc(void)
|
|
{
|
|
int data[ADC_CH_COUNT];
|
|
return adc_read_all_channels(data);
|
|
}
|
|
#endif
|
|
|
|
void run_test(void)
|
|
{
|
|
test_reset();
|
|
|
|
#ifdef CONFIG_I2C_MASTER
|
|
RUN_STRESS_TEST("I2C Stress Test", test_i2c, I2C_TEST_ITERATION);
|
|
#endif
|
|
#ifdef CONFIG_ADC
|
|
RUN_STRESS_TEST("ADC Stress Test", test_adc, ADC_TEST_ITERATION);
|
|
#endif
|
|
|
|
test_print_result();
|
|
}
|