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