diff options
-rw-r--r-- | board/stm32l476g-eval/board.c | 11 | ||||
-rw-r--r-- | board/stm32l476g-eval/gpio.inc | 9 | ||||
-rw-r--r-- | cts/build.mk | 4 | ||||
-rw-r--r-- | cts/timer/cts.testlist | 19 | ||||
-rw-r--r-- | cts/timer/dut.c | 44 | ||||
-rw-r--r-- | cts/timer/th.c | 77 |
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); + } +} |