Skip to content

Commit aa24270

Browse files
nordic-baminordic-piks
authored andcommitted
tests: timer: Extend GRTC LFRC sourced timer test
Test the LFRC based GRTC timer count accuracy. Signed-off-by: Bartosz Miller <[email protected]>
1 parent 3fa3025 commit aa24270

File tree

3 files changed

+113
-17
lines changed

3 files changed

+113
-17
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
/* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */
22

3+
/ {
4+
aliases {
5+
tst-timer = &timer130;
6+
};
7+
};
8+
39
&grtc {
410
/delete-property/ child-owned-channels;
511
};
12+
13+
&timer130 {
14+
status = "okay";
15+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
CONFIG_ZTEST=y
22
CONFIG_NRF_GRTC_TIMER=y
33
CONFIG_CLOCK_CONTROL=y
4+
CONFIG_COUNTER=y
45

56
CONFIG_LOG=y
67
CONFIG_CLOCK_CONTROL_LOG_LEVEL_DBG=y

tests/drivers/timer/grtc_timer_lfrc/src/main.c

Lines changed: 102 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <zephyr/ztest.h>
77
#include <zephyr/drivers/timer/nrf_grtc_timer.h>
88
#include <hal/nrf_grtc.h>
9+
#include <zephyr/drivers/counter.h>
910
#include <zephyr/devicetree/clocks.h>
1011
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
1112

@@ -17,7 +18,16 @@ typedef enum {
1718
CHANGE_TO_LFRC = 2
1819
} lfclk_source_change_option;
1920

20-
const struct device *lfclk_dev = DEVICE_DT_GET(DT_NODELABEL(lfclk));
21+
struct accuracy_test_limit {
22+
bool is_reference_timer_enabled;
23+
uint32_t grtc_timer_count_time_ms;
24+
uint32_t time_delta_abs_tolerance_us;
25+
uint64_t final_max_ticks_count_difference;
26+
};
27+
28+
const struct device *const tst_timer_dev = DEVICE_DT_GET(DT_ALIAS(tst_timer));
29+
const struct device *const lfclk_dev = DEVICE_DT_GET(DT_NODELABEL(lfclk));
30+
const struct device *const fll16m_dev = DEVICE_DT_GET(DT_NODELABEL(fll16m));
2131
static volatile uint8_t compare_isr_call_counter;
2232
static volatile uint64_t compare_count_value;
2333

@@ -33,6 +43,12 @@ const struct nrf_clock_spec lfclk_synth_mode = {
3343
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
3444
};
3545

46+
const struct nrf_clock_spec fll16m_bypass_mode = {
47+
.frequency = MHZ(16),
48+
.accuracy = 30,
49+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
50+
};
51+
3652
static void request_clock_spec(const struct device *clk_dev, const struct nrf_clock_spec *clk_spec)
3753
{
3854
int ret = 0;
@@ -61,32 +77,69 @@ static void request_clock_spec(const struct device *clk_dev, const struct nrf_cl
6177

6278
static void timer_compare_interrupt_handler(int32_t id, uint64_t expire_time, void *user_data)
6379
{
80+
uint32_t tst_timer_value;
81+
uint64_t reference_timer_value_us;
82+
struct accuracy_test_limit *test_limit = (struct accuracy_test_limit *)user_data;
83+
6484
compare_count_value = z_nrf_grtc_timer_read();
6585
compare_isr_call_counter++;
66-
TC_PRINT("Compare value reached, user data: '%s'\n", (char *)user_data);
67-
TC_PRINT("Call counter: %d\n", compare_isr_call_counter);
86+
if (test_limit->is_reference_timer_enabled) {
87+
counter_stop(tst_timer_dev);
88+
counter_get_value(tst_timer_dev, &tst_timer_value);
89+
reference_timer_value_us = counter_ticks_to_us(tst_timer_dev, tst_timer_value);
90+
TC_PRINT("Reference timer value [us]: %llu\n", reference_timer_value_us);
91+
TC_PRINT("Time delta (Specified (GRTC) - referecne timer) [us]: %lld\n",
92+
(uint64_t)test_limit->grtc_timer_count_time_ms * 1000 -
93+
reference_timer_value_us);
94+
zassert_true((uint64_t)test_limit->grtc_timer_count_time_ms * 1000 <
95+
reference_timer_value_us +
96+
test_limit->time_delta_abs_tolerance_us,
97+
"GRTC timer count value is over upper limit");
98+
zassert_true((uint64_t)test_limit->grtc_timer_count_time_ms * 1000 >
99+
reference_timer_value_us -
100+
test_limit->time_delta_abs_tolerance_us,
101+
"GRTC timer count value is under lower limit");
102+
}
103+
104+
TC_PRINT("Compare count value [ticks]: %llu\n", compare_count_value);
105+
}
106+
107+
static void configure_test_timer(const struct device *timer_dev, uint32_t count_time_ms)
108+
{
109+
struct counter_alarm_cfg counter_cfg;
110+
111+
counter_cfg.flags = 0;
112+
counter_cfg.ticks = counter_us_to_ticks(timer_dev, (uint64_t)count_time_ms * 1000);
113+
counter_cfg.user_data = &counter_cfg;
68114
}
69115

70-
static void test_timer_compare(uint32_t timer_count_time_ms,
116+
static void test_timer_compare(const struct accuracy_test_limit *test_limit,
71117
lfclk_source_change_option tst_dynamic_clk_change_option)
72118
{
73119
int err;
74120
uint64_t test_ticks = 0;
75121
uint64_t compare_value = 0;
76-
char user_data[] = "test_timer_count_in_compare_mode\n";
77122
int32_t channel = z_nrf_grtc_timer_chan_alloc();
78123

124+
if (test_limit->is_reference_timer_enabled) {
125+
TC_PRINT("Reference timer (HFCLK sourced) is enabled\n");
126+
configure_test_timer(tst_timer_dev, test_limit->grtc_timer_count_time_ms * 2);
127+
}
128+
79129
TC_PRINT("Allocated GRTC channel %d\n", channel);
80130
if (channel < 0) {
81131
TC_PRINT("Failed to allocate GRTC channel, chan=%d\n", channel);
82132
ztest_test_fail();
83133
}
84134

85135
compare_isr_call_counter = 0;
86-
test_ticks = z_nrf_grtc_timer_get_ticks(K_MSEC(timer_count_time_ms));
136+
test_ticks = z_nrf_grtc_timer_get_ticks(K_MSEC(test_limit->grtc_timer_count_time_ms));
87137
err = z_nrf_grtc_timer_set(channel, test_ticks, timer_compare_interrupt_handler,
88-
(void *)user_data);
138+
(void *)test_limit);
89139

140+
if (test_limit->is_reference_timer_enabled) {
141+
counter_start(tst_timer_dev);
142+
}
90143
zassert_equal(err, 0, "z_nrf_grtc_timer_set raised an error: %d", err);
91144

92145
z_nrf_grtc_timer_compare_read(channel, &compare_value);
@@ -106,45 +159,77 @@ static void test_timer_compare(uint32_t timer_count_time_ms,
106159
TC_PRINT("Clock source change not requested\n");
107160
}
108161

109-
k_sleep(K_MSEC(2 * timer_count_time_ms));
162+
k_sleep(K_MSEC(2 * test_limit->grtc_timer_count_time_ms));
110163
zassert_equal(compare_isr_call_counter, 1, "Compare isr call counter: %d",
111164
compare_isr_call_counter);
112165

113166
TC_PRINT("Compare count - initial compare value: %lld\n",
114167
compare_count_value - compare_value);
168+
169+
zassert_true((compare_count_value - compare_value) <
170+
test_limit->final_max_ticks_count_difference,
171+
"Maximal final ticks count difference is over the limit");
115172
z_nrf_grtc_timer_chan_free(channel);
116173
}
117174

175+
/*
176+
* This test uses HFCLK based timer130 as a reference.
177+
* The timers start is not ideally sunchronised,
178+
* this is taken into account in the limit
179+
*/
118180
ZTEST(grtc_timer_lfrc, test_timer_count_in_compare_mode_lfclk_source_from_lfrc)
119181
{
120-
uint32_t timer_count_time_ms = 50;
182+
const struct accuracy_test_limit test_limit = {.is_reference_timer_enabled = true,
183+
.grtc_timer_count_time_ms = 1000,
184+
.time_delta_abs_tolerance_us = 15,
185+
.final_max_ticks_count_difference = 50};
121186

122187
request_clock_spec(lfclk_dev, &lfclk_lfrc_mode);
123-
test_timer_compare(timer_count_time_ms, false);
188+
test_timer_compare(&test_limit, NO_CHANGE);
124189
}
125190

126191
ZTEST(grtc_timer_lfrc, test_timer_count_in_compare_mode_lfclk_source_from_synth)
127192
{
128-
uint32_t timer_count_time_ms = 50;
193+
const struct accuracy_test_limit test_limit = {.is_reference_timer_enabled = false,
194+
.grtc_timer_count_time_ms = 50,
195+
.time_delta_abs_tolerance_us = 0,
196+
.final_max_ticks_count_difference = 50};
129197

130198
request_clock_spec(lfclk_dev, &lfclk_synth_mode);
131-
test_timer_compare(timer_count_time_ms, false);
199+
test_timer_compare(&test_limit, NO_CHANGE);
132200
}
133201

134202
ZTEST(grtc_timer_lfrc, test_timer_count_in_compare_mode_lfclk_runtime_update_lfrc_to_synth)
135203
{
136-
uint32_t timer_count_time_ms = 500;
204+
const struct accuracy_test_limit test_limit = {.is_reference_timer_enabled = false,
205+
.grtc_timer_count_time_ms = 250,
206+
.time_delta_abs_tolerance_us = 0,
207+
.final_max_ticks_count_difference = 50};
137208

138209
request_clock_spec(lfclk_dev, &lfclk_lfrc_mode);
139-
test_timer_compare(timer_count_time_ms, CHANGE_TO_SYNTH);
210+
test_timer_compare(&test_limit, CHANGE_TO_SYNTH);
140211
}
141212

142213
ZTEST(grtc_timer_lfrc, test_timer_count_in_compare_mode_lfclk_runtime_update_synth_to_lfrc)
143214
{
144-
uint32_t timer_count_time_ms = 500;
215+
const struct accuracy_test_limit test_limit = {.is_reference_timer_enabled = false,
216+
.grtc_timer_count_time_ms = 250,
217+
.time_delta_abs_tolerance_us = 0,
218+
.final_max_ticks_count_difference = 50};
145219

146220
request_clock_spec(lfclk_dev, &lfclk_synth_mode);
147-
test_timer_compare(timer_count_time_ms, CHANGE_TO_LFRC);
221+
test_timer_compare(&test_limit, CHANGE_TO_LFRC);
222+
}
223+
224+
/*
225+
* FLL16M must be set in bypass mode
226+
* to achieve the HFCLK 30ppm accuracy
227+
*/
228+
void *test_setup(void)
229+
{
230+
request_clock_spec(fll16m_dev, &fll16m_bypass_mode);
231+
232+
return NULL;
148233
}
149234

150-
ZTEST_SUITE(grtc_timer_lfrc, NULL, NULL, NULL, NULL, NULL);
235+
ZTEST_SUITE(grtc_timer_lfrc, NULL, test_setup, NULL, NULL, NULL);

0 commit comments

Comments
 (0)