diff --git a/tests/periph_ptp_timer/Makefile b/tests/periph_ptp_timer/Makefile new file mode 100644 index 0000000000..2659ba0356 --- /dev/null +++ b/tests/periph_ptp_timer/Makefile @@ -0,0 +1,9 @@ +BOARD ?= nucleo-f767zi +include ../Makefile.tests_common + +FEATURES_REQUIRED = periph_ptp_timer + +USEMODULE += event +USEMODULE += fmt + +include $(RIOTBASE)/Makefile.include diff --git a/tests/periph_ptp_timer/README.md b/tests/periph_ptp_timer/README.md new file mode 100644 index 0000000000..f446e019a7 --- /dev/null +++ b/tests/periph_ptp_timer/README.md @@ -0,0 +1,17 @@ +Peripheral PTP Timer Test Application +===================================== + +This tests setting the PTP timer to the following targets: + +- one second into the future (using the absolute API) +- 1st of January 1970 0:00:00 (using the absolute API) + - This is expected to fire right away according to the API +- 1 µs to 99µs into the future (using the relative API) + +If all timeouts fire within ± 10 µs of the target time, the test succeeds. + +Expected Output on Success +-------------------------- + + main(): This is RIOT! (Version: ) + TEST SUCCEEDED! diff --git a/tests/periph_ptp_timer/main.c b/tests/periph_ptp_timer/main.c new file mode 100644 index 0000000000..0ef00ff98a --- /dev/null +++ b/tests/periph_ptp_timer/main.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Peripheral PTP clock test application + * + * @author Marian Buschsieweke + * + * @} + */ + +#include +#include + +#include "event.h" +#include "fmt.h" +#include "kernel_defines.h" +#include "periph/ptp.h" + +static uint64_t ts_target; +static uint64_t ts_hit; +static const uint64_t max_diff = 10000; /* 10 µs */ +static int failed = 0; +static unsigned n_timeouts = 0; +static event_queue_t q = EVENT_QUEUE_INIT_DETACHED; + +static inline uint64_t abs_diff(uint64_t a, uint64_t b) +{ + return (a >= b) ? (a - b) : (b - a); +} + +static void ev_handler(event_t *ev) +{ + (void)ev; + uint64_t diff = abs_diff(ts_target, ts_hit); + if (diff > max_diff) { + failed = 1; + print_str("Error: Timeout missed target by "); + print_u64_dec(diff); + print_str(" ns\n"); + } + + n_timeouts++; + + if (n_timeouts == 1) { + /* check if setting timeout in the past does trigger IRQ */ + ts_target = ptp_clock_read_u64(); + ptp_timer_set_absolute_u64(0); + } + else if (n_timeouts < 100) { + /* check if setting small relative timeouts work */ + uint64_t delay = (99 - n_timeouts) * 1000; + ts_target = ptp_clock_read_u64() + delay; + ptp_timer_set_u64(delay); + } + else { + if (failed) { + print_str("TEST FAILED!\n"); + } + else { + print_str("TEST SUCCEEDED!\n"); + } + } +} + +void ptp_timer_cb(void) +{ + ts_hit = ptp_clock_read_u64(); + static event_t ev = { .handler = ev_handler }; + event_post(&q, &ev); +} + +int main(void) +{ + ts_target = ptp_clock_read_u64() + NS_PER_SEC; + ptp_timer_set_absolute_u64(ts_target); + event_queue_claim(&q); + event_loop(&q); + UNREACHABLE(); +} diff --git a/tests/periph_ptp_timer/tests/01-run.py b/tests/periph_ptp_timer/tests/01-run.py new file mode 100755 index 0000000000..d69fd91a34 --- /dev/null +++ b/tests/periph_ptp_timer/tests/01-run.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +import sys +from testrunner import run + + +def testfunc(child): + child.expect_exact("TEST SUCCEEDED!\r\n") + + +if __name__ == "__main__": + sys.exit(run(testfunc))