diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2016-10-03 12:51:52 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-10-05 20:58:20 -0700 |
commit | 3afd683d683f482f003405c721800e3ba2ccb637 (patch) | |
tree | 0d4a7a23b273d09cbe46f49f5c41eb56ceb3db2b /cts | |
parent | 8c22c2dcd7397cddd78e518f808212a0ac86df90 (diff) | |
download | chrome-ec-3afd683d683f482f003405c721800e3ba2ccb637.tar.gz |
cts: Add I2C tests for read8/16/32 and write8/16/32
This patch adds tests for i2c_read8/16/32 and i2c_write8/16/32.
BUG=chromium:653183
BRANCH=none
TEST=make buildall. Run cts.py -m i2c for 100kHz with 10k ohms
pull-up registers on SCL and SDA. TH=stm32l476g-eval DUT=nucleo-f072rb.
Change-Id: I8121b1c5dc7542da45141543e35036ef41364c38
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/393331
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'cts')
-rw-r--r-- | cts/build.mk | 8 | ||||
-rw-r--r-- | cts/i2c/cts.testlist | 14 | ||||
-rw-r--r-- | cts/i2c/cts_i2c.h | 20 | ||||
-rw-r--r-- | cts/i2c/dut.c | 104 | ||||
-rw-r--r-- | cts/i2c/th.c | 167 |
5 files changed, 313 insertions, 0 deletions
diff --git a/cts/build.mk b/cts/build.mk index 8d132e8da2..63b51c6fbf 100644 --- a/cts/build.mk +++ b/cts/build.mk @@ -9,6 +9,14 @@ ifeq "$(CTS_MODULE)" "gpio" CFLAGS_CTS+=-DCTS_MODULE_GPIO endif +ifeq "$(CTS_MODULE)" "i2c" +CFLAGS_CTS+=-DCTS_MODULE_I2C +CONFIG_I2C=y +ifneq ($(BOARD),stm32l476g-eval) +CONFIG_I2C_MASTER=y +endif +endif + ifeq ($(BOARD),stm32l476g-eval) cts-y+=$(CTS_MODULE)/th.o cts-y+=common/th_common.o diff --git a/cts/i2c/cts.testlist b/cts/i2c/cts.testlist new file mode 100644 index 0000000000..79732dc65b --- /dev/null +++ b/cts/i2c/cts.testlist @@ -0,0 +1,14 @@ +/* Copyright 2016 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. + */ + +/* Currently tests will execute in the order they are listed here */ + +/* Test whether sync completes successfully */ +CTS_TEST(write8_test) +CTS_TEST(write16_test) +CTS_TEST(write32_test) +CTS_TEST(read8_test) +CTS_TEST(read16_test) +CTS_TEST(read32_test)
\ No newline at end of file diff --git a/cts/i2c/cts_i2c.h b/cts/i2c/cts_i2c.h new file mode 100644 index 0000000000..9d287580bf --- /dev/null +++ b/cts/i2c/cts_i2c.h @@ -0,0 +1,20 @@ +/* Copyright 2016 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. + */ + +enum cts_i2c_packets { + WRITE_8_OFFSET = 0, + WRITE_16_OFFSET = 1, + WRITE_32_OFFSET = 2, + READ_8_OFFSET = 3, + READ_16_OFFSET = 4, + READ_32_OFFSET = 5, +}; + +#define WRITE_8_DATA 0x42 +#define WRITE_16_DATA 0x1234 +#define WRITE_32_DATA 0xDEADBEEF +#define READ_8_DATA 0x23 +#define READ_16_DATA 0xACED +#define READ_32_DATA 0x01ABCDEF diff --git a/cts/i2c/dut.c b/cts/i2c/dut.c new file mode 100644 index 0000000000..b629475ffa --- /dev/null +++ b/cts/i2c/dut.c @@ -0,0 +1,104 @@ +/* Copyright 2016 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. + */ + +#include "common.h" +#include "cts_common.h" +#include "cts_i2c.h" +#include "dut_common.h" +#include "i2c.h" +#include "registers.h" +#include "timer.h" +#include "uart.h" +#include "watchdog.h" + +#define TH_ADDR 0x3c + +enum cts_rc write8_test(void) +{ + int port = i2c_ports[0].port; + + i2c_write8(port, TH_ADDR, WRITE_8_OFFSET, WRITE_8_DATA); + + return CTS_RC_SUCCESS; +} + +enum cts_rc write16_test(void) +{ + int port = i2c_ports[0].port; + + i2c_write16(port, TH_ADDR, WRITE_16_OFFSET, WRITE_16_DATA); + + return CTS_RC_SUCCESS; +} + +enum cts_rc write32_test(void) +{ + int port = i2c_ports[0].port; + + i2c_write32(port, TH_ADDR, WRITE_32_OFFSET, WRITE_32_DATA); + + return CTS_RC_SUCCESS; +} + +enum cts_rc read8_test(void) +{ + int result; + int port = i2c_ports[0].port; + + i2c_read8(port, TH_ADDR, READ_8_OFFSET, &result); + + if (result != READ_8_DATA) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + +enum cts_rc read16_test(void) +{ + int result; + int port = i2c_ports[0].port; + + i2c_read16(port, TH_ADDR, READ_16_OFFSET, &result); + + if (result != READ_16_DATA) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + +enum cts_rc read32_test(void) +{ + int result; + int port = i2c_ports[0].port; + + i2c_read32(port, TH_ADDR, READ_32_OFFSET, &result); + + if (result != READ_32_DATA) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + + +#include "cts_testlist.h" + +void cts_task(void) +{ + int i; + + cflush(); + for (i = 0; i < CTS_TEST_ID_COUNT; i++) { + sync(); + CPRINTF("\n%s %d\n", tests[i].name, tests[i].run()); + uart_flush_output(); + } + + CPRINTS("I2C test suite finished"); + uart_flush_output(); + while (1) { + watchdog_reload(); + sleep(1); + } +} diff --git a/cts/i2c/th.c b/cts/i2c/th.c new file mode 100644 index 0000000000..86c3a2c8de --- /dev/null +++ b/cts/i2c/th.c @@ -0,0 +1,167 @@ +/* Copyright 2016 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. + */ + +#include <string.h> +#include "common.h" +#include "cts_common.h" +#include "cts_i2c.h" +#include "dut_common.h" +#include "i2c.h" +#include "registers.h" +#include "timer.h" +#include "uart.h" +#include "watchdog.h" + +static uint8_t inbox[I2C_MAX_HOST_PACKET_SIZE + 2]; +static char data_received; + +void i2c_data_received(int port, uint8_t *buf, int len) +{ + memcpy(inbox, buf, len); + data_received = 1; +} + +/* CTS I2C protocol implementation */ +int i2c_set_response(int port, uint8_t *buf, int len) +{ + switch (buf[0]) { + case READ_8_OFFSET: + buf[0] = READ_8_DATA; + return 1; + case READ_16_OFFSET: + buf[0] = READ_16_DATA & 0xFF; + buf[1] = (READ_16_DATA >> 8) & 0xFF; + return 2; + case READ_32_OFFSET: + buf[0] = READ_32_DATA & 0xFF; + buf[1] = (READ_32_DATA >> 8) & 0xFF; + buf[2] = (READ_32_DATA >> 16) & 0xFF; + buf[3] = (READ_32_DATA >> 24) & 0xFF; + return 4; + default: + return 0; + } +} + +static int wait_for_in_flag(uint32_t timeout_ms) +{ + uint64_t start_time, end_time; + + start_time = get_time().val; + end_time = start_time + timeout_ms * 1000; + + while (get_time().val < end_time) { + if (data_received) + return 0; + msleep(5); + watchdog_reload(); + } + return 1; +} + +static void clear_inbox(void) +{ + memset(inbox, 0, sizeof(inbox)); + data_received = 0; +} + +enum cts_rc write8_test(void) +{ + int in; + + if (wait_for_in_flag(100)) + return CTS_RC_TIMEOUT; + if (inbox[0] != WRITE_8_OFFSET) + return CTS_RC_FAILURE; + in = inbox[1]; + if (in != WRITE_8_DATA) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + +enum cts_rc write16_test(void) +{ + int in; + + if (wait_for_in_flag(100)) + return CTS_RC_TIMEOUT; + if (inbox[0] != WRITE_16_OFFSET) + return CTS_RC_FAILURE; + in = inbox[2] << 8 | inbox[1] << 0; + if (in != WRITE_16_DATA) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + +enum cts_rc write32_test(void) +{ + int in; + + if (wait_for_in_flag(100)) + return CTS_RC_TIMEOUT; + if (inbox[0] != WRITE_32_OFFSET) + return CTS_RC_FAILURE; + in = inbox[4] << 24 | inbox[3] << 16 | inbox[2] << 8 | inbox[1]; + if (in != WRITE_32_DATA) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + +enum cts_rc read8_test(void) +{ + if (wait_for_in_flag(100)) + return CTS_RC_TIMEOUT; + if (inbox[0] != READ_8_OFFSET) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + +enum cts_rc read16_test(void) +{ + if (wait_for_in_flag(100)) + return CTS_RC_TIMEOUT; + if (inbox[0] != READ_16_OFFSET) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + +enum cts_rc read32_test(void) +{ + if (wait_for_in_flag(100)) + return CTS_RC_TIMEOUT; + if (inbox[0] != READ_32_OFFSET) + return CTS_RC_FAILURE; + + return CTS_RC_SUCCESS; +} + +#include "cts_testlist.h" + +void cts_task(void) +{ + enum cts_rc result; + int i; + + cflush(); + for (i = 0; i < CTS_TEST_ID_COUNT; i++) { + clear_inbox(); + sync(); + result = tests[i].run(); + CPRINTF("\n%s %d\n", tests[i].name, result); + uart_flush_output(); + } + + CPRINTS("I2C test suite finished"); + uart_flush_output(); + while (1) { + watchdog_reload(); + sleep(1); + } +} |