1 /*
2  * Copyright (c) 2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/sensor.h>
9 #include <zephyr/drivers/sensor/adc_cmp_npcx.h>
10 #include <zephyr/sys/atomic.h>
11 #include <zephyr/kernel.h>
12 
13 #include <stdio.h>
14 
15 #define ADC_CMP_NODE			DT_NODELABEL(adc_cmp)
16 
17 #define ADC_CMP_UPPER_THRESHOLD_MV	1000
18 #define ADC_CMP_LOWER_THRESHOLD_MV	250
19 #define IS_RUNNING			!(atomic_test_bit(&stop, 0))
20 #define STOP()				atomic_set_bit(&stop, 0)
21 
22 enum threshold_state {
23 	THRESHOLD_UPPER,
24 	THRESHOLD_LOWER
25 } state;
26 
27 atomic_val_t stop;
28 
29 const struct sensor_trigger sensor_trig = {
30 	.type = SENSOR_TRIG_THRESHOLD,
31 	.chan = SENSOR_CHAN_VOLTAGE
32 };
33 
set_upper_threshold(const struct device * dev)34 void set_upper_threshold(const struct device *dev)
35 {
36 	struct sensor_value val;
37 	int err;
38 
39 	printf("ADC CMP: Set Upper threshold");
40 	val.val1 = ADC_CMP_UPPER_THRESHOLD_MV;
41 	err = sensor_attr_set(dev, SENSOR_CHAN_VOLTAGE,
42 		SENSOR_ATTR_UPPER_VOLTAGE_THRESH, &val);
43 	if (err) {
44 		printf("Error setting upper threshold");
45 		STOP();
46 	}
47 }
48 
set_lower_threshold(const struct device * dev)49 void set_lower_threshold(const struct device *dev)
50 {
51 	struct sensor_value val;
52 	int err;
53 
54 	printf("ADC CMP: Set Lower threshold");
55 	val.val1 = ADC_CMP_LOWER_THRESHOLD_MV;
56 	err = sensor_attr_set(dev, SENSOR_CHAN_VOLTAGE,
57 		SENSOR_ATTR_LOWER_VOLTAGE_THRESH, &val);
58 	if (err) {
59 		printf("ADC CMP: Error setting lower threshold");
60 		STOP();
61 	}
62 }
63 
enable_threshold(const struct device * dev,bool enable)64 void enable_threshold(const struct device *dev, bool enable)
65 {
66 	struct sensor_value val;
67 	int err;
68 
69 	val.val1 = enable;
70 	err = sensor_attr_set(dev, SENSOR_CHAN_VOLTAGE, SENSOR_ATTR_ALERT,
71 			&val);
72 	if (err) {
73 		printf("ADC CMP: Error %sabling threshold",
74 			enable ? "en":"dis");
75 		STOP();
76 	}
77 }
78 
threshold_trigger_handler(const struct device * dev,const struct sensor_trigger * trigger)79 void threshold_trigger_handler(const struct device *dev,
80 				     const struct sensor_trigger *trigger)
81 {
82 	enable_threshold(dev, false);
83 
84 	if (state == THRESHOLD_UPPER) {
85 		state = THRESHOLD_LOWER;
86 		printf("ADC CMP: Lower threshold detected");
87 		set_lower_threshold(dev);
88 	} else if (state == THRESHOLD_LOWER) {
89 		state = THRESHOLD_UPPER;
90 		printf("ADC CMP: Upper threshold detected");
91 		set_upper_threshold(dev);
92 	} else {
93 		printf("ADC CMP: Error, unexpected state");
94 		STOP();
95 	}
96 
97 	enable_threshold(dev, true);
98 }
99 
main(void)100 int main(void)
101 {
102 	const struct device *const adc_cmp = DEVICE_DT_GET(ADC_CMP_NODE);
103 	int err;
104 
105 	if (!device_is_ready(adc_cmp)) {
106 		printf("ADC CMP: Error, device is not ready");
107 		return 0;
108 	}
109 
110 	err = sensor_trigger_set(adc_cmp, &sensor_trig,
111 		threshold_trigger_handler);
112 	if (err) {
113 		printf("ADC CMP: Error setting handler");
114 		return 0;
115 	}
116 
117 	set_upper_threshold(adc_cmp);
118 
119 	enable_threshold(adc_cmp, true);
120 
121 	while (IS_RUNNING) {
122 		k_sleep(K_MSEC(1));
123 	}
124 
125 	printf("ADC CMP: Exiting application");
126 	return 0;
127 }
128