summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-07-18 15:12:32 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-07-29 15:02:44 -0700
commitb517067a418e1551f7c70cc32840f10845003934 (patch)
tree581f7e1c55fe0a4f29d900b6d880c46cb20a7b97
parent4a72f8f60750ff43c0cffb4735a6279db25c1d67 (diff)
downloadchrome-ec-b517067a418e1551f7c70cc32840f10845003934.tar.gz
cts: Add timer test
The timer test checks the accuracy of the internal timer. After sync, DUT and TH start counting down one second. After one second, DUT raises GPIO level. TH determines whether the test passes or not based on how much more or less time elapsed than one second, assuming its clock is calibrated. This test takes advantage of TH running on a bare chip. If the host were measuring (instead of TH), the timing would be affected by many software and hardware layers (e.g. UART drivers on DUT and host, python interpreter, etc.). BUG=chromium:624520 BRANCH=none TEST=cts.py --module timer && cts.py --module gpio && make buildall Change-Id: I535e7772b4d93f1f5d248506f7ea167429a50174 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/361384
-rw-r--r--board/stm32l476g-eval/board.c11
-rw-r--r--board/stm32l476g-eval/gpio.inc9
-rw-r--r--cts/build.mk4
-rw-r--r--cts/timer/cts.testlist19
-rw-r--r--cts/timer/dut.c44
-rw-r--r--cts/timer/th.c77
6 files changed, 164 insertions, 0 deletions
diff --git a/board/stm32l476g-eval/board.c b/board/stm32l476g-eval/board.c
index 37ff088090..6a5089a874 100644
--- a/board/stm32l476g-eval/board.c
+++ b/board/stm32l476g-eval/board.c
@@ -7,6 +7,17 @@
#include "gpio.h"
#include "hooks.h"
#include "registers.h"
+
+#ifdef CTS_MODULE
+/*
+ * Dummy interrupt handler. It's supposed to be overwritten by each suite
+ * if needed.
+ */
+__attribute__((weak)) void cts_irq(enum gpio_signal signal)
+{
+}
+#endif
+
#include "gpio_list.h"
void tick_event(void)
diff --git a/board/stm32l476g-eval/gpio.inc b/board/stm32l476g-eval/gpio.inc
index 4878f3b857..85447432c0 100644
--- a/board/stm32l476g-eval/gpio.inc
+++ b/board/stm32l476g-eval/gpio.inc
@@ -7,6 +7,13 @@
/* Declare symbolic names for all the GPIOs that we care about.
* Note: Those with interrupt handlers must be declared first. */
+#ifdef CTS_MODULE
+#ifndef CTS_MODULE_GPIO
+/* Overload C10 for notification. Enabled only for non-GPIO suites as
+ * GPIO tests don't require a separate notification line. */
+GPIO_INT(CTS_NOTIFY, PIN(C, 10), GPIO_INT_FALLING | GPIO_PULL_UP , cts_irq)
+#endif
+#endif
/* Outputs */
GPIO(LED_GREEN, PIN(B, 2), GPIO_OUT_LOW)
@@ -24,5 +31,7 @@ ALTERNATE(PIN_MASK(G, 0x0180), GPIO_ALT_F8, MODULE_UART, 0) /* LPUART: PG7/8 */
GPIO(HANDSHAKE_OUTPUT, PIN(D, 2), GPIO_ODR_LOW)
GPIO(HANDSHAKE_INPUT, PIN(C, 12), GPIO_INPUT | GPIO_PULL_UP)
GPIO(OUTPUT_TEST, PIN(C, 11), GPIO_ODR_LOW)
+#ifdef CTS_MODULE_GPIO
GPIO(INPUT_TEST, PIN(C, 10), GPIO_INPUT | GPIO_PULL_UP)
#endif
+#endif
diff --git a/cts/build.mk b/cts/build.mk
index 59fa85547c..8d132e8da2 100644
--- a/cts/build.mk
+++ b/cts/build.mk
@@ -5,6 +5,10 @@
CFLAGS_CTS=-DCTS_MODULE -DCTS_TASKFILE=cts.tasklist
+ifeq "$(CTS_MODULE)" "gpio"
+CFLAGS_CTS+=-DCTS_MODULE_GPIO
+endif
+
ifeq ($(BOARD),stm32l476g-eval)
cts-y+=$(CTS_MODULE)/th.o
cts-y+=common/th_common.o
diff --git a/cts/timer/cts.testlist b/cts/timer/cts.testlist
new file mode 100644
index 0000000000..d4cb3c30b3
--- /dev/null
+++ b/cts/timer/cts.testlist
@@ -0,0 +1,19 @@
+/* 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.
+ */
+
+/*
+ * Test timer accuracy
+ *
+ * After sync, DUT and TH start counting down one second. After one second,
+ * DUT raises GPIO level, which triggers an interrupt on TH. TH determines
+ * whether the test passes or not based on how much more or less time elapsed
+ * than one second.
+ *
+ * Requirements:
+ * - Sync connection
+ * - GPIO_OUTPUT connection for sending notification from DUT
+ * - Calibrated TH timer
+ */
+CTS_TEST(timer_calibration_test)
diff --git a/cts/timer/dut.c b/cts/timer/dut.c
new file mode 100644
index 0000000000..29003f36af
--- /dev/null
+++ b/cts/timer/dut.c
@@ -0,0 +1,44 @@
+/* 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 "dut_common.h"
+#include "gpio.h"
+#include "timer.h"
+#include "watchdog.h"
+
+static enum cts_rc timer_calibration_test(void)
+{
+ gpio_set_flags(GPIO_OUTPUT_TEST, GPIO_ODR_HIGH);
+
+ sync();
+ usleep(SECOND);
+ gpio_set_level(GPIO_OUTPUT_TEST, 0);
+
+ return CTS_RC_SUCCESS;
+}
+
+#include "cts_testlist.h"
+
+void cts_task(void)
+{
+ enum cts_rc rc;
+ int i;
+
+ for (i = 0; i < CTS_TEST_ID_COUNT; i++) {
+ sync();
+ rc = tests[i].run();
+ CPRINTF("\n%s %d\n", tests[i].name, rc);
+ cflush();
+ }
+
+ CPRINTS("Timer test suite finished");
+ cflush();
+
+ while (1) {
+ watchdog_reload();
+ sleep(1);
+ }
+}
diff --git a/cts/timer/th.c b/cts/timer/th.c
new file mode 100644
index 0000000000..a6e9d575b1
--- /dev/null
+++ b/cts/timer/th.c
@@ -0,0 +1,77 @@
+/* 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 "gpio.h"
+#include "registers.h"
+#include "task.h"
+#include "th_common.h"
+#include "timer.h"
+#include "watchdog.h"
+
+/*
+ * Interrupt handler
+ *
+ * DUT is supposed to trigger an interrupt when it's done counting down,
+ * causing this function to be invoked.
+ */
+void cts_irq(enum gpio_signal signal)
+{
+ /* Wake up the CTS task */
+ task_wake(TASK_ID_CTS);
+}
+
+static enum cts_rc timer_calibration_test(void)
+{
+ /* Error margin: +/-2 msec (0.2% for one second) */
+ const int32_t margin = 2 * MSEC;
+ int32_t elapsed, delta;
+ timestamp_t t0, t1;
+
+ gpio_enable_interrupt(GPIO_CTS_NOTIFY);
+ interrupt_enable();
+
+ sync();
+ t0 = get_time();
+ /* Wait for interrupt */
+ task_wait_event(-1);
+ t1 = get_time();
+
+ elapsed = (int32_t)(t1.val - t0.val);
+ delta = elapsed - SECOND;
+ if (delta < -margin) {
+ CPRINTS("DUT clock runs too fast: %+d usec", delta);
+ return CTS_RC_FAILURE;
+ }
+ if (margin < delta) {
+ CPRINTS("DUT clock runs too slow: %+d usec", delta);
+ return CTS_RC_FAILURE;
+ }
+
+ return CTS_RC_SUCCESS;
+}
+
+#include "cts_testlist.h"
+
+void cts_task(void)
+{
+ enum cts_rc rc;
+ int i;
+
+ for (i = 0; i < CTS_TEST_ID_COUNT; i++) {
+ sync();
+ rc = tests[i].run();
+ CPRINTF("\n%s %d\n", tests[i].name, rc);
+ cflush();
+ }
+
+ CPRINTS("Timer test suite finished");
+ cflush();
+
+ while (1) {
+ watchdog_reload();
+ sleep(1);
+ }
+}