1 /*
2 * Copyright (c) 2020, Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/ztest.h>
7 #include <hal/nrf_clock.h>
8 #include <zephyr/drivers/clock_control/nrf_clock_control.h>
9
10 static nrf_clock_lfclk_t clk_type;
11 static bool clk_on;
12 static uint32_t rtc_cnt;
13
xtal_check(bool on,nrf_clock_lfclk_t type)14 static void xtal_check(bool on, nrf_clock_lfclk_t type)
15 {
16 if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
17 zassert_false(on, "Clock should be off");
18 } else if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY)) {
19 bool is_running =
20 rtc_cnt || (on && (type == NRF_CLOCK_LFCLK_RC));
21
22 zassert_true(is_running, "Clock should be on");
23 } else {
24 zassert_true(on, "Clock should be on");
25 zassert_equal(type, NRF_CLOCK_LFCLK_XTAL);
26 }
27 }
28
rc_check(bool on,nrf_clock_lfclk_t type)29 static void rc_check(bool on, nrf_clock_lfclk_t type)
30 {
31 if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
32 zassert_false(on, "Clock should be off");
33 } else {
34 zassert_true(on, "Clock should be on");
35 zassert_equal(type, NRF_CLOCK_LFCLK_RC);
36 }
37 }
38
synth_check(bool on,nrf_clock_lfclk_t type)39 static void synth_check(bool on, nrf_clock_lfclk_t type)
40 {
41 #ifdef CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH
42 if (!IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
43 zassert_true(on, "Clock should be on");
44 zassert_equal(type, NRF_CLOCK_LFCLK_SYNTH);
45 }
46 #endif
47 }
48
ZTEST(nrf_lf_clock_start,test_clock_check)49 ZTEST(nrf_lf_clock_start, test_clock_check)
50 {
51 bool xtal;
52
53 xtal = IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL) |
54 IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING) |
55 IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING);
56
57 if (xtal) {
58 xtal_check(clk_on, clk_type);
59 } else if (IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC)) {
60 rc_check(clk_on, clk_type);
61 } else {
62 synth_check(clk_on, clk_type);
63 }
64 }
65
ZTEST(nrf_lf_clock_start,test_wait_in_thread)66 ZTEST(nrf_lf_clock_start, test_wait_in_thread)
67 {
68 nrf_clock_lfclk_t t;
69 bool o;
70
71 if (!(IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) &&
72 IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL))) {
73 return;
74 }
75
76 z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_AVAILABLE);
77 o = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &t);
78 zassert_false((t == NRF_CLOCK_LFCLK_XTAL) && o);
79 k_busy_wait(35);
80 zassert_true(k_cycle_get_32() > 0);
81
82 z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_STABLE);
83 o = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &t);
84 zassert_true((t == NRF_CLOCK_LFCLK_XTAL) && o);
85 }
86
test_init(void)87 void *test_init(void)
88 {
89 TC_PRINT("CLOCK_CONTROL_NRF_K32SRC=%s\n",
90 IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC) ? "RC" :
91 IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH) ? "SYNTH" :
92 IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL) ? "XTAL"
93 : "???");
94 if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
95 TC_PRINT("SYSTEM_CLOCK_NO_WAIT=y\n");
96 }
97 if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY)) {
98 TC_PRINT("SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY=y\n");
99 }
100 if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_STABILITY)) {
101 TC_PRINT("SYSTEM_CLOCK_WAIT_FOR_STABILITY=y\n");
102 }
103 return NULL;
104 }
105 ZTEST_SUITE(nrf_lf_clock_start, NULL, test_init, NULL, NULL, NULL);
106
107 /* This test needs to read the LF clock state soon after the system clock is
108 * started (to check if the starting routine waits for the LF clock or not),
109 * so do it at the beginning of the POST_KERNEL stage (the system clock is
110 * started in PRE_KERNEL_2). Reading of the clock state in the ZTEST setup
111 * function turns out to be too late.
112 */
get_lfclk_state(void)113 static int get_lfclk_state(void)
114 {
115
116 /* Do clock state read as early as possible. When RC is already running
117 * and XTAL has been started then LFSRCSTAT register content might be
118 * not valid, in that case read system clock to check if it has
119 * progressed.
120 */
121 clk_on = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &clk_type);
122 k_busy_wait(100);
123 rtc_cnt = k_cycle_get_32();
124
125 return 0;
126 }
127 SYS_INIT(get_lfclk_state, POST_KERNEL, 0);
128