1 /*
2 * Copyright (c) 2024, Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/drivers/comparator/nrf_comp.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/kernel.h>
11
12 static const struct device *test_dev = DEVICE_DT_GET(DT_ALIAS(test_comp));
13 static const struct gpio_dt_spec test_pin_1 = GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), first_gpios);
14 static const struct gpio_dt_spec test_pin_2 = GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), second_gpios);
15
16 #define TEST_COMP_SE_PSEL_AIN _CONCAT(COMP_NRF_COMP_PSEL_AIN, \
17 CONFIG_TEST_COMP_SE_PSEL_AIN_INDEX)
18 #define TEST_COMP_SE_EXTREFSEL_AIN _CONCAT(COMP_NRF_COMP_EXTREFSEL_AIN, \
19 CONFIG_TEST_COMP_SE_EXTREFSEL_AIN_INDEX)
20 #define TEST_COMP_DIFF_PSEL_AIN _CONCAT(COMP_NRF_COMP_PSEL_AIN, \
21 CONFIG_TEST_COMP_DIFF_PSEL_AIN_INDEX)
22 #define TEST_COMP_DIFF_EXTREFSEL_AIN _CONCAT(COMP_NRF_COMP_EXTREFSEL_AIN, \
23 CONFIG_TEST_COMP_DIFF_EXTREFSEL_AIN_INDEX)
24
25 struct comp_nrf_comp_se_config comp_se_config = {
26 .psel = TEST_COMP_SE_PSEL_AIN,
27 .sp_mode = COMP_NRF_COMP_SP_MODE_HIGH,
28 .isource = COMP_NRF_COMP_ISOURCE_DISABLED,
29 .refsel = COMP_NRF_COMP_REFSEL_AREF,
30 .extrefsel = TEST_COMP_SE_EXTREFSEL_AIN,
31 .th_up = 32,
32 .th_down = 32,
33 };
34
35 struct comp_nrf_comp_diff_config comp_diff_config = {
36 .psel = TEST_COMP_DIFF_PSEL_AIN,
37 .sp_mode = COMP_NRF_COMP_SP_MODE_LOW,
38 .isource = COMP_NRF_COMP_ISOURCE_DISABLED,
39 .extrefsel = TEST_COMP_DIFF_EXTREFSEL_AIN,
40 .enable_hyst = true,
41 };
42
43 atomic_t counter;
44
test_callback(const struct device * dev,void * user_data)45 static void test_callback(const struct device *dev, void *user_data)
46 {
47 counter++;
48 }
49
50 /**
51 * @brief Configure comparator in single-ended mode with
52 * external voltage reference.
53 * Check if events were detected.
54 */
55
ZTEST(comparator_runtime_configure,test_comp_config_se_aref)56 ZTEST(comparator_runtime_configure, test_comp_config_se_aref)
57 {
58 int rc;
59
60 rc = comp_nrf_comp_configure_se(test_dev, &comp_se_config);
61 zassert_equal(rc, 0, "Cannot configure comparator.");
62
63 rc = comparator_set_trigger_callback(test_dev, test_callback, NULL);
64 zassert_equal(rc, 0, "Cannot set callback for comparator.");
65
66 rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_BOTH_EDGES);
67 zassert_equal(rc, 0, "Cannot set trigger for comparator.");
68
69 k_msleep(10);
70
71 atomic_clear(&counter);
72 gpio_pin_set_dt(&test_pin_2, 1);
73 k_msleep(10);
74 zassert_equal(atomic_get(&counter), 1, "COMP was not triggered for first threshold cross");
75 gpio_pin_set_dt(&test_pin_2, 0);
76 k_msleep(10);
77 zassert_equal(atomic_get(&counter), 2, "COMP was not triggered for second threshold cross");
78
79 }
80
81 /**
82 * @brief Configure comparator in single-ended mode with
83 * internal voltage reference.
84 * Check if events were detected.
85 */
86
87
ZTEST(comparator_runtime_configure,test_comp_config_se_vdd)88 ZTEST(comparator_runtime_configure, test_comp_config_se_vdd)
89 {
90 int rc;
91
92 struct comp_nrf_comp_se_config conf = comp_se_config;
93
94 #ifdef COMP_REFSEL_REFSEL_AVDDAO1V8
95 conf.refsel = COMP_NRF_COMP_REFSEL_AVDDAO1V8;
96 #elif defined(COMP_REFSEL_REFSEL_VDD)
97 conf.refsel = COMP_NRF_COMP_REFSEL_VDD;
98 #else
99 /* Use internal 1.2 V derived from VDD */
100 conf.refsel = COMP_NRF_COMP_REFSEL_INT_1V2;
101 #endif
102 rc = comp_nrf_comp_configure_se(test_dev, &conf);
103 zassert_equal(rc, 0, "Cannot configure comparator.");
104
105 rc = comparator_set_trigger_callback(test_dev, test_callback, NULL);
106 zassert_equal(rc, 0, "Cannot set callback for comparator.");
107
108 rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_BOTH_EDGES);
109 zassert_equal(rc, 0, "Cannot set trigger for comparator.");
110
111 k_msleep(10);
112
113 atomic_clear(&counter);
114 gpio_pin_set_dt(&test_pin_2, 1);
115 k_msleep(10);
116 zassert_equal(atomic_get(&counter), 1, "COMP was not triggered for first threshold cross");
117 gpio_pin_set_dt(&test_pin_2, 0);
118 k_msleep(10);
119 zassert_equal(atomic_get(&counter), 2, "COMP was not triggered for second threshold cross");
120
121 }
122
123 /**
124 * @brief Configure comparator in differential mode
125 * Check if events were detected.
126 */
127
ZTEST(comparator_runtime_configure,test_comp_config_diff_both)128 ZTEST(comparator_runtime_configure, test_comp_config_diff_both)
129 {
130 int rc;
131
132 gpio_pin_set_dt(&test_pin_1, 1);
133 gpio_pin_set_dt(&test_pin_2, 0);
134 comparator_trigger_is_pending(test_dev);
135
136 atomic_clear(&counter);
137 struct comp_nrf_comp_diff_config config = comp_diff_config;
138
139 config.isource = COMP_NRF_COMP_ISOURCE_2UA5;
140 rc = comp_nrf_comp_configure_diff(test_dev, &config);
141 zassert_equal(rc, 0, "Cannot configure comparator.");
142
143 rc = comparator_set_trigger_callback(test_dev, test_callback, NULL);
144 zassert_equal(rc, 0, "Cannot set callback for comparator.");
145
146 rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_BOTH_EDGES);
147 zassert_equal(rc, 0, "Cannot set trigger for comparator.");
148 k_msleep(10);
149
150 atomic_clear(&counter);
151 gpio_pin_set_dt(&test_pin_1, 0);
152 gpio_pin_set_dt(&test_pin_2, 1);
153 k_msleep(10);
154 zassert_equal(atomic_get(&counter), 1, "COMP was not triggered for first threshold cross");
155
156 gpio_pin_set_dt(&test_pin_2, 0);
157 gpio_pin_set_dt(&test_pin_1, 1);
158 k_msleep(10);
159
160 zassert_equal(atomic_get(&counter), 2, "COMP was not triggered for second threshold cross");
161 }
162
163 /**
164 * @brief Configure comparator in differential mode
165 * trigger both edges, event should be detected for falling one
166 */
167
ZTEST(comparator_runtime_configure,test_comp_config_diff_falling)168 ZTEST(comparator_runtime_configure, test_comp_config_diff_falling)
169 {
170 int rc;
171
172 gpio_pin_set_dt(&test_pin_1, 0);
173 gpio_pin_set_dt(&test_pin_2, 1);
174 comparator_trigger_is_pending(test_dev);
175
176 atomic_clear(&counter);
177 struct comp_nrf_comp_diff_config config = comp_diff_config;
178
179 config.isource = COMP_NRF_COMP_ISOURCE_5UA;
180 rc = comp_nrf_comp_configure_diff(test_dev, &config);
181
182 zassert_equal(rc, 0, "Cannot configure comparator.");
183
184 rc = comparator_set_trigger_callback(test_dev, test_callback, NULL);
185 zassert_equal(rc, 0, "Cannot set callback for comparator.");
186
187 rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_FALLING_EDGE);
188 zassert_equal(rc, 0, "Cannot set trigger for comparator.");
189
190 atomic_clear(&counter);
191 gpio_pin_set_dt(&test_pin_1, 1);
192 gpio_pin_set_dt(&test_pin_2, 0);
193 k_msleep(10);
194
195 zassert_equal(counter, 0, "COMP was triggered for rising threshold cross");
196
197 gpio_pin_set_dt(&test_pin_1, 0);
198 gpio_pin_set_dt(&test_pin_2, 1);
199 k_msleep(10);
200
201 zassert_equal(atomic_get(&counter), 1, "COMP wasn't triggered for falling threshold cross");
202 }
203
204 /**
205 * @brief Configure comparator in differential mode
206 * trigger both edges, event should be detected for rising one
207 */
208
ZTEST(comparator_runtime_configure,test_comp_config_diff_rising)209 ZTEST(comparator_runtime_configure, test_comp_config_diff_rising)
210 {
211 int rc;
212
213 gpio_pin_set_dt(&test_pin_1, 1);
214 gpio_pin_set_dt(&test_pin_2, 0);
215 comparator_trigger_is_pending(test_dev);
216
217 atomic_clear(&counter);
218 struct comp_nrf_comp_diff_config config = comp_diff_config;
219
220 config.isource = COMP_NRF_COMP_ISOURCE_10UA;
221 rc = comp_nrf_comp_configure_diff(test_dev, &config);
222 zassert_equal(rc, 0, "Cannot configure comparator.");
223
224 rc = comparator_set_trigger_callback(test_dev, test_callback, NULL);
225 zassert_equal(rc, 0, "Cannot set callback for comparator.");
226
227 rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_RISING_EDGE);
228 zassert_equal(rc, 0, "Cannot set trigger for comparator.");
229
230 atomic_clear(&counter);
231 gpio_pin_set_dt(&test_pin_1, 0);
232 gpio_pin_set_dt(&test_pin_2, 1);
233 k_msleep(10);
234
235 zassert_equal(atomic_get(&counter), 0, "COMP was triggered for falling threshold cross");
236
237 gpio_pin_set_dt(&test_pin_1, 1);
238 gpio_pin_set_dt(&test_pin_2, 0);
239 k_msleep(10);
240
241 zassert_equal(atomic_get(&counter), 1, "COMP was not triggered for rising threshold cross");
242 }
243
244 /**
245 * @brief Configure comparator in differential mode
246 * trigger both edges, event should not be detected.
247 */
248
ZTEST(comparator_runtime_configure,test_comp_config_diff_none)249 ZTEST(comparator_runtime_configure, test_comp_config_diff_none)
250 {
251 int rc;
252
253 gpio_pin_set_dt(&test_pin_1, 1);
254 gpio_pin_set_dt(&test_pin_2, 0);
255 comparator_trigger_is_pending(test_dev);
256
257 atomic_clear(&counter);
258 struct comp_nrf_comp_diff_config config = comp_diff_config;
259
260 config.isource = COMP_NRF_COMP_ISOURCE_10UA;
261 rc = comp_nrf_comp_configure_diff(test_dev, &config);
262 zassert_equal(rc, 0, "Cannot configure comparator.");
263
264 rc = comparator_set_trigger_callback(test_dev, test_callback, NULL);
265 zassert_equal(rc, 0, "Cannot set callback for comparator.");
266
267 rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_NONE);
268 zassert_equal(rc, 0, "Cannot set trigger for comparator.");
269
270 atomic_clear(&counter);
271 gpio_pin_set_dt(&test_pin_1, 0);
272 gpio_pin_set_dt(&test_pin_2, 1);
273 k_msleep(10);
274
275 zassert_equal(atomic_get(&counter), 0, "COMP was triggered for falling threshold cross");
276
277 gpio_pin_set_dt(&test_pin_1, 1);
278 gpio_pin_set_dt(&test_pin_2, 0);
279 k_msleep(10);
280
281 zassert_equal(atomic_get(&counter), 0, "COMP was not triggered for rising threshold cross");
282 }
283
suite_setup(void)284 static void *suite_setup(void)
285 {
286 TC_PRINT("Test executed on %s\n", CONFIG_BOARD_TARGET);
287 TC_PRINT("===================================================================\n");
288
289 return NULL;
290 }
291
test_before(void * f)292 static void test_before(void *f)
293 {
294 ARG_UNUSED(f);
295 gpio_pin_configure_dt(&test_pin_1, GPIO_OUTPUT_INACTIVE);
296 gpio_pin_configure_dt(&test_pin_2, GPIO_OUTPUT_INACTIVE);
297
298 }
299
300 ZTEST_SUITE(comparator_runtime_configure, NULL, suite_setup, test_before, NULL, NULL);
301