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 	#if !defined(CLOCK_LFCLKSRC_SRC_Synth) && \
42 	    !defined(CLOCK_LFCLKSRC_SRC_LFSYNT)
43 	#define NRF_CLOCK_LFCLK_SYNTH 0
44 	#endif
45 
46 	if (!IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
47 		zassert_true(on, "Clock should be on");
48 		zassert_equal(type, NRF_CLOCK_LFCLK_SYNTH);
49 	}
50 }
51 
ZTEST(nrf_lf_clock_start,test_clock_check)52 ZTEST(nrf_lf_clock_start, test_clock_check)
53 {
54 	bool xtal;
55 
56 	xtal = IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL) |
57 		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING) |
58 		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING);
59 
60 	if (xtal) {
61 		xtal_check(clk_on, clk_type);
62 	} else if (IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC)) {
63 		rc_check(clk_on, clk_type);
64 	} else {
65 		synth_check(clk_on, clk_type);
66 	}
67 }
68 
ZTEST(nrf_lf_clock_start,test_wait_in_thread)69 ZTEST(nrf_lf_clock_start, test_wait_in_thread)
70 {
71 	nrf_clock_lfclk_t t;
72 	bool o;
73 
74 	if (!(IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) &&
75 		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL))) {
76 		return;
77 	}
78 
79 	z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_AVAILABLE);
80 	o = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &t);
81 	zassert_false((t == NRF_CLOCK_LFCLK_XTAL) && o);
82 	k_busy_wait(35);
83 	zassert_true(k_cycle_get_32() > 0);
84 
85 	z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_STABLE);
86 	o = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &t);
87 	zassert_true((t == NRF_CLOCK_LFCLK_XTAL) && o);
88 }
89 
test_init(void)90 void *test_init(void)
91 {
92 	TC_PRINT("CLOCK_CONTROL_NRF_K32SRC=%s\n",
93 		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC)    ? "RC" :
94 		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH) ? "SYNTH" :
95 		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL)  ? "XTAL"
96 								  : "???");
97 	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
98 		TC_PRINT("SYSTEM_CLOCK_NO_WAIT=y\n");
99 	}
100 	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY)) {
101 		TC_PRINT("SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY=y\n");
102 	}
103 	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_STABILITY)) {
104 		TC_PRINT("SYSTEM_CLOCK_WAIT_FOR_STABILITY=y\n");
105 	}
106 	return NULL;
107 }
108 ZTEST_SUITE(nrf_lf_clock_start, NULL, test_init, NULL, NULL, NULL);
109 
110 /* This test needs to read the LF clock state soon after the system clock is
111  * started (to check if the starting routine waits for the LF clock or not),
112  * so do it at the beginning of the POST_KERNEL stage (the system clock is
113  * started in PRE_KERNEL_2). Reading of the clock state in the ZTEST setup
114  * function turns out to be too late.
115  */
get_lfclk_state(void)116 static int get_lfclk_state(void)
117 {
118 
119 	/* Do clock state read as early as possible. When RC is already running
120 	 * and XTAL has been started then LFSRCSTAT register content might be
121 	 * not valid, in that case read system clock to check if it has
122 	 * progressed.
123 	 */
124 	clk_on = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &clk_type);
125 	k_busy_wait(100);
126 	rtc_cnt = k_cycle_get_32();
127 
128 	return 0;
129 }
130 SYS_INIT(get_lfclk_state, POST_KERNEL, 0);
131