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/kernel.h>
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/sensor.h>
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/pm/device_runtime.h>
13 
14 static K_SEM_DEFINE(sem, 0, 1);
15 static const struct gpio_dt_spec phase_a = GPIO_DT_SPEC_GET(DT_ALIAS(qenca), gpios);
16 static const struct gpio_dt_spec phase_b = GPIO_DT_SPEC_GET(DT_ALIAS(qencb), gpios);
17 static const struct device *const qdec_dev = DEVICE_DT_GET(DT_ALIAS(qdec0));
18 static const uint32_t qdec_config_step = DT_PROP(DT_ALIAS(qdec0), steps);
19 static struct sensor_trigger qdec_trigger = {.type = SENSOR_TRIG_DATA_READY,
20 					     .chan = SENSOR_CHAN_ROTATION};
21 static bool toggle_a = true;
22 
qdec_trigger_handler(const struct device * dev,const struct sensor_trigger * trigger)23 static void qdec_trigger_handler(const struct device *dev, const struct sensor_trigger *trigger)
24 {
25 	zassert_not_null(dev);
26 	zassert_not_null(trigger);
27 	zassert_equal_ptr(dev, qdec_dev);
28 	/* trigger should be stored as a pointer in a driver
29 	 * thus this address should match
30 	 */
31 	zassert_equal_ptr(trigger, &qdec_trigger);
32 
33 	k_sem_give(&sem);
34 }
35 
qenc_emulate_work_handler(struct k_work * work)36 static void qenc_emulate_work_handler(struct k_work *work)
37 {
38 	if (toggle_a) {
39 		gpio_pin_toggle_dt(&phase_a);
40 	} else {
41 		gpio_pin_toggle_dt(&phase_b);
42 	}
43 	toggle_a = !toggle_a;
44 }
45 
46 static K_WORK_DEFINE(qenc_emulate_work, qenc_emulate_work_handler);
47 
qenc_emulate_timer_handler(struct k_timer * dummy)48 static void qenc_emulate_timer_handler(struct k_timer *dummy)
49 {
50 	k_work_submit(&qenc_emulate_work);
51 }
52 
53 static K_TIMER_DEFINE(qenc_emulate_timer, qenc_emulate_timer_handler, NULL);
54 
qenc_emulate_reset_pin(const struct gpio_dt_spec * gpio_dt)55 static void qenc_emulate_reset_pin(const struct gpio_dt_spec *gpio_dt)
56 {
57 	int rc;
58 
59 	rc = gpio_pin_set_dt(gpio_dt, 0);
60 	zassert_ok(rc, "%s: pin set failed: %d", gpio_dt->port->name, rc);
61 }
62 
qenc_emulate_setup_pin(const struct gpio_dt_spec * gpio_dt)63 static void qenc_emulate_setup_pin(const struct gpio_dt_spec *gpio_dt)
64 {
65 	int rc;
66 
67 	rc = gpio_is_ready_dt(gpio_dt);
68 	zassert_true(rc, "%s: device not ready: %d", gpio_dt->port->name, rc);
69 
70 	rc = gpio_pin_configure_dt(gpio_dt, GPIO_OUTPUT);
71 	zassert_true(rc == 0, "%s: pin configure failed: %d", gpio_dt->port->name, rc);
72 }
73 
qenc_emulate_start(k_timeout_t period,bool forward)74 static void qenc_emulate_start(k_timeout_t period, bool forward)
75 {
76 	qenc_emulate_reset_pin(&phase_a);
77 	qenc_emulate_reset_pin(&phase_b);
78 
79 	toggle_a = !forward;
80 
81 	k_timer_start(&qenc_emulate_timer, period, period);
82 }
83 
qenc_emulate_stop(void)84 static void qenc_emulate_stop(void)
85 {
86 	k_timer_stop(&qenc_emulate_timer);
87 
88 	qenc_emulate_reset_pin(&phase_a);
89 	qenc_emulate_reset_pin(&phase_b);
90 }
91 
qenc_emulate_verify_reading(int emulator_period_ms,int emulation_duration_ms,bool forward,bool overflow_expected)92 static void qenc_emulate_verify_reading(int emulator_period_ms, int emulation_duration_ms,
93 					bool forward, bool overflow_expected)
94 {
95 	int rc;
96 	struct sensor_value val = {0};
97 	int32_t expected_steps = emulation_duration_ms / emulator_period_ms;
98 	int32_t expected_reading = 360 * expected_steps / qdec_config_step;
99 	int32_t delta = expected_reading / 5;
100 
101 	if (!forward) {
102 		expected_reading *= -1;
103 	}
104 
105 	qenc_emulate_start(K_MSEC(emulator_period_ms), forward);
106 
107 	/* wait for some readings*/
108 	k_msleep(emulation_duration_ms);
109 
110 	rc = sensor_sample_fetch(qdec_dev);
111 
112 	if (!overflow_expected) {
113 		zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
114 	} else {
115 		zassert_true(rc == -EOVERFLOW, "Failed to detect overflow");
116 	}
117 
118 	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
119 	zassert_true(rc == 0, "Failed to get sample (%d)", rc);
120 
121 	if (!overflow_expected) {
122 		zassert_within(val.val1, expected_reading, delta,
123 			       "Expected reading: %d,  but got: %d", expected_reading, val.val1);
124 	}
125 
126 	qenc_emulate_stop();
127 
128 	/* wait and get readings to clear state */
129 	k_msleep(100);
130 
131 	rc = sensor_sample_fetch(qdec_dev);
132 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
133 
134 	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
135 	zassert_true(rc == 0, "Failed to get sample (%d)", rc);
136 }
137 
138 /**
139  * @brief sensor_trigger_set test disable trigger
140  *
141  * Confirm trigger happens after set and stops after being disabled
142  *
143  */
ZTEST(qdec_sensor,test_sensor_trigger_set_and_disable)144 ZTEST(qdec_sensor, test_sensor_trigger_set_and_disable)
145 {
146 	int rc;
147 
148 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
149 		pm_device_runtime_get(qdec_dev);
150 	}
151 
152 	qdec_trigger.type = SENSOR_TRIG_DATA_READY;
153 	qdec_trigger.chan = SENSOR_CHAN_ALL;
154 	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
155 	zassume_true(rc != -ENOSYS, "sensor_trigger_set not supported");
156 
157 	zassert_true(rc == 0, "sensor_trigger_set failed: %d", rc);
158 
159 	qenc_emulate_start(K_MSEC(10), true);
160 
161 	/* emulation working, handler should be called */
162 	rc = k_sem_take(&sem, K_MSEC(200));
163 	zassert_true(rc == 0, "qdec handler should be triggered (%d)", rc);
164 
165 	qenc_emulate_stop();
166 
167 	/* emulation not working, but there maybe old trigger, ignore */
168 	rc = k_sem_take(&sem, K_MSEC(200));
169 
170 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
171 		pm_device_runtime_put(qdec_dev);
172 	}
173 
174 	/* there should be no triggers now*/
175 	rc = k_sem_take(&sem, K_MSEC(200));
176 	zassert_true(rc == -EAGAIN, "qdec handler should not be triggered (%d)", rc);
177 
178 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
179 		pm_device_runtime_get(qdec_dev);
180 	}
181 
182 	/* register empty trigger - disable trigger */
183 	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, NULL);
184 	zassert_true(rc == 0, "sensor_trigger_set failed: %d", rc);
185 
186 	qenc_emulate_start(K_MSEC(10), true);
187 
188 	/* emulation working, but handler not set, thus should not be called */
189 	rc = k_sem_take(&sem, K_MSEC(200));
190 	zassert_true(rc == -EAGAIN, "qdec handler should not be triggered (%d)", rc);
191 
192 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
193 		pm_device_runtime_put(qdec_dev);
194 	}
195 }
196 
197 /**
198  * @brief sensor_trigger_set test
199  *
200  * Confirm trigger happens after set
201  *
202  */
ZTEST(qdec_sensor,test_sensor_trigger_set)203 ZTEST(qdec_sensor, test_sensor_trigger_set)
204 {
205 	int rc;
206 	struct sensor_value val = {0};
207 
208 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
209 		pm_device_runtime_get(qdec_dev);
210 	}
211 
212 	qdec_trigger.type = SENSOR_TRIG_DATA_READY;
213 	qdec_trigger.chan = SENSOR_CHAN_ROTATION;
214 	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
215 	zassume_true(rc != -ENOSYS, "sensor_trigger_set not supported");
216 
217 	zassert_true(rc == 0, "sensor_trigger_set failed: %d", rc);
218 
219 	qenc_emulate_start(K_MSEC(10), true);
220 
221 	/* emulation working now */
222 	rc = k_sem_take(&sem, K_MSEC(200));
223 	zassert_true(rc == 0, "qdec handler should be triggered (%d)", rc);
224 
225 	rc = sensor_sample_fetch(qdec_dev);
226 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
227 
228 	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
229 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
230 
231 	TC_PRINT("QDEC reading: %d\n", val.val1);
232 	zassert_true(val.val1 != 0, "No readings from QDEC");
233 
234 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
235 		pm_device_runtime_put(qdec_dev);
236 	}
237 }
238 
239 /**
240  * @brief sensor_trigger_set test negative
241  *
242  * Confirm setting trigger with invalid data does not work
243  *
244  */
ZTEST(qdec_sensor,test_sensor_trigger_set_negative)245 ZTEST(qdec_sensor, test_sensor_trigger_set_negative)
246 {
247 	int rc;
248 
249 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
250 		pm_device_runtime_get(qdec_dev);
251 	}
252 
253 	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
254 	zassume_true(rc != -ENOSYS, "sensor_trigger_set not supported");
255 
256 	qdec_trigger.type = SENSOR_TRIG_MAX;
257 	qdec_trigger.chan = SENSOR_CHAN_ROTATION;
258 
259 	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
260 	zassume_true(rc < 0, "sensor_trigger_set should fail due to invalid trigger type");
261 
262 	qdec_trigger.type = SENSOR_TRIG_DATA_READY;
263 	qdec_trigger.chan = SENSOR_CHAN_MAX;
264 
265 	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
266 	zassume_true(rc < 0, "sensor_trigger_set should fail due to invalid channel");
267 
268 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
269 		pm_device_runtime_put(qdec_dev);
270 	}
271 }
272 
273 /**
274  * @brief QDEC readings tests
275  *
276  * Valid reading from QDEC base on simulated signal
277  *
278  */
ZTEST(qdec_sensor,test_qdec_readings)279 ZTEST(qdec_sensor, test_qdec_readings)
280 {
281 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
282 		pm_device_runtime_get(qdec_dev);
283 	}
284 
285 	qenc_emulate_verify_reading(10, 100, true, false);
286 	qenc_emulate_verify_reading(2, 500, true, false);
287 	qenc_emulate_verify_reading(10, 200, false, false);
288 	qenc_emulate_verify_reading(1, 1000, false, true);
289 	qenc_emulate_verify_reading(1, 1000, true, true);
290 
291 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
292 		pm_device_runtime_put(qdec_dev);
293 	}
294 }
295 
296 /**
297  * @brief sensor_channel_get test with no emulation
298  *
299  * Confirm getting empty reading from QDEC
300  *
301  */
ZTEST(qdec_sensor,test_sensor_channel_get_empty)302 ZTEST(qdec_sensor, test_sensor_channel_get_empty)
303 {
304 	int rc;
305 	struct sensor_value val = {0};
306 
307 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
308 		pm_device_runtime_get(qdec_dev);
309 	}
310 
311 	/* wait for potential new readings */
312 	k_msleep(100);
313 
314 	rc = sensor_sample_fetch(qdec_dev);
315 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
316 
317 	/* get readings but ignore them, as they may include reading from time
318 	 * when emulation was still working (i.e. during previous test)
319 	 */
320 	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
321 	zassert_true(rc == 0, "Failed to get sample (%d)", rc);
322 
323 	/* wait for potential new readings */
324 	k_msleep(100);
325 
326 	rc = sensor_sample_fetch(qdec_dev);
327 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
328 
329 	/* emulation was not working, expect no readings */
330 	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
331 	zassert_true(rc == 0, "Failed to get sample (%d)", rc);
332 	zassert_true(val.val1 == 0, "Expected no readings but got: %d", val.val1);
333 	zassert_true(val.val2 == 0, "Expected no readings but got: %d", val.val2);
334 
335 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
336 		pm_device_runtime_put(qdec_dev);
337 	}
338 }
339 
340 /**
341  * @brief sensor_channel_get test with emulation
342  *
343  * Confirm getting readings from QDEC
344  *
345  */
ZTEST(qdec_sensor,test_sensor_channel_get)346 ZTEST(qdec_sensor, test_sensor_channel_get)
347 {
348 	int rc;
349 	struct sensor_value val_first = {0};
350 	struct sensor_value val_second = {0};
351 
352 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
353 		pm_device_runtime_get(qdec_dev);
354 	}
355 
356 	qenc_emulate_start(K_MSEC(10), true);
357 
358 	/* wait for some readings*/
359 	k_msleep(100);
360 
361 	rc = sensor_sample_fetch(qdec_dev);
362 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
363 
364 	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val_first);
365 	zassert_true(rc == 0, "Failed to get sample (%d)", rc);
366 	zassert_true(val_first.val1 != 0, "No readings from QDEC");
367 
368 	/* wait for more readings*/
369 	k_msleep(200);
370 
371 	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val_second);
372 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
373 	zassert_true(val_second.val1 != 0, "No readings from QDEC");
374 
375 	/* subsequent calls of sensor_channel_get without calling sensor_sample_fetch
376 	 * should yield the same value
377 	 */
378 	zassert_true(val_first.val1 == val_second.val1,
379 		     "Expected the same readings: %d vs %d",
380 		     val_first.val1,
381 		     val_second.val1);
382 
383 	zassert_true(val_first.val2 == val_second.val2,
384 		     "Expected the same readings: %d vs %d",
385 		     val_first.val2,
386 		     val_second.val2);
387 
388 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
389 		pm_device_runtime_put(qdec_dev);
390 	}
391 }
392 
393 /**
394  * @brief sensor_channel_get test negative
395  *
396  * Confirm getting readings from QDEC with invalid channel
397  *
398  */
ZTEST(qdec_sensor,test_sensor_channel_get_negative)399 ZTEST(qdec_sensor, test_sensor_channel_get_negative)
400 {
401 	int rc;
402 	struct sensor_value val = {0};
403 
404 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
405 		pm_device_runtime_get(qdec_dev);
406 	}
407 
408 	qenc_emulate_start(K_MSEC(10), true);
409 
410 	/* wait for some readings*/
411 	k_msleep(100);
412 
413 	rc = sensor_sample_fetch(qdec_dev);
414 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
415 
416 	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_MAX, &val);
417 	zassert_true(rc < 0, "Should failed to get sample (%d)", rc);
418 	zassert_true(val.val1 == 0, "Some readings from QDEC: %d", val.val1);
419 	zassert_true(val.val2 == 0, "Some readings from QDEC: %d", val.val2);
420 
421 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
422 		pm_device_runtime_put(qdec_dev);
423 	}
424 }
425 
426 /**
427  * @brief sensor_sample_fetch(_chan) test
428  *
429  * Confirm fetching work with QDEC specific channel - rotation
430  *
431  */
ZTEST(qdec_sensor,test_sensor_sample_fetch)432 ZTEST(qdec_sensor, test_sensor_sample_fetch)
433 {
434 	int rc;
435 
436 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
437 		pm_device_runtime_get(qdec_dev);
438 	}
439 
440 	rc = sensor_sample_fetch(qdec_dev);
441 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
442 
443 	rc = sensor_sample_fetch_chan(qdec_dev, SENSOR_CHAN_ROTATION);
444 	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
445 
446 	rc = sensor_sample_fetch_chan(qdec_dev, SENSOR_CHAN_MAX);
447 	zassert_true(rc < 0, "Should fail to fetch sample from invalid channel (%d)", rc);
448 
449 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
450 		pm_device_runtime_put(qdec_dev);
451 	}
452 }
453 
setup(void)454 static void *setup(void)
455 {
456 	int rc;
457 
458 	rc = device_is_ready(qdec_dev);
459 	zassert_true(rc, "QDEC device not ready: %d", rc);
460 
461 	qenc_emulate_setup_pin(&phase_a);
462 	qenc_emulate_setup_pin(&phase_b);
463 
464 	return NULL;
465 }
466 
before(void * fixture)467 static void before(void *fixture)
468 {
469 	ARG_UNUSED(fixture);
470 
471 	qenc_emulate_stop();
472 }
473 
after(void * fixture)474 static void after(void *fixture)
475 {
476 	ARG_UNUSED(fixture);
477 
478 	qenc_emulate_stop();
479 }
480 
481 ZTEST_SUITE(qdec_sensor, NULL, setup, before, after, NULL);
482