1 /*
2 * Copyright (c) 2021 Friedt Professional Engineering Services, Inc
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/kernel.h>
9
swap64(uint64_t * a,uint64_t * b)10 static void swap64(uint64_t *a, uint64_t *b)
11 {
12 uint64_t t = *a;
13 *a = *b;
14 *b = t;
15 }
16
msg(uint64_t c64)17 static void msg(uint64_t c64)
18 {
19 int64_t ms = k_uptime_get();
20 int s = ms / 1000;
21 int m = s / 60;
22 int h = m / 60;
23 int d = h / 24;
24
25 h %= 24;
26 m %= 60;
27 s %= 60;
28 ms %= 1000;
29
30 printk("[%03d:%02d:%02d:%02d.%03d]: cycle: %016" PRIx64 "\n", d, h, m, s, (int)ms, c64);
31 }
32
timeout(uint64_t prev,uint64_t now)33 uint32_t timeout(uint64_t prev, uint64_t now)
34 {
35 uint64_t next = prev + BIT64(32) - now;
36
37 next &= UINT32_MAX;
38 if (next == 0) {
39 next = UINT32_MAX;
40 }
41
42 return (uint32_t)next;
43 }
44
ZTEST(cycle64_tests,test_32bit_wrap_around)45 ZTEST(cycle64_tests, test_32bit_wrap_around)
46 {
47 enum {
48 CURR,
49 PREV,
50 };
51
52 int i;
53 uint64_t now;
54 uint64_t c64[2];
55
56 printk("32-bit wrap-around should occur every %us\n",
57 (uint32_t)(BIT64(32) / (uint32_t)sys_clock_hw_cycles_per_sec()));
58
59 printk("[ddd:hh:mm:ss.0ms]\n");
60
61 c64[CURR] = k_cycle_get_64();
62 msg(c64[CURR]);
63
64 for (i = 0; i < 2; ++i) {
65 k_sleep(Z_TIMEOUT_CYC(timeout(c64[CURR], k_cycle_get_64())));
66
67 now = k_cycle_get_64();
68 swap64(&c64[PREV], &c64[CURR]);
69 c64[CURR] = now;
70
71 msg(c64[CURR]);
72
73 zassert_equal(((c64[CURR] - c64[PREV]) >> 32), 1,
74 "The 64-bit cycle counter did not increment by 2^32");
75 }
76 }
77
78 ZTEST_SUITE(cycle64_tests, NULL, NULL, NULL, NULL, NULL);
79