1 /*
2 * Copyright (c) 2022, Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/ztest.h>
7 #include <zephyr/drivers/timer/nrf_grtc_timer.h>
8 #include <hal/nrf_grtc.h>
9
10 #define GRTC_SLEW_TICKS 10
11 #define NUMBER_OF_TRIES 2000
12 #define CYC_PER_TICK \
13 ((uint64_t)sys_clock_hw_cycles_per_sec() / (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC)
14 #define TIMER_COUNT_TIME_MS 10
15 #define WAIT_FOR_TIMER_EVENT_TIME_MS TIMER_COUNT_TIME_MS + 5
16
17 static volatile uint8_t compare_isr_call_counter;
18
19 /* GRTC timer compare interrupt handler */
timer_compare_interrupt_handler(int32_t id,uint64_t expire_time,void * user_data)20 static void timer_compare_interrupt_handler(int32_t id, uint64_t expire_time, void *user_data)
21 {
22 compare_isr_call_counter++;
23 TC_PRINT("Compare value reached, user data: '%s'\n", (char *)user_data);
24 TC_PRINT("Call counter: %d\n", compare_isr_call_counter);
25 }
26
ZTEST(nrf_grtc_timer,test_get_ticks)27 ZTEST(nrf_grtc_timer, test_get_ticks)
28 {
29 k_timeout_t t = K_MSEC(1);
30
31 uint64_t exp_ticks = z_nrf_grtc_timer_read() + t.ticks * CYC_PER_TICK;
32 int64_t ticks;
33
34 /* Relative 1ms from now timeout converted to GRTC */
35 ticks = z_nrf_grtc_timer_get_ticks(t);
36 zassert_true((ticks >= exp_ticks) && (ticks <= (exp_ticks + GRTC_SLEW_TICKS)),
37 "Unexpected result %" PRId64 " (expected: %" PRId64 ")", ticks, exp_ticks);
38
39 k_msleep(1);
40
41 for (uint32_t i = 0; i < NUMBER_OF_TRIES; i++) {
42 /* Absolute timeout 1ms in the past */
43 t = Z_TIMEOUT_TICKS(Z_TICK_ABS(sys_clock_tick_get() - K_MSEC(1).ticks));
44
45 exp_ticks = z_nrf_grtc_timer_read() - K_MSEC(1).ticks * CYC_PER_TICK;
46 ticks = z_nrf_grtc_timer_get_ticks(t);
47 zassert_true((ticks >= (exp_ticks - CYC_PER_TICK + 1)) &&
48 (ticks <= (exp_ticks + GRTC_SLEW_TICKS)),
49 "Unexpected result %" PRId64 " (expected: %" PRId64 ")", ticks,
50 exp_ticks);
51
52 /* Absolute timeout 10ms in the future */
53 t = Z_TIMEOUT_TICKS(Z_TICK_ABS(sys_clock_tick_get() + K_MSEC(10).ticks));
54 exp_ticks = z_nrf_grtc_timer_read() + K_MSEC(10).ticks * CYC_PER_TICK;
55 ticks = z_nrf_grtc_timer_get_ticks(t);
56 zassert_true((ticks >= (exp_ticks - CYC_PER_TICK + 1)) &&
57 (ticks <= (exp_ticks + GRTC_SLEW_TICKS)),
58 "Unexpected result %" PRId64 " (expected: %" PRId64 ")", ticks,
59 exp_ticks);
60 }
61 }
62
ZTEST(nrf_grtc_timer,test_timer_count_in_compare_mode)63 ZTEST(nrf_grtc_timer, test_timer_count_in_compare_mode)
64 {
65 int err;
66 uint64_t test_ticks = 0;
67 uint64_t compare_value = 0;
68 char user_data[] = "test_timer_count_in_compare_mode\n";
69 int32_t channel = z_nrf_grtc_timer_chan_alloc();
70
71 TC_PRINT("Allocated GRTC channel %d\n", channel);
72 if (channel < 0) {
73 TC_PRINT("Failed to allocate GRTC channel, chan=%d\n", channel);
74 ztest_test_fail();
75 }
76
77 compare_isr_call_counter = 0;
78 test_ticks = z_nrf_grtc_timer_get_ticks(K_MSEC(TIMER_COUNT_TIME_MS));
79 err = z_nrf_grtc_timer_set(channel, test_ticks, timer_compare_interrupt_handler,
80 (void *)user_data);
81
82 zassert_equal(err, 0, "z_nrf_grtc_timer_set raised an error: %d", err);
83
84 z_nrf_grtc_timer_compare_read(channel, &compare_value);
85 zassert_true(K_TIMEOUT_EQ(K_TICKS(compare_value), K_TICKS(test_ticks)),
86 "Compare register set failed");
87 zassert_equal(err, 0, "Unexpected error raised when setting timer, err: %d", err);
88
89 k_sleep(K_MSEC(WAIT_FOR_TIMER_EVENT_TIME_MS));
90
91 TC_PRINT("Compare event generated ?: %d\n", z_nrf_grtc_timer_compare_evt_check(channel));
92 TC_PRINT("Compare event register address: %X\n",
93 z_nrf_grtc_timer_compare_evt_address_get(channel));
94
95 zassert_equal(compare_isr_call_counter, 1, "Compare isr call counter: %d",
96 compare_isr_call_counter);
97 z_nrf_grtc_timer_chan_free(channel);
98 }
99
ZTEST(nrf_grtc_timer,test_timer_abort_in_compare_mode)100 ZTEST(nrf_grtc_timer, test_timer_abort_in_compare_mode)
101 {
102 int err;
103 uint64_t test_ticks = 0;
104 uint64_t compare_value = 0;
105 char user_data[] = "test_timer_abort_in_compare_mode\n";
106 int32_t channel = z_nrf_grtc_timer_chan_alloc();
107
108 TC_PRINT("Allocated GRTC channel %d\n", channel);
109 if (channel < 0) {
110 TC_PRINT("Failed to allocate GRTC channel, chan=%d\n", channel);
111 ztest_test_fail();
112 }
113
114 compare_isr_call_counter = 0;
115 test_ticks = z_nrf_grtc_timer_get_ticks(K_MSEC(TIMER_COUNT_TIME_MS));
116 err = z_nrf_grtc_timer_set(channel, test_ticks, timer_compare_interrupt_handler,
117 (void *)user_data);
118 zassert_equal(err, 0, "z_nrf_grtc_timer_set raised an error: %d", err);
119
120 z_nrf_grtc_timer_abort(channel);
121
122 z_nrf_grtc_timer_compare_read(channel, &compare_value);
123 zassert_true(K_TIMEOUT_EQ(K_TICKS(compare_value), K_TICKS(test_ticks)),
124 "Compare register set failed");
125
126 zassert_equal(err, 0, "Unexpected error raised when setting timer, err: %d", err);
127
128 k_sleep(K_MSEC(WAIT_FOR_TIMER_EVENT_TIME_MS));
129 zassert_equal(compare_isr_call_counter, 0, "Compare isr call counter: %d",
130 compare_isr_call_counter);
131 z_nrf_grtc_timer_chan_free(channel);
132 }
133
134 ZTEST_SUITE(nrf_grtc_timer, NULL, NULL, NULL, NULL, NULL);
135