Skip to content

Commit 0ebd718

Browse files
nordic-baminordic-piks
authored andcommitted
tests: drivers: timer: Run GRTC timer (LFRC src) on nrf54l
Run the GRTC timer (sourced from LFRC) accuracy test on the nrf54l devices Signed-off-by: Bartosz Miller <[email protected]>
1 parent 1f9ed59 commit 0ebd718

File tree

10 files changed

+216
-95
lines changed

10 files changed

+216
-95
lines changed

tests/drivers/timer/grtc_timer_lfrc/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ cmake_minimum_required(VERSION 3.20.0)
55
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
66
project(nrf_grtc_timer)
77

8-
FILE(GLOB app_sources src/*.c)
9-
target_sources(app PRIVATE ${app_sources})
8+
target_sources(app PRIVATE src/common.c src/main.c)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */
2+
3+
/ {
4+
aliases {
5+
tst-timer = &timer20;
6+
};
7+
};
8+
9+
&timer20 {
10+
status = "okay";
11+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */
2+
3+
/ {
4+
aliases {
5+
tst-timer = &timer20;
6+
};
7+
};
8+
9+
&timer20 {
10+
status = "okay";
11+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */
2+
3+
/ {
4+
aliases {
5+
tst-timer = &timer20;
6+
};
7+
};
8+
9+
&timer20 {
10+
status = "okay";
11+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */
2+
3+
/ {
4+
aliases {
5+
tst-timer = &timer20;
6+
};
7+
};
8+
9+
&timer20 {
10+
status = "okay";
11+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */
2+
3+
/ {
4+
aliases {
5+
tst-timer = &timer20;
6+
};
7+
};
8+
9+
&timer20 {
10+
status = "okay";
11+
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2025, Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include "common.h"
8+
9+
#if defined(CONFIG_SOC_NRF54H20)
10+
const struct device *const lfclk_dev = DEVICE_DT_GET(DT_NODELABEL(lfclk));
11+
const struct device *const fll16m_dev = DEVICE_DT_GET(DT_NODELABEL(fll16m));
12+
13+
const struct nrf_clock_spec lfclk_lfrc_mode = {
14+
.frequency = 32768,
15+
.accuracy = 0,
16+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
17+
};
18+
19+
const struct nrf_clock_spec lfclk_synth_mode = {
20+
.frequency = 32768,
21+
.accuracy = 30,
22+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
23+
};
24+
25+
const struct nrf_clock_spec fll16m_bypass_mode = {
26+
.frequency = MHZ(16),
27+
.accuracy = 30,
28+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
29+
};
30+
31+
#else
32+
const struct device *const hfclock = DEVICE_DT_GET(DT_NODELABEL(clock));
33+
#endif /* CONFIG_SOC_NRF54H20 */
34+
35+
#if defined(CONFIG_SOC_NRF54H20)
36+
int request_clock_spec(const struct device *clk_dev, const struct nrf_clock_spec *clk_spec)
37+
{
38+
int ret = 0;
39+
int res = 0;
40+
struct onoff_client cli;
41+
uint32_t rate;
42+
43+
printk("Clock: %s, requesting frequency=%d, accuracy=%d, precision=%d\n", clk_dev->name,
44+
clk_spec->frequency, clk_spec->accuracy, clk_spec->precision);
45+
sys_notify_init_spinwait(&cli.notify);
46+
ret = nrf_clock_control_request(clk_dev, clk_spec, &cli);
47+
if (!(ret >= 0 && ret <= 2)) {
48+
return -1;
49+
}
50+
do {
51+
ret = sys_notify_fetch_result(&cli.notify, &res);
52+
k_yield();
53+
} while (ret == -EAGAIN);
54+
if (ret != 0) {
55+
return -2;
56+
}
57+
if (res != 0) {
58+
return -3;
59+
}
60+
ret = clock_control_get_rate(clk_dev, NULL, &rate);
61+
if (ret != -ENOSYS) {
62+
if (ret != 0) {
63+
return -4;
64+
}
65+
if (rate != clk_spec->frequency) {
66+
return -5;
67+
};
68+
k_busy_wait(REQUEST_SERVING_WAIT_TIME_US);
69+
}
70+
71+
return 0;
72+
}
73+
#endif /* CONFIG_SOC_NRF54H20 */
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2025, Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/drivers/timer/nrf_grtc_timer.h>
9+
#include <hal/nrf_grtc.h>
10+
#include <zephyr/drivers/counter.h>
11+
#include <zephyr/drivers/counter.h>
12+
#include <zephyr/devicetree/clocks.h>
13+
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
14+
15+
#define REQUEST_SERVING_WAIT_TIME_US 10000
16+
#define HFCLOCK_SETUP_TIME_MS 500
17+
#if defined(CONFIG_COVERAGE)
18+
#define DIFF_TOLERANCE 2
19+
#else
20+
#define DIFF_TOLERANCE 1
21+
#endif
22+
#define NUMBER_OF_REPETITIONS 5
23+
24+
typedef enum {
25+
NO_CHANGE = 0,
26+
CHANGE_TO_SYNTH = 1,
27+
CHANGE_TO_LFRC = 2
28+
} lfclk_source_change_option;
29+
30+
struct accuracy_test_limit {
31+
uint32_t grtc_timer_count_time_ms;
32+
uint32_t time_delta_abs_tolerance_us;
33+
};
34+
35+
int request_clock_spec(const struct device *clk_dev, const struct nrf_clock_spec *clk_spec);

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

Lines changed: 28 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3,95 +3,30 @@
33
*
44
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
55
*/
6-
#include <zephyr/kernel.h>
7-
#include <zephyr/drivers/timer/nrf_grtc_timer.h>
8-
#include <hal/nrf_grtc.h>
9-
#include <zephyr/drivers/counter.h>
10-
#include <zephyr/devicetree/clocks.h>
11-
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
12-
13-
#define REQUEST_SERVING_WAIT_TIME_US 10000
14-
#if defined(CONFIG_COVERAGE)
15-
#define DIFF_TOLERANCE 2
16-
#else
17-
#define DIFF_TOLERANCE 1
18-
#endif
19-
#define NUMBER_OF_REPETITIONS 5
206

21-
typedef enum {
22-
NO_CHANGE = 0,
23-
CHANGE_TO_SYNTH = 1,
24-
CHANGE_TO_LFRC = 2
25-
} lfclk_source_change_option;
26-
27-
struct accuracy_test_limit {
28-
uint32_t grtc_timer_count_time_ms;
29-
uint32_t time_delta_abs_tolerance_us;
30-
};
7+
#include "common.h"
318

329
static volatile uint8_t compare_isr_call_counter;
3310
static volatile uint64_t compare_count_value;
3411
static volatile uint64_t reference_timer_value_us;
3512

3613
const struct device *const tst_timer_dev = DEVICE_DT_GET(DT_ALIAS(tst_timer));
37-
const struct device *const lfclk_dev = DEVICE_DT_GET(DT_NODELABEL(lfclk));
38-
const struct device *const fll16m_dev = DEVICE_DT_GET(DT_NODELABEL(fll16m));
39-
40-
const struct nrf_clock_spec lfclk_lfrc_mode = {
41-
.frequency = 32768,
42-
.accuracy = 0,
43-
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
44-
};
4514

46-
const struct nrf_clock_spec lfclk_synth_mode = {
47-
.frequency = 32768,
15+
const struct nrf_clock_spec clock_hf = {
16+
.frequency = MHZ(32),
4817
.accuracy = 30,
4918
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
5019
};
5120

52-
const struct nrf_clock_spec fll16m_bypass_mode = {
53-
.frequency = MHZ(16),
54-
.accuracy = 30,
55-
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
56-
};
57-
58-
static int request_clock_spec(const struct device *clk_dev, const struct nrf_clock_spec *clk_spec)
59-
{
60-
int ret = 0;
61-
int res = 0;
62-
struct onoff_client cli;
63-
uint32_t rate;
64-
65-
printk("Clock: %s, requesting frequency=%d, accuracy=%d, precision=%d\n", clk_dev->name,
66-
clk_spec->frequency, clk_spec->accuracy, clk_spec->precision);
67-
sys_notify_init_spinwait(&cli.notify);
68-
ret = nrf_clock_control_request(clk_dev, clk_spec, &cli);
69-
if (!(ret >= 0 && ret <= 2)) {
70-
return -1;
71-
}
72-
do {
73-
ret = sys_notify_fetch_result(&cli.notify, &res);
74-
k_yield();
75-
} while (ret == -EAGAIN);
76-
if (ret != 0) {
77-
return -2;
78-
}
79-
if (res != 0) {
80-
return -3;
81-
}
82-
ret = clock_control_get_rate(clk_dev, NULL, &rate);
83-
if (ret != -ENOSYS) {
84-
if (ret != 0) {
85-
return -4;
86-
}
87-
if (rate != clk_spec->frequency) {
88-
return -5;
89-
};
90-
k_busy_wait(REQUEST_SERVING_WAIT_TIME_US);
91-
}
92-
93-
return 0;
94-
}
21+
#if defined(CONFIG_SOC_NRF54H20)
22+
extern const struct device *const lfclk_dev;
23+
extern const struct device *const fll16m_dev;
24+
extern const struct nrf_clock_spec lfclk_lfrc_mode;
25+
extern const struct nrf_clock_spec lfclk_synth_mode;
26+
extern const struct nrf_clock_spec fll16m_bypass_mode;
27+
#else
28+
extern const struct device *const hfclock;
29+
#endif /* CONFIG_SOC_NRF54H20 */
9530

9631
static void timer_compare_interrupt_handler(int32_t id, uint64_t expire_time, void *user_data)
9732
{
@@ -140,6 +75,8 @@ static int test_timer_compare(int32_t channel, const struct accuracy_test_limit
14075
printk("Compare register set failed\n");
14176
return -2;
14277
}
78+
79+
#if defined(CONFIG_SOC_NRF54H20)
14380
if (tst_dynamic_clk_change_option == CHANGE_TO_SYNTH) {
14481
printk("Changing clock source of the GRTC (LFCLK) to SYNTH while waiting for "
14582
"compare callback\n");
@@ -151,6 +88,9 @@ static int test_timer_compare(int32_t channel, const struct accuracy_test_limit
15188
} else {
15289
printk("Clock source change not requested\n");
15390
}
91+
#else /* CONFIG_SOC_NRF54H20 */
92+
printk("Clock source change not supported\n");
93+
#endif
15494

15595
k_sleep(K_MSEC(2 * test_limit->grtc_timer_count_time_ms));
15696
if (compare_isr_call_counter != 1) {
@@ -188,19 +128,21 @@ static int test_timer_count_in_compare_mode_lfclk_source_from_lfrc(int32_t grtc_
188128
.time_delta_abs_tolerance_us = 250};
189129

190130
printk("test_timer_count_in_compare_mode_lfclk_source_from_lfrc\n");
131+
#if defined(CONFIG_SOC_NRF54H20)
191132
request_clock_spec(lfclk_dev, &lfclk_lfrc_mode);
192133
if (ret != 0) {
193134
printk("Clock request failed: %d\n", ret);
194135
return -1;
195136
}
137+
#endif /* CONFIG_SOC_NRF54H20 */
196138

197139
for (int i = 0; i < NUMBER_OF_REPETITIONS; i++) {
198140
ret += test_timer_compare(grtc_channel, &test_limit, NO_CHANGE);
199141
}
200142
return ret;
201143
}
202144

203-
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
145+
#if defined(CONFIG_SOC_NRF54H20_CPUAPP)
204146
static int test_timer_count_in_compare_mode_lfclk_source_from_synth(int32_t grtc_channel)
205147
{
206148
int ret = 0;
@@ -257,14 +199,19 @@ static int test_timer_count_in_compare_mode_lfclk_runtime_update_synth_to_lfrc(i
257199
}
258200
return ret;
259201
}
260-
#endif /* !CONFIG_SOC_NRF54H20_CPURAD */
202+
#endif /* CONFIG_SOC_NRF54H20_CPUAPP */
261203

262204
int main(void)
263205
{
264206
int32_t grtc_channel;
265207
int ret = 0;
266208

209+
#if defined(CONFIG_SOC_NRF54H20)
267210
ret = request_clock_spec(fll16m_dev, &fll16m_bypass_mode);
211+
#else
212+
k_msleep(HFCLOCK_SETUP_TIME_MS);
213+
ret = clock_control_on(hfclock, CLOCK_CONTROL_NRF_SUBSYS_HF);
214+
#endif /* CONFIG_SOC_NRF54H20 */
268215
if (ret != 0) {
269216
printk("Clock request failed: %d\n", ret);
270217
return -1;
@@ -279,12 +226,11 @@ int main(void)
279226
}
280227

281228
ret = test_timer_count_in_compare_mode_lfclk_source_from_lfrc(grtc_channel);
282-
#if !defined(CONFIG_SOC_NRF54H20_CPURAD)
283-
/* Swiching to SYNTH via Clock Control Api is not possible from CPURAD */
229+
#if defined(CONFIG_SOC_NRF54H20_CPUAPP)
284230
ret += test_timer_count_in_compare_mode_lfclk_source_from_synth(grtc_channel);
285231
ret += test_timer_count_in_compare_mode_lfclk_runtime_update_lfrc_to_synth(grtc_channel);
286232
ret += test_timer_count_in_compare_mode_lfclk_runtime_update_synth_to_lfrc(grtc_channel);
287-
#endif /* !CONFIG_SOC_NRF54H20_CPURAD */
233+
#endif /* CONFIG_SOC_NRF54H20_CPUAPP */
288234

289235
if (ret != 0) {
290236
printk("Tests status: FAIL\n");

0 commit comments

Comments
 (0)