1 /*
2 * Copyright (c) 2020 Vestas Wind Systems A/S
3 * Copyright NXP 2024
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/sensor.h>
10 #include <zephyr/drivers/sensor/mcux_lpcmp.h>
11 #include <zephyr/kernel.h>
12 #include <stdio.h>
13
14 struct lpcmp_attr {
15 int16_t attr;
16 int32_t val;
17 };
18
19 static const struct lpcmp_attr attrs[] = {
20 {.attr = SENSOR_ATTR_MCUX_LPCMP_POSITIVE_MUX_INPUT, .val = 0},
21 {.attr = SENSOR_ATTR_MCUX_LPCMP_NEGATIVE_MUX_INPUT, .val = 7},
22
23 {.attr = SENSOR_ATTR_MCUX_LPCMP_DAC_ENABLE, .val = 1},
24 {.attr = SENSOR_ATTR_MCUX_LPCMP_DAC_HIGH_POWER_MODE_ENABLE, .val = 0},
25 {.attr = SENSOR_ATTR_MCUX_LPCMP_DAC_REFERENCE_VOLTAGE_SOURCE, .val = 0},
26 {.attr = SENSOR_ATTR_MCUX_LPCMP_DAC_OUTPUT_VOLTAGE, .val = (0xFF >> 1)},
27
28 {.attr = SENSOR_ATTR_MCUX_LPCMP_SAMPLE_ENABLE, .val = 0},
29 {.attr = SENSOR_ATTR_MCUX_LPCMP_FILTER_COUNT, .val = 7},
30 {.attr = SENSOR_ATTR_MCUX_LPCMP_FILTER_PERIOD, .val = (0xFF >> 1)},
31
32 {.attr = SENSOR_ATTR_MCUX_LPCMP_COUTA_WINDOW_ENABLE, .val = 0},
33 {.attr = SENSOR_ATTR_MCUX_LPCMP_COUTA_WINDOW_SIGNAL_INVERT_ENABLE, .val = 0},
34 {.attr = SENSOR_ATTR_MCUX_LPCMP_COUTA_SIGNAL, .val = 0},
35 {.attr = SENSOR_ATTR_MCUX_LPCMP_COUT_EVENT_TO_CLOSE_WINDOW, .val = 0},
36 };
37
38 #ifdef CONFIG_MCUX_LPCMP_TRIGGER
39 static const int16_t triggers[] = {
40 SENSOR_TRIG_MCUX_LPCMP_OUTPUT_RISING,
41 SENSOR_TRIG_MCUX_LPCMP_OUTPUT_FALLING,
42 };
43 #endif /* CONFIG_MCUX_LPCMP_TRIGGER */
44
lpcmp_input_handler(bool above_threshold)45 static void lpcmp_input_handler(bool above_threshold)
46 {
47 if (above_threshold) {
48 printf("LPCMP input above threshold\n");
49 } else {
50 printf("LPCMP input below threshold\n");
51 }
52 }
53
54 #ifdef CONFIG_MCUX_LPCMP_TRIGGER
lpcmp_trigger_handler(const struct device * dev,const struct sensor_trigger * trigger)55 static void lpcmp_trigger_handler(const struct device *dev, const struct sensor_trigger *trigger)
56 {
57 ARG_UNUSED(dev);
58
59 lpcmp_input_handler((int16_t)trigger->type == SENSOR_TRIG_MCUX_LPCMP_OUTPUT_RISING);
60 }
61 #endif /* CONFIG_MCUX_LPCMP_TRIGGER */
62
main(void)63 int main(void)
64 {
65 #ifdef CONFIG_MCUX_LPCMP_TRIGGER
66 struct sensor_trigger trigger[ARRAY_SIZE(triggers)] = {
67 [0] = {
68 .chan = SENSOR_CHAN_MCUX_LPCMP_OUTPUT,
69 .type = triggers[0],
70 },
71 [1] = {
72 .chan = SENSOR_CHAN_MCUX_LPCMP_OUTPUT,
73 .type = triggers[1],
74 }
75 };
76 #endif /* CONFIG_MCUX_LPCMP_TRIGGER */
77 const struct device *const lpcmp = DEVICE_DT_GET(DT_NODELABEL(lpcmp0));
78 struct sensor_value val;
79 int err;
80
81 if (!device_is_ready(lpcmp)) {
82 printf("LPCMP device not ready\n");
83 return 0;
84 }
85
86 /* Set LPCMP attributes */
87 val.val2 = 0;
88 for (uint8_t i = 0; i < ARRAY_SIZE(attrs); i++) {
89 val.val1 = attrs[i].val;
90 err = sensor_attr_set(lpcmp, SENSOR_CHAN_MCUX_LPCMP_OUTPUT, attrs[i].attr, &val);
91 if (err) {
92 printf("failed to set attribute %d (err %d)\n", i, err);
93 return 0;
94 }
95 }
96
97 /* Delay for analog components (DAC, CMP, ...) to settle */
98 k_sleep(K_MSEC(1));
99
100 #ifdef CONFIG_MCUX_LPCMP_TRIGGER
101 /* Set LPCMP triggers */
102 for (uint8_t i = 0; i < ARRAY_SIZE(triggers); i++) {
103 err = sensor_trigger_set(lpcmp, &trigger[i], lpcmp_trigger_handler);
104 if (err) {
105 printf("failed to set trigger %d (err %d)\n", i, err);
106 return 0;
107 }
108 }
109
110 /* Await trigger */
111 while (true) {
112 k_sleep(K_MSEC(1));
113 }
114 #else /* !CONFIG_MCUX_LPCMP_TRIGGER */
115 err = sensor_sample_fetch(lpcmp);
116 if (err) {
117 printf("failed to fetch sample (err %d)\n", err);
118 return 0;
119 }
120
121 err = sensor_channel_get(lpcmp, SENSOR_CHAN_MCUX_LPCMP_OUTPUT, &val);
122 if (err) {
123 printf("failed to get channel (err %d)\n", err);
124 return 0;
125 }
126
127 lpcmp_input_handler(val.val1 == 1);
128 #endif /* CONFIG_MCUX_LPCMP_TRIGGER */
129
130 return 0;
131 }
132