1 /*
2  * Copyright (c) 2015 Intel Corporation
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	15000
18 #define SLEEPTIME	300
19 
20 #if !DT_HAS_COMPAT_STATUS_OKAY(bosch_bmg160)
21 #error "No bosch,bmg160 compatible node found in the device tree"
22 #endif
23 
print_gyro_data(const struct device * bmg160)24 static void print_gyro_data(const struct device *bmg160)
25 {
26 	struct sensor_value val[3];
27 
28 	if (sensor_channel_get(bmg160, SENSOR_CHAN_GYRO_XYZ, val) < 0) {
29 		printf("Cannot read bmg160 gyro channels.\n");
30 		return;
31 	}
32 
33 	printf("Gyro (rad/s): X=%f, Y=%f, Z=%f\n",
34 	       val[0].val1 + val[0].val2 / 1000000.0,
35 	       val[1].val1 + val[1].val2 / 1000000.0,
36 	       val[2].val1 + val[2].val2 / 1000000.0);
37 }
38 
print_temp_data(const struct device * bmg160)39 static void print_temp_data(const struct device *bmg160)
40 {
41 	struct sensor_value val;
42 
43 	if (sensor_channel_get(bmg160, SENSOR_CHAN_DIE_TEMP, &val) < 0) {
44 		printf("Temperature channel read error.\n");
45 		return;
46 	}
47 
48 	printf("Temperature (Celsius): %f\n",
49 	       val.val1 + val.val2 / 1000000.0);
50 }
51 
test_polling_mode(const struct device * bmg160)52 static void test_polling_mode(const struct device *bmg160)
53 {
54 	int32_t remaining_test_time = MAX_TEST_TIME;
55 
56 	do {
57 		if (sensor_sample_fetch(bmg160) < 0) {
58 			printf("Gyro sample update error.\n");
59 		}
60 
61 		print_gyro_data(bmg160);
62 
63 		print_temp_data(bmg160);
64 
65 		/* wait a while */
66 		k_msleep(SLEEPTIME);
67 
68 		remaining_test_time -= SLEEPTIME;
69 	} while (remaining_test_time > 0);
70 }
71 
trigger_handler(const struct device * bmg160,const struct sensor_trigger * trigger)72 static void trigger_handler(const struct device *bmg160,
73 			    const struct sensor_trigger *trigger)
74 {
75 	if (trigger->type != SENSOR_TRIG_DATA_READY &&
76 	    trigger->type != SENSOR_TRIG_DELTA) {
77 		printf("Gyro: trigger handler: unknown trigger type.\n");
78 		return;
79 	}
80 
81 	if (sensor_sample_fetch(bmg160) < 0) {
82 		printf("Gyro sample update error.\n");
83 	}
84 
85 	print_gyro_data(bmg160);
86 }
87 
test_trigger_mode(const struct device * bmg160)88 static void test_trigger_mode(const struct device *bmg160)
89 {
90 	int32_t remaining_test_time = MAX_TEST_TIME;
91 	struct sensor_trigger trig;
92 	struct sensor_value attr;
93 
94 	trig.type = SENSOR_TRIG_DELTA;
95 	trig.chan = SENSOR_CHAN_GYRO_XYZ;
96 
97 	printf("Gyro: Testing anymotion trigger.\n");
98 
99 	/* set up the trigger */
100 
101 	/* set slope threshold to 10 dps */
102 
103 	sensor_degrees_to_rad(10, &attr); /* convert to rad/s */
104 
105 	if (sensor_attr_set(bmg160, SENSOR_CHAN_GYRO_XYZ,
106 			    SENSOR_ATTR_SLOPE_TH, &attr) < 0) {
107 		printf("Gyro: cannot set slope threshold.\n");
108 		return;
109 	}
110 
111 	/* set slope duration to 4 samples */
112 	attr.val1 = 4;
113 	attr.val2 = 0;
114 
115 	if (sensor_attr_set(bmg160, SENSOR_CHAN_GYRO_XYZ,
116 			    SENSOR_ATTR_SLOPE_DUR, &attr) < 0) {
117 		printf("Gyro: cannot set slope duration.\n");
118 		return;
119 	}
120 
121 	if (sensor_trigger_set(bmg160, &trig, trigger_handler) < 0) {
122 		printf("Gyro: cannot set trigger.\n");
123 		return;
124 	}
125 
126 	printf("Gyro: rotate the device and wait for events.\n");
127 	do {
128 		k_msleep(SLEEPTIME);
129 		remaining_test_time -= SLEEPTIME;
130 	} while (remaining_test_time > 0);
131 
132 	if (sensor_trigger_set(bmg160, &trig, NULL) < 0) {
133 		printf("Gyro: cannot clear trigger.\n");
134 		return;
135 	}
136 
137 	printf("Gyro: Anymotion trigger test finished.\n");
138 
139 	printf("Gyro: Testing data ready trigger.\n");
140 
141 	attr.val1 = 100;
142 	attr.val2 = 0;
143 
144 	if (sensor_attr_set(bmg160, SENSOR_CHAN_GYRO_XYZ,
145 			    SENSOR_ATTR_SAMPLING_FREQUENCY, &attr) < 0) {
146 		printf("Gyro: cannot set sampling frequency.\n");
147 		return;
148 	}
149 
150 	trig.type = SENSOR_TRIG_DATA_READY;
151 	trig.chan = SENSOR_CHAN_GYRO_XYZ;
152 
153 	if (sensor_trigger_set(bmg160, &trig, trigger_handler) < 0) {
154 		printf("Gyro: cannot set trigger.\n");
155 		return;
156 	}
157 
158 	remaining_test_time = MAX_TEST_TIME;
159 
160 	do {
161 		k_msleep(SLEEPTIME);
162 		remaining_test_time -= SLEEPTIME;
163 	} while (remaining_test_time > 0);
164 
165 	if (sensor_trigger_set(bmg160, &trig, NULL) < 0) {
166 		printf("Gyro: cannot clear trigger.\n");
167 		return;
168 	}
169 
170 	printf("Gyro: Data ready trigger test finished.\n");
171 }
172 
main(void)173 int main(void)
174 {
175 	const struct device *const bmg160 = DEVICE_DT_GET_ANY(bosch_bmg160);
176 #if defined(CONFIG_BMG160_RANGE_RUNTIME)
177 	struct sensor_value attr;
178 #endif
179 
180 	if (!device_is_ready(bmg160)) {
181 		printf("Device %s is not ready.\n", bmg160->name);
182 		return 0;
183 	}
184 
185 #if defined(CONFIG_BMG160_RANGE_RUNTIME)
186 	/*
187 	 * Set gyro range to +/- 250 degrees/s. Since the sensor API needs SI
188 	 * units, convert the range to rad/s.
189 	 */
190 	sensor_degrees_to_rad(250, &attr);
191 
192 	if (sensor_attr_set(bmg160, SENSOR_CHAN_GYRO_XYZ,
193 			    SENSOR_ATTR_FULL_SCALE, &attr) < 0) {
194 		printf("Cannot set gyro range.\n");
195 		return 0;
196 	}
197 #endif
198 
199 	printf("Testing the polling mode.\n");
200 	test_polling_mode(bmg160);
201 	printf("Polling mode test finished.\n");
202 
203 	printf("Testing the trigger mode.\n");
204 	test_trigger_mode(bmg160);
205 	printf("Trigger mode test finished.\n");
206 	return 0;
207 }
208