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