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