1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/tc_util.h>
9 #include <zephyr/ztest.h>
10 
test_frequency(void)11 int test_frequency(void)
12 {
13 	volatile uint32_t start, end;
14 	uint32_t delta, pct;
15 
16 	TC_PRINT("Testing system tick frequency\n");
17 
18 	start = k_cycle_get_32();
19 	k_sleep(K_MSEC(1000));
20 	end = k_cycle_get_32();
21 
22 	delta = end - start;
23 	pct = (uint64_t)delta * 100U / sys_clock_hw_cycles_per_sec();
24 
25 	printk("delta: %u  expected: %u  %u%%\n", delta,
26 	       sys_clock_hw_cycles_per_sec(), pct);
27 
28 	/* Heuristic: if we're more than 10% off, throw an error */
29 	if (pct < 90 || pct > 110) {
30 		TC_PRINT("Clock calibration is way off!\n");
31 		return -1;
32 	}
33 
34 	return 0;
35 }
36 
37 /**
38  * @brief Test monotonic timer
39  *
40  * Validates monotonic timer's clock calibration.
41  *
42  * It reads the System clock’s h/w timer frequency value continuously
43  * using k_cycle_get_32() to verify its working and correctness.
44  * It also checks system tick frequency by checking the delta error
45  * between generated and system clock provided HW cycles per sec values.
46  *
47  * @ingroup kernel_timer_tests
48  *
49  * @see k_cycle_get_32(), sys_clock_hw_cycles_per_sec()
50  */
ZTEST(timer_fn,test_timer)51 ZTEST(timer_fn, test_timer)
52 {
53 	volatile uint32_t t_last, t_now;
54 	uint32_t i, errors;
55 	int32_t diff;
56 
57 	errors = 0U;
58 
59 	TC_PRINT("k_ticks_to_cyc_floor32(1) = %d\n",
60 		 k_ticks_to_cyc_floor32(1));
61 	TC_PRINT("sys_clock_hw_cycles_per_sec() = %d\n",
62 		 sys_clock_hw_cycles_per_sec());
63 
64 	t_last = k_cycle_get_32();
65 
66 	for (i = 0U; i < 1000000; i++) {
67 		t_now = k_cycle_get_32();
68 
69 		if (t_now < t_last) {
70 			diff = t_now - t_last;
71 			TC_PRINT("diff = %d (t_last = %u : t_now = %u);"
72 				"i = %u\n", diff, t_last, t_now, i);
73 			errors++;
74 		}
75 		t_last = t_now;
76 	}
77 
78 	zassert_false(errors, "errors = %d\n", errors);
79 
80 	zassert_false(test_frequency(), "test frequency failed");
81 }
82 
83 ZTEST_SUITE(timer_fn, NULL, NULL, NULL, NULL, NULL);
84