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