1 /*
2  * Copyright (c) 2024 TDK Invensense
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/devicetree.h>
10 #include <zephyr/drivers/sensor.h>
11 #include <stdio.h>
12 #include <zephyr/logging/log.h>
13 
14 LOG_MODULE_REGISTER(PRESS_INT_SAMPLE, CONFIG_SENSOR_LOG_LEVEL);
15 
16 /*
17  * Get a device structure from a devicetree node from alias
18  * "pressure_sensor".
19  */
get_pressure_sensor_device(void)20 static const struct device *get_pressure_sensor_device(void)
21 {
22 	const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(pressure_sensor));
23 
24 	if (!device_is_ready(dev)) {
25 		printk("\nError: Device \"%s\" is not ready; "
26 		       "check the driver initialization logs for errors.\n",
27 		       dev->name);
28 		return NULL;
29 	}
30 
31 	printk("Found device \"%s\", getting sensor data\n", dev->name);
32 	return dev;
33 }
34 
35 #ifdef CONFIG_PRESSURE_DRDY
data_ready_handler(const struct device * dev,const struct sensor_trigger * trig)36 static void data_ready_handler(const struct device *dev, const struct sensor_trigger *trig)
37 {
38 
39 	if (trig->type == SENSOR_TRIG_DATA_READY) {
40 		int rc = sensor_sample_fetch_chan(dev, trig->chan);
41 
42 		if (rc < 0) {
43 			printf("sample fetch failed: %d\n", rc);
44 			printf("cancelling trigger\n");
45 			(void)sensor_trigger_set(dev, trig, NULL);
46 			return;
47 		} else if (rc == 0) {
48 
49 			struct sensor_value pressure;
50 			struct sensor_value temperature;
51 			struct sensor_value altitude;
52 
53 			sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure);
54 			sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temperature);
55 			sensor_channel_get(dev, SENSOR_CHAN_ALTITUDE, &altitude);
56 
57 			LOG_INF("temp %.2f Cel, pressure %f kPa, altitude %f m",
58 				sensor_value_to_double(&temperature),
59 				sensor_value_to_double(&pressure),
60 				sensor_value_to_double(&altitude));
61 		}
62 	}
63 }
64 #endif
65 
66 #ifdef CONFIG_PRESSURE_THRESHOLD
threshold_handler(const struct device * dev,const struct sensor_trigger * trig)67 static void threshold_handler(const struct device *dev, const struct sensor_trigger *trig)
68 {
69 	if (trig->type == SENSOR_TRIG_THRESHOLD) {
70 		LOG_INF("PRESSURE THRESHOLD INTERRUPT");
71 	}
72 }
73 #endif
74 
75 #ifdef CONFIG_PRESSURE_DELTA
delta_handler(const struct device * dev,const struct sensor_trigger * trig)76 static void delta_handler(const struct device *dev, const struct sensor_trigger *trig)
77 {
78 	if (trig->type == SENSOR_TRIG_DELTA) {
79 		LOG_INF("PRESSURE CHANGE INTERRUPT\n");
80 	}
81 }
82 #endif
83 
main(void)84 int main(void)
85 {
86 	static struct sensor_trigger data_ready_trigger;
87 	const struct device *dev = get_pressure_sensor_device();
88 #ifdef CONFIG_PRESSURE_THRESHOLD
89 	static struct sensor_trigger threshold_trigger;
90 	struct sensor_value pressure, pressure_threshold;
91 #endif
92 #ifdef CONFIG_PRESSURE_DELTA
93 	static struct sensor_trigger delta_trigger;
94 	struct sensor_value pressure_delta;
95 #endif
96 
97 	if (dev == NULL) {
98 		return 0;
99 	}
100 #ifdef CONFIG_PRESSURE_DRDY
101 	/* Configure data ready trigger */
102 	data_ready_trigger = (struct sensor_trigger){
103 		.type = SENSOR_TRIG_DATA_READY,
104 		.chan = SENSOR_CHAN_ALL,
105 	};
106 	if (sensor_trigger_set(dev, &data_ready_trigger, data_ready_handler) < 0) {
107 		printf("Cannot configure data trigger!!!\n");
108 		return 0;
109 	}
110 #endif
111 
112 #ifdef CONFIG_PRESSURE_THRESHOLD
113 	/* Configure pressure threshold trigger */
114 	/* Interrupt is triggered if sensor is lifted of about 50cm */
115 	/* Read current pressure */
116 	k_sleep(K_MSEC(50));
117 	sensor_sample_fetch_chan(dev, SENSOR_CHAN_PRESS);
118 	sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure);
119 
120 	/* Retrieve 5 Pa, around 50cm altitude increase */
121 	pressure_threshold.val1 = pressure.val1;
122 	pressure_threshold.val2 = pressure.val2 - 5000;
123 	sensor_attr_set(dev, SENSOR_CHAN_PRESS, SENSOR_ATTR_LOWER_THRESH, &pressure_threshold);
124 
125 	LOG_INF("Pressure at reset %.3f kPa, interrupt sets at %.3f kPa.\n",
126 		sensor_value_to_double(&pressure), sensor_value_to_double(&pressure_threshold));
127 
128 	threshold_trigger = (struct sensor_trigger){
129 		.type = SENSOR_TRIG_THRESHOLD,
130 		.chan = SENSOR_CHAN_PRESS,
131 	};
132 	if (sensor_trigger_set(dev, &threshold_trigger, threshold_handler) < 0) {
133 		printf("Cannot configure threshold trigger!!!\n");
134 		return 0;
135 	}
136 #endif
137 
138 #ifdef CONFIG_PRESSURE_DELTA
139 	/* Configure pressure delta trigger */
140 	/* Set pressure delta to 0.01 kPa to detect a press on the sensor */
141 	pressure_delta.val1 = 0;
142 	pressure_delta.val2 = 10000;
143 	sensor_attr_set(dev, SENSOR_CHAN_PRESS, SENSOR_ATTR_SLOPE_TH, &pressure_delta);
144 	delta_trigger = (struct sensor_trigger){
145 		.type = SENSOR_TRIG_DELTA,
146 		.chan = SENSOR_CHAN_PRESS,
147 	};
148 	if (sensor_trigger_set(dev, &delta_trigger, delta_handler) < 0) {
149 		printf("Cannot configure threshold trigger!!!\n");
150 		return 0;
151 	}
152 #endif
153 
154 	LOG_INF("Starting pressure event sample.\n");
155 
156 	return 0;
157 }
158