diff --git a/tests/unittests/tests-rtt_rtc/Makefile b/tests/unittests/tests-rtt_rtc/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/tests/unittests/tests-rtt_rtc/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-rtt_rtc/Makefile.include b/tests/unittests/tests-rtt_rtc/Makefile.include new file mode 100644 index 0000000000..c3d957baf7 --- /dev/null +++ b/tests/unittests/tests-rtt_rtc/Makefile.include @@ -0,0 +1,8 @@ +USEMODULE += rtt_rtc + +CFLAGS += -DMOCK_RTT_FREQUENCY=32 +CFLAGS += -DMOCK_RTT_MAX_VALUE=0xFFFF + +# mulle always enables periph_rtt. +# This clashes with mock_rtt. +BOARD_BLACKLIST := mulle diff --git a/tests/unittests/tests-rtt_rtc/mock_rtt.c b/tests/unittests/tests-rtt_rtc/mock_rtt.c new file mode 100644 index 0000000000..2febb83b92 --- /dev/null +++ b/tests/unittests/tests-rtt_rtc/mock_rtt.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * 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. + */ + +/** + * @{ + * + * @file + * @brief Mock implementation of a Real-Time Timer + * + * @author Benjamin Valentin + */ +#include +#include "periph/rtt.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +static uint32_t counter, alarm; +static rtt_cb_t alarm_cb, overflow_cb; +static void *alarm_arg, *overflow_arg; + +uint32_t rtt_get_counter(void) +{ + DEBUG("%s() = %"PRIu32"\n", __func__, counter); + return counter; +} + +void rtt_set_counter(uint32_t _counter) +{ + DEBUG("%s(%"PRIu32")\n", __func__, _counter); + counter = _counter & RTT_MAX_VALUE; +} + +void rtt_set_alarm(uint32_t _alarm, rtt_cb_t cb, void *arg) +{ + DEBUG("%s(%"PRIu32")\n", __func__, _alarm); + + alarm = _alarm & RTT_MAX_VALUE; + alarm_cb = cb; + alarm_arg = arg; +} + +uint32_t rtt_get_alarm(void) +{ + return alarm; +} + +void rtt_clear_alarm(void) +{ + alarm_cb = NULL; +} + +void rtt_set_overflow_cb(rtt_cb_t cb, void *arg) +{ + DEBUG("%s()\n", __func__); + overflow_cb = cb; + overflow_arg = arg; +} + +void rtt_clear_overflow_cb(void) +{ + overflow_cb = NULL; +} + +void rtt_init(void) +{ + counter = 0; +} + +static void _tick(void) +{ + counter = (counter + 1) & RTT_MAX_VALUE; + + if (overflow_cb && (counter == 0)) { + DEBUG("RTT: overflow\n"); + overflow_cb(overflow_arg); + } + + if (alarm_cb && (counter == alarm)) { + DEBUG("RTT: alarm\n"); + alarm_cb(alarm_arg); + } +} + +void rtt_add_ticks(uint64_t ticks) +{ + while (ticks--) { + _tick(); + } +} +/** @} */ diff --git a/tests/unittests/tests-rtt_rtc/tests-rtt_rtc.c b/tests/unittests/tests-rtt_rtc/tests-rtt_rtc.c new file mode 100644 index 0000000000..3f8d0d0ed4 --- /dev/null +++ b/tests/unittests/tests-rtt_rtc/tests-rtt_rtc.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * 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. + */ + +/** + * @{ + * + * @file + */ +#include +#include + +#include "embUnit.h" +#include "periph/rtc.h" +#include "periph/rtt.h" + +void rtt_add_ticks(uint64_t ticks); + +static void test_set_time(void) +{ + struct tm t1 = { + .tm_sec = 42, + .tm_min = 37, + .tm_hour = 13, + .tm_mday = 23, + .tm_mon = 5, + .tm_year = 120, + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst= 0, + }; + struct tm now; + + rtc_set_time(&t1); + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + rtt_add_ticks(60 * RTT_FREQUENCY); + t1.tm_min++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + rtt_add_ticks(60 * 60 * RTT_FREQUENCY); + t1.tm_hour++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(t1.tm_hour, now.tm_hour); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + rtt_add_ticks(60 * RTT_FREQUENCY); + t1.tm_min++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); +} + +static void _alarm_cb(void *arg) +{ + struct tm now, *expt = arg; + + rtc_get_time(&now); + + TEST_ASSERT_EQUAL_INT(expt->tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(expt->tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(expt, &now)); + + /* use dst to signal how often cb was called */ + expt->tm_isdst++; +} + +static void test_set_alarm(void) +{ + struct tm t1 = { + .tm_sec = 42, + .tm_min = 37, + .tm_hour = 13, + .tm_mday = 23, + .tm_mon = 5, + .tm_year = 120, + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst= 0, + }; + struct tm now, alarm = t1; + alarm.tm_hour++; + + rtc_set_time(&t1); + rtc_set_alarm(&alarm, _alarm_cb, &alarm); + + rtt_add_ticks(60 * RTT_FREQUENCY); + t1.tm_min++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + rtt_add_ticks(24*60*60UL * RTT_FREQUENCY); + t1.tm_mday++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + TEST_ASSERT_EQUAL_INT(1, alarm.tm_isdst); +} + +static void test_set_alarm_short(void) +{ + struct tm t1 = { + .tm_sec = 42, + .tm_min = 37, + .tm_hour = 13, + .tm_mday = 23, + .tm_mon = 5, + .tm_year = 120, + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst= 0, + }; + struct tm now, alarm = t1; + alarm.tm_sec += 10; + + rtc_set_time(&t1); + rtc_set_alarm(&alarm, _alarm_cb, &alarm); + + rtt_add_ticks(60 * RTT_FREQUENCY); + t1.tm_min++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + rtt_add_ticks(60*60 * RTT_FREQUENCY); + t1.tm_hour++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + TEST_ASSERT_EQUAL_INT(1, alarm.tm_isdst); +} + +static void test_set_alarm_set_time(void) +{ + struct tm t1 = { + .tm_sec = 42, + .tm_min = 37, + .tm_hour = 13, + .tm_mday = 23, + .tm_mon = 5, + .tm_year = 120, + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst= 0, + }; + struct tm now, alarm = t1; + alarm.tm_hour += 5; + + rtc_set_time(&t1); + rtc_set_alarm(&alarm, _alarm_cb, &alarm); + + t1.tm_hour += 4; + rtc_set_time(&t1); + + rtt_add_ticks(60 * RTT_FREQUENCY); + t1.tm_min++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + rtt_add_ticks(60*60 * RTT_FREQUENCY); + t1.tm_hour++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + TEST_ASSERT_EQUAL_INT(1, alarm.tm_isdst); + + rtc_set_alarm(&alarm, _alarm_cb, &alarm); + + t1.tm_hour--; + rtc_set_time(&t1); + rtt_add_ticks(60*60 * RTT_FREQUENCY); + t1.tm_hour++; + rtc_get_time(&now); + TEST_ASSERT_EQUAL_INT(t1.tm_sec, now.tm_sec); + TEST_ASSERT_EQUAL_INT(t1.tm_min, now.tm_min); + TEST_ASSERT_EQUAL_INT(0, rtc_tm_compare(&t1, &now)); + + TEST_ASSERT_EQUAL_INT(2, alarm.tm_isdst); + + rtt_add_ticks(60*60 * RTT_FREQUENCY); + TEST_ASSERT_EQUAL_INT(2, alarm.tm_isdst); +} + +Test *tests_rtt_rtt_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_set_time), + new_TestFixture(test_set_alarm), + new_TestFixture(test_set_alarm_short), + new_TestFixture(test_set_alarm_set_time), + }; + + EMB_UNIT_TESTCALLER(rtt_rtc_tests, NULL, NULL, fixtures); + + return (Test *)&rtt_rtc_tests; +} + +void tests_rtt_rtc(void) +{ + rtc_init(); + rtt_add_ticks(10); + TESTS_RUN(tests_rtt_rtt_tests()); +} +/** @} */ diff --git a/tests/unittests/tests-rtt_rtc/tests-rtt_rtc.h b/tests/unittests/tests-rtt_rtc/tests-rtt_rtc.h new file mode 100644 index 0000000000..c5065b24ad --- /dev/null +++ b/tests/unittests/tests-rtt_rtc/tests-rtt_rtc.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 Benjamin Valentin + * + * 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. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file + * @brief Unittests for the ``rtt_rtc`` module + * + * @author Benjamin Valentin + */ +#ifndef TESTS_RTT_RTC_H +#define TESTS_RTT_RTC_H + +#include "embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The entry point of this test suite. + */ +void tests_rtt_rtc(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TESTS_RTT_RTC_H */ +/** @} */