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