1 /*
2  * Copyright (c) 2025 Paul Timke <ptimkec@live.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/sensor.h>
9 #include <zephyr/drivers/sensor/paj7620.h>
10 
11 #define GESTURE_POLL_TIME_MS 100
12 
13 #ifdef CONFIG_PAJ7620_TRIGGER
14 K_SEM_DEFINE(sem, 0, 1); /* starts off "not available" */
15 
trigger_handler(const struct device * dev,const struct sensor_trigger * trigger)16 static void trigger_handler(const struct device *dev, const struct sensor_trigger *trigger)
17 {
18 	ARG_UNUSED(trigger);
19 
20 	if (sensor_sample_fetch(dev) < 0) {
21 		printf("sensor_sample_fetch failed\n");
22 		return;
23 	}
24 
25 	k_sem_give(&sem);
26 }
27 #endif
28 
print_hand_gesture(uint16_t gest_flags)29 static void print_hand_gesture(uint16_t gest_flags)
30 {
31 	if ((gest_flags & PAJ7620_FLAG_GES_UP) != 0) {
32 		printf("Gesture UP\n");
33 	}
34 	if ((gest_flags & PAJ7620_FLAG_GES_DOWN) != 0) {
35 		printf("Gesture DOWN\n");
36 	}
37 	if ((gest_flags & PAJ7620_FLAG_GES_LEFT) != 0) {
38 		printf("Gesture LEFT\n");
39 	}
40 	if ((gest_flags & PAJ7620_FLAG_GES_RIGHT) != 0) {
41 		printf("Gesture RIGHT\n");
42 	}
43 	if ((gest_flags & PAJ7620_FLAG_GES_FORWARD) != 0) {
44 		printf("Gesture FORWARD\n");
45 	}
46 	if ((gest_flags & PAJ7620_FLAG_GES_BACKWARD) != 0) {
47 		printf("Gesture BACKWARD\n");
48 	}
49 	if ((gest_flags & PAJ7620_FLAG_GES_CLOCKWISE) != 0) {
50 		printf("Gesture CLOCKWISE\n");
51 	}
52 	if ((gest_flags & PAJ7620_FLAG_GES_COUNTERCLOCKWISE) != 0) {
53 		printf("Gesture COUNTER CLOCKWISE\n");
54 	}
55 }
56 
57 #ifdef CONFIG_PAJ7620_TRIGGER_OWN_THREAD
trigger_main_loop(const struct device * dev)58 static void trigger_main_loop(const struct device *dev)
59 {
60 	struct sensor_value data;
61 
62 	while (1) {
63 		k_sem_take(&sem, K_FOREVER);
64 
65 		(void)sensor_channel_get(dev, (enum sensor_channel)SENSOR_CHAN_PAJ7620_GESTURES,
66 					 &data);
67 
68 		print_hand_gesture(data.val1);
69 	}
70 }
71 #endif
72 
73 #ifdef CONFIG_PAJ7620_TRIGGER_NONE
polling_main_loop(const struct device * dev)74 static void polling_main_loop(const struct device *dev)
75 {
76 	struct sensor_value data;
77 
78 	while (1) {
79 		(void)sensor_sample_fetch(dev);
80 		(void)sensor_channel_get(dev, (enum sensor_channel)SENSOR_CHAN_PAJ7620_GESTURES,
81 					 &data);
82 
83 		print_hand_gesture(data.val1);
84 		k_msleep(GESTURE_POLL_TIME_MS);
85 	}
86 }
87 #endif
88 
main(void)89 int main(void)
90 {
91 	const struct device *dev = DEVICE_DT_GET_ONE(pixart_paj7620);
92 
93 	if (!device_is_ready(dev)) {
94 		printf("Device %s is not ready\n", dev->name);
95 		return -ENODEV;
96 	}
97 
98 #ifdef CONFIG_PAJ7620_TRIGGER
99 	struct sensor_trigger trig = {
100 		.type = SENSOR_TRIG_MOTION,
101 		.chan = (enum sensor_channel)SENSOR_CHAN_PAJ7620_GESTURES,
102 	};
103 	int ret;
104 
105 	printf("PAJ7620 gesture sensor sample - trigger mode\n");
106 
107 	ret = sensor_trigger_set(dev, &trig, trigger_handler);
108 	if (ret < 0) {
109 		printf("Could not set trigger\n");
110 		return ret;
111 	}
112 
113 	trigger_main_loop(dev);
114 #else
115 	printf("PAJ7620 gesture sensor sample - polling mode\n");
116 	polling_main_loop(dev);
117 #endif
118 }
119