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