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