1 /*
2  * Copyright (c) 2019-2020, Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <zephyr/ztest.h>
7 #include <zephyr/drivers/clock_control.h>
8 #include <zephyr/drivers/clock_control/nrf_clock_control.h>
9 #include <hal/nrf_clock.h>
10 #include <zephyr/drivers/sensor.h>
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(test);
13 
14 #ifndef CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC
15 #error "LFCLK must use RC source"
16 #endif
17 
18 #define CALIBRATION_PROCESS_TIME_MS 35
19 
20 extern void mock_temp_nrf5_value_set(struct sensor_value *val);
21 
turn_on_clock(const struct device * dev,clock_control_subsys_t subsys)22 static void turn_on_clock(const struct device *dev,
23 			  clock_control_subsys_t subsys)
24 {
25 	int err;
26 	int res;
27 	struct onoff_client cli;
28 	struct onoff_manager *mgr = z_nrf_clock_control_get_onoff(subsys);
29 
30 	sys_notify_init_spinwait(&cli.notify);
31 	err = onoff_request(mgr, &cli);
32 	if (err < 0) {
33 		zassert_false(true, "Failed to start clock");
34 	}
35 	while (sys_notify_fetch_result(&cli.notify, &res) != 0) {
36 	}
37 }
38 
turn_off_clock(const struct device * dev,clock_control_subsys_t subsys)39 static void turn_off_clock(const struct device *dev,
40 			   clock_control_subsys_t subsys)
41 {
42 	int err;
43 	struct onoff_manager *mgr = z_nrf_clock_control_get_onoff(subsys);
44 
45 	do {
46 		err = onoff_release(mgr);
47 	} while (err >= 0);
48 
49 	while (clock_control_get_status(dev, subsys) !=
50 		CLOCK_CONTROL_STATUS_OFF) {
51 	}
52 }
53 
54 #define TEST_CALIBRATION(exp_cal, exp_skip, sleep_ms) \
55 	test_calibration(exp_cal, exp_skip, sleep_ms, __LINE__)
56 
57 /* Function tests if during given time expected number of calibrations and
58  * skips occurs.
59  */
test_calibration(uint32_t exp_cal,uint32_t exp_skip,uint32_t sleep_ms,uint32_t line)60 static void test_calibration(uint32_t exp_cal, uint32_t exp_skip,
61 				uint32_t sleep_ms, uint32_t line)
62 {
63 	int cal_cnt;
64 	int skip_cnt;
65 
66 	cal_cnt = z_nrf_clock_calibration_count();
67 	skip_cnt = z_nrf_clock_calibration_skips_count();
68 
69 	k_sleep(K_MSEC(sleep_ms));
70 
71 	cal_cnt = z_nrf_clock_calibration_count() - cal_cnt;
72 	skip_cnt = z_nrf_clock_calibration_skips_count() - skip_cnt;
73 
74 	zassert_equal(cal_cnt, exp_cal,
75 			"%d: Unexpected number of calibrations (%d, exp:%d)",
76 			line, cal_cnt, exp_cal);
77 	zassert_equal(skip_cnt, exp_skip,
78 			"%d: Unexpected number of skips (%d, exp:%d)",
79 			line, skip_cnt, exp_skip);
80 }
81 
82 /* Function pends until calibration counter is performed. When function leaves,
83  * it is just after calibration.
84  */
sync_just_after_calibration(void)85 static void sync_just_after_calibration(void)
86 {
87 	uint32_t cal_cnt = z_nrf_clock_calibration_count();
88 
89 	/* wait until calibration is performed. */
90 	while (z_nrf_clock_calibration_count() == cal_cnt) {
91 		k_sleep(K_MSEC(1));
92 	}
93 }
94 
95 /* Test checks if calibration and calibration skips are performed according
96  * to timing configuration.
97  */
ZTEST(nrf_clock_calibration,test_basic_clock_calibration)98 ZTEST(nrf_clock_calibration, test_basic_clock_calibration)
99 {
100 	int wait_ms = CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD *
101 		(CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP + 1) +
102 		CALIBRATION_PROCESS_TIME_MS;
103 	struct sensor_value value = { .val1 = 0, .val2 = 0 };
104 
105 	mock_temp_nrf5_value_set(&value);
106 	sync_just_after_calibration();
107 
108 	TEST_CALIBRATION(1, CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP,
109 			 wait_ms);
110 }
111 
112 /* Test checks if calibration happens just after clock is enabled. */
ZTEST(nrf_clock_calibration,test_calibration_after_enabling_lfclk)113 ZTEST(nrf_clock_calibration, test_calibration_after_enabling_lfclk)
114 {
115 	if (IS_ENABLED(CONFIG_SOC_NRF52832)) {
116 		/* On nrf52832 LF clock cannot be stopped because it leads
117 		 * to RTC COUNTER register reset and that is unexpected by
118 		 * system clock which is disrupted and may hang in the test.
119 		 */
120 		ztest_test_skip();
121 	}
122 
123 	const struct device *const clk_dev = DEVICE_DT_GET_ONE(nordic_nrf_clock);
124 	struct sensor_value value = { .val1 = 0, .val2 = 0 };
125 
126 	zassert_true(device_is_ready(clk_dev), "Device is not ready");
127 
128 	mock_temp_nrf5_value_set(&value);
129 
130 	turn_off_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
131 
132 	k_busy_wait(10000);
133 
134 	turn_on_clock(clk_dev, CLOCK_CONTROL_NRF_SUBSYS_LF);
135 
136 	TEST_CALIBRATION(1, 0,
137 			 CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD);
138 }
139 
140 /* Test checks if temperature change triggers calibration. */
ZTEST(nrf_clock_calibration,test_temp_change_triggers_calibration)141 ZTEST(nrf_clock_calibration, test_temp_change_triggers_calibration)
142 {
143 	struct sensor_value value = { .val1 = 0, .val2 = 0 };
144 
145 	mock_temp_nrf5_value_set(&value);
146 	sync_just_after_calibration();
147 
148 	/* change temperature by 0.25'C which should not trigger calibration */
149 	value.val2 += ((CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_TEMP_DIFF - 1) *
150 			250000);
151 	mock_temp_nrf5_value_set(&value);
152 
153 	/* expected one skip */
154 	TEST_CALIBRATION(0, CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP,
155 				CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP *
156 				CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD +
157 				CALIBRATION_PROCESS_TIME_MS);
158 
159 	TEST_CALIBRATION(1, 0,
160 			 CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD + 40);
161 
162 	value.val2 += (CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_TEMP_DIFF * 250000);
163 	mock_temp_nrf5_value_set(&value);
164 
165 	/* expect calibration due to temp change. */
166 	TEST_CALIBRATION(1, 0,
167 			 CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD + 40);
168 }
169 
170 /* Test checks if z_nrf_clock_calibration_force_start() results in immediate
171  * calibration.
172  */
ZTEST(nrf_clock_calibration,test_force_calibration)173 ZTEST(nrf_clock_calibration, test_force_calibration)
174 {
175 	sync_just_after_calibration();
176 
177 	z_nrf_clock_calibration_force_start();
178 
179 	/*expect immediate calibration */
180 	TEST_CALIBRATION(1, 0,
181 		CALIBRATION_PROCESS_TIME_MS + 5);
182 
183 	/* and back to scheduled operation. */
184 	TEST_CALIBRATION(1, CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP,
185 		CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD *
186 		(CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP + 1) +
187 		CALIBRATION_PROCESS_TIME_MS);
188 
189 }
190 ZTEST_SUITE(nrf_clock_calibration, NULL, NULL, NULL, NULL, NULL);
191