diff --git a/tests/periph_rtt_min/Makefile b/tests/periph_rtt_min/Makefile new file mode 100644 index 0000000000..c0583244da --- /dev/null +++ b/tests/periph_rtt_min/Makefile @@ -0,0 +1,20 @@ +BOARD ?= samr21-xpro +include ../Makefile.tests_common + +USEMODULE += xtimer + +FEATURES_REQUIRED += periph_rtt +DISABLE_MODULE += periph_init_rtt + +SAMPLES ?= 1024 +CFLAGS += -DSAMPLES=$(SAMPLES) + +include $(RIOTBASE)/Makefile.include + +$(call target-export-variables, test, SAMPLES) + +# use highest possible RTT_FREQUENCY for boards that allow it +ifneq (,$(filter stm32 nrf5%,$(CPU))) + RTT_FREQUENCY ?= RTT_MAX_FREQUENCY + CFLAGS += -DRTT_FREQUENCY=$(RTT_FREQUENCY) +endif diff --git a/tests/periph_rtt_min/README.md b/tests/periph_rtt_min/README.md new file mode 100644 index 0000000000..d0bc3a9ab6 --- /dev/null +++ b/tests/periph_rtt_min/README.md @@ -0,0 +1,30 @@ +## About + +This applications is meant to determine RTT_MIN_OFFSET for a specific BOARD. + +The application will iteratively set an alarm starting from 0 ticks offset +until the alarm actually triggers. Every time the alarm underflows the +alarm will not be triggered within the expected time, so the application +will set another one with a larger offset until the alarm successfully triggers. + +The rtt might advance between the call to rtt_get_counter() and +rtt_set_alarm(). If that happens with val=1 then the alarm would be set +to the current time and underflow. The test is ran over multiple samples +to make this more likely to happen. Nonetheless its always possible +that now sample will underflow so a conservatory value would be to +set RTT_MIN_OFFSET to the value found out with this test + 1tick. + +## Usage + +Run `BOARD= make -C tests/periph_rtt_min/ flash test` the value will +be printed as: + +``` +Evaluate RTT_MIN_OFFSET over 1024 samples +........................................................................ +........................................................................ +........................................................................ +........................................................................ +........................................................................ +RTT_MIN_OFFSET for : 2 +``` diff --git a/tests/periph_rtt_min/main.c b/tests/periph_rtt_min/main.c new file mode 100644 index 0000000000..369b61e203 --- /dev/null +++ b/tests/periph_rtt_min/main.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 Inria + * + * 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 Test to figure out RTT_MIN_OFFSET + * + * @author Francisco Molina + * + * @} + */ + +#include +#include +#include + +#include "cpu.h" +#include "periph_conf.h" +#include "periph/rtt.h" + +#include "xtimer.h" + +#define US_PER_TICK (US_PER_SEC / RTT_FREQUENCY) +/* min. amount of time to wait between set_alarm() */ +#define MIN_WAIT_US (3 * US_PER_TICK) + +#ifndef SAMPLES +#define SAMPLES 1024LU +#endif + +void cb(void *arg) +{ + mutex_unlock(arg); +} + +int main(void) +{ + uint32_t value = 0; + /* mutex starts out locked, and each time an rtt callback is successfully + called it will be locked again for the next iteration */ + mutex_t lock = MUTEX_INIT_LOCKED; + + rtt_init(); + + printf("Evaluate RTT_MIN_OFFSET over %" PRIu32 " samples\n", + (uint32_t)SAMPLES); + + for (unsigned i = 0; i < SAMPLES; i++) { + uint32_t offset = 0; + int ret = -1; + while (ret != 0) { + offset++; + rtt_clear_alarm(); + uint32_t now = rtt_get_counter(); + rtt_set_alarm((now + offset) % RTT_MAX_VALUE, cb, &lock); + ret = xtimer_mutex_lock_timeout( + &lock, offset * US_PER_TICK + MIN_WAIT_US); + } + if (offset > value) { + value = offset; + } + printf("."); + fflush(stdout); + } + printf("\n"); + + printf("RTT_MIN_OFFSET for %s: %" PRIu32 "\n", RIOT_BOARD, value); + + return 0; +} diff --git a/tests/periph_rtt_min/tests/01-run.py b/tests/periph_rtt_min/tests/01-run.py new file mode 100755 index 0000000000..17ba5eaba5 --- /dev/null +++ b/tests/periph_rtt_min/tests/01-run.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2020 Inria +# +# 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 os +import sys + +from testrunner import run + +SAMPLES = int(os.getenv("SAMPLES", "1024")) + + +def testfunc(child): + for _ in range(0, SAMPLES): + child.expect_exact('.') + child.expect(r'RTT_MIN_OFFSET for [a-zA-Z\-\_0-9]+: \d+') + + +if __name__ == "__main__": + sys.exit(run(testfunc))