1 /*
2  * Copyright (c) 2020 Richard Osterloh
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 
9 #include <zephyr/sys/printk.h>
10 #include <zephyr/sys_clock.h>
11 #include <stdio.h>
12 
13 #include <zephyr/device.h>
14 #include <zephyr/drivers/sensor.h>
15 #include <zephyr/drivers/i2c.h>
16 
17 #define MAX_TEST_TIME	5000
18 #define SLEEPTIME	300
19 
print_proxy_data(const struct device * dev)20 static void print_proxy_data(const struct device *dev)
21 {
22 	struct sensor_value pdata;
23 
24 	if (sensor_channel_get(dev, SENSOR_CHAN_PROX, &pdata) < 0) {
25 		printf("Cannot read proximity data.\n");
26 		return;
27 	}
28 
29 	printf("Proximity: %d\n", (uint16_t) pdata.val1);
30 }
31 #if defined(CONFIG_VCNL4040_ENABLE_ALS)
print_als_data(const struct device * dev)32 static void print_als_data(const struct device *dev)
33 {
34 	struct sensor_value val;
35 
36 	if (sensor_channel_get(dev, SENSOR_CHAN_LIGHT, &val) < 0) {
37 		printf("ALS read error.\n");
38 		return;
39 	}
40 
41 	printf("Light (lux): %d\n", (uint16_t) val.val1);
42 }
43 #endif
test_polling_mode(const struct device * dev)44 static void test_polling_mode(const struct device *dev)
45 {
46 	int32_t remaining_test_time = MAX_TEST_TIME;
47 
48 	do {
49 		if (sensor_sample_fetch(dev) < 0) {
50 			printf("sample update error.\n");
51 		} else {
52 			print_proxy_data(dev);
53 #if defined(CONFIG_VCNL4040_ENABLE_ALS)
54 			print_als_data(dev);
55 #endif
56 		}
57 
58 		/* wait a while */
59 		k_sleep(K_MSEC(SLEEPTIME));
60 
61 		remaining_test_time -= SLEEPTIME;
62 	} while (remaining_test_time > 0);
63 }
64 
65 #if defined(CONFIG_VCNL4040_TRIGGER)
trigger_handler(const struct device * dev,const struct sensor_trigger * trig)66 static void trigger_handler(const struct device *dev,
67 			    const struct sensor_trigger *trig)
68 {
69 	switch (trig->type) {
70 	case SENSOR_TRIG_THRESHOLD:
71 		printf("Triggered.\n");
72 		if (sensor_sample_fetch(dev) < 0) {
73 			printf("sample update error.\n");
74 		} else {
75 			print_proxy_data(dev);
76 		}
77 		return;
78 
79 	default:
80 		printf("trigger handler: unknown trigger type.\n");
81 		return;
82 	}
83 }
84 #endif
85 
test_trigger_mode(const struct device * dev)86 static void test_trigger_mode(const struct device *dev)
87 {
88 #if defined(CONFIG_VCNL4040_TRIGGER)
89 	struct sensor_trigger trig;
90 	struct sensor_value attr;
91 
92 	printf("Testing proximity trigger.\n");
93 
94 	attr.val1 = 127;
95 	attr.val2 = 0;
96 
97 	if (sensor_attr_set(dev, SENSOR_CHAN_PROX,
98 			    SENSOR_ATTR_UPPER_THRESH, &attr) < 0) {
99 		printf("cannot set proximity high threshold.\n");
100 		return;
101 	}
102 
103 	attr.val1 = 122;
104 
105 	if (sensor_attr_set(dev, SENSOR_CHAN_PROX,
106 			    SENSOR_ATTR_LOWER_THRESH, &attr) < 0) {
107 		printf("cannot set proximity low threshold.\n");
108 		return;
109 	}
110 
111 	trig.type = SENSOR_TRIG_THRESHOLD;
112 	trig.chan = SENSOR_CHAN_PROX;
113 
114 	if (sensor_trigger_set(dev, &trig, trigger_handler) < 0) {
115 		printf("cannot set trigger.\n");
116 		return;
117 	}
118 
119 	k_sleep(K_MSEC(MAX_TEST_TIME));
120 
121 	if (sensor_trigger_set(dev, &trig, NULL) < 0) {
122 		printf("cannot clear trigger.\n");
123 		return;
124 	}
125 
126 	printf("Threshold trigger test finished.\n");
127 #endif
128 
129 }
130 
main(void)131 int main(void)
132 {
133 	const struct device *const vcnl = DEVICE_DT_GET_ONE(vishay_vcnl4040);
134 
135 	if (!device_is_ready(vcnl)) {
136 		printk("sensor: device not ready.\n");
137 		return 0;
138 	}
139 
140 	printf("Testing the polling mode.\n");
141 	test_polling_mode(vcnl);
142 	printf("Polling mode test finished.\n");
143 
144 	printf("Testing the trigger mode.\n");
145 	test_trigger_mode(vcnl);
146 	printf("Trigger mode test finished.\n");
147 	return 0;
148 }
149