-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathmain.c
More file actions
249 lines (213 loc) · 6.86 KB
/
Copy pathmain.c
File metadata and controls
249 lines (213 loc) · 6.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/*
* Copyright (c) 2022 T-Mobile USA, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor/lis2dw12.h>
#define DOUBLE_TAP_EVENT 0x10U
#define SINGLE_TAP_EVENT 0x08U
#define FREEFALL_EVENT 0x02U
#define DATAREADY_EVENT 0x01U
bool sample_init_complete = false;
uint8_t reg_value;
struct sensor_value temperature;
struct sensor_value sensor_attr_val;
struct sensor_trigger trig;
static void trigger_and_display(const struct device *sensor)
{
static unsigned int count;
struct sensor_value accel[3];
const char *overrun = "";
int rc = sensor_sample_fetch(sensor);
if (!sample_init_complete) {
return;
}
++count;
if (rc == -EBADMSG) {
/* Sample overrun. Ignore in polled mode. */
if (IS_ENABLED(CONFIG_LIS2DW12_TRIGGER)) {
overrun = "[OVERRUN] ";
}
rc = 0;
}
if (rc == 0) {
rc = sensor_channel_get(sensor, SENSOR_CHAN_ACCEL_XYZ, accel);
}
#if LIS2DW12_DEBUG
if (rc < 0) {
printf("\tERROR: Update failed: %d\n", rc);
} else {
printf("\t#%u @ %u ms: %sx %f , y %f , z %f", count, k_uptime_get_32(), overrun,
sensor_value_to_double(&accel[0]), sensor_value_to_double(&accel[1]),
sensor_value_to_double(&accel[2]));
}
#endif
rc = sensor_attr_get(sensor, trig.chan, SENSOR_ATTR_STATUS,
(struct sensor_value *)&sensor_attr_val);
if (rc < 0) {
printf("\n\tERROR: Unable to read register 0X27 :%d\n", rc);
} else {
reg_value = (uint8_t)sensor_attr_val.val1;
if ((reg_value & SINGLE_TAP_EVENT) == SINGLE_TAP_EVENT) {
printf("\n\tSINGLE TAP was detected (%xh)\n", (reg_value));
} else if ((reg_value & DOUBLE_TAP_EVENT) == DOUBLE_TAP_EVENT) {
printf("\n\tDOUBLE TAP was detected (%xh)\n", (reg_value));
} else if ((reg_value & FREEFALL_EVENT) == FREEFALL_EVENT) {
printf("\n\tFREE FALL was detected (%xh)\n", (reg_value));
} else if ((reg_value & DATAREADY_EVENT) == DATAREADY_EVENT) {
printf("\n\tDATAREADY was detected (%xh)\n", (reg_value));
} else {
printf("\n\tUNKNOWN event was detected (%xh)\n", (reg_value));
}
}
uint8_t reg_array[5] = {0};
rc = sensor_attr_get(sensor, trig.chan, SENSOR_ATTR_ALL_WAKE_UP_SRC,
(struct sensor_value *)®_array[0]);
if (rc < 0) {
printf("\n\tERROR: Unable to read register 0x38 :%d\n", rc);
} else {
if (reg_array[1]) {
if ((reg_array[1] & 0x20) == 0x20) {
printf("\tReg 38h - FREE FALL detected (%xh)\n", (reg_array[1]));
}
} else {
printf("\tReg 38h - No WAKE SRC detected (%xh)\n", (reg_array[1]));
}
}
reg_value = 0;
rc = sensor_attr_get(sensor, trig.chan, SENSOR_ATTR_TAP_SRC,
(struct sensor_value *)®_value);
if (rc < 0) {
printf("\n\tERROR: Unable to read register 0x39 :%d\n", rc);
} else {
if (reg_value) {
if ((reg_value & 0x01) == 0x01) {
printf("\tReg 39h - TAP_EVENT Negative Accel detected (%xh)\n",
(reg_value));
} else {
printf("\tReg 39h - TAP_EVENT Positive Accel detected (%xh)\n",
(reg_value));
}
if ((reg_value & 0x04) == 0x04) {
printf("\tReg 39h - TAP_EVENT X-Axis detected\n");
}
if ((reg_value & 0x02) == 0x02) {
printf("\tReg 39h - TAP_EVENT Y-Axis detected\n");
}
if ((reg_value & 0x01) == 0x01) {
printf("\tReg 39h - TAP_EVENT Z-Axis detected\n");
}
} else {
printf("\tReg 39h - No TAP_EVENT detected (%xh)\n", (reg_value));
}
}
rc = sensor_channel_get(sensor, SENSOR_CHAN_AMBIENT_TEMP, &temperature);
if (rc < 0) {
printf("\n\tERROR: Unable to read ambient temperature :%d\n", rc);
} else {
printf("\t\tAmbient Temperature: %.2f C\n", sensor_value_to_double(&temperature));
}
}
#ifdef CONFIG_LIS2DW12_TRIGGER
static void trigger_handler(const struct device *dev, const struct sensor_trigger *trig)
{
trigger_and_display(dev);
}
#endif
static void greeting()
{
printf("\n\t\t\tWelcome to T-Mobile DevEdge!\n\n"
"This sample application demonstrates the integrated DevEdge based motion sensor\n"
"(STMicroelectronics LIS2DW12 MEMS accelerometer).\n"
"The motion sensor can detect single-tap, double-tap, and free-fall events.\n"
"Motion events detected by the LIS2DW12 result in interrupts that trigger\n"
"a handler function, which collects and displays specific information about each "
"event.\n\n"
"Note:\n"
"To generate \"tap\" events, quickly move the board in the X, Y, or Z-axes.\n"
"Free-fall events can be simulated with vertical up or down acceleration movements\n"
"in which you are simulating a moment of weightlessness and then a sudden increase\n"
"in shock (g-forces). For Free-fall try to keep the z-axis pointing straight "
"up.\n\n");
}
void main(void)
{
k_sleep(K_MSEC(2000));
greeting();
k_sleep(K_MSEC(5000));
const struct device *sensor = DEVICE_DT_GET_ANY(st_lis2dw12);
if (!sensor) {
return;
}
#if CONFIG_LIS2DW12_TRIGGER
int rc;
trig.type = SENSOR_TRIG_DATA_READY;
trig.chan = SENSOR_CHAN_ACCEL_XYZ;
struct sensor_value odr = {
.val1 = 1,
};
rc = sensor_attr_set(sensor, trig.chan, SENSOR_ATTR_SAMPLING_FREQUENCY, &odr);
if (rc != 0) {
printf("\tFailed to set odr: %d\n", rc);
return;
}
trig.type = SENSOR_TRIG_DOUBLE_TAP;
trig.chan = SENSOR_CHAN_ACCEL_XYZ;
rc = sensor_trigger_set(sensor, &trig, trigger_handler);
if (rc != 0) {
printf("\tFailed to set Double Tap trigger: %d\n", rc);
return;
}
trig.type = SENSOR_TRIG_THRESHOLD;
trig.chan = SENSOR_CHAN_ACCEL_XYZ;
rc = sensor_trigger_set(sensor, &trig, trigger_handler);
if (rc != 0) {
printf("\tFailed to set Threshold trigger: %d\n", rc);
return;
}
struct sensor_value ctrl4_reg = {
.val1 = 0x58,
};
rc = sensor_attr_set(sensor, trig.chan, SENSOR_ATTR_ENABLE_EVENT_INTERRUPT, &ctrl4_reg);
if (rc != 0) {
printf("\tFailed to set odr: %d\n", rc);
return;
}
rc = sensor_attr_get(sensor, trig.chan, SENSOR_ATTR_CHIP_ID,
(struct sensor_value *)&sensor_attr_val);
if (rc != 0) {
printf("\tFailed to get status: %d\n", rc);
return;
}
if (sensor_attr_val.val1 == 0x44) {
printf("\tWHOAMI: (%xh)\n", (uint8_t)sensor_attr_val.val1);
} else {
printf("\tError : WHOAMI (%xh) doesnt match the LIS2DW12 ?\n",
(sensor_attr_val.val1));
return;
}
rc = sensor_attr_get(sensor, trig.chan, SENSOR_ATTR_STATUS,
(struct sensor_value *)&sensor_attr_val);
if (rc != 0) {
printf("\tFailed to get status: %d\n", rc);
return;
}
printf("\tSENSOR_ATTR_STATUS: (%xh)\n", sensor_attr_val.val1);
/* Let the interrupt handler know the sample is ready to run */
sample_init_complete = true;
/* We should be spinning in this loop waiting for the user to trigger us.*/
printf("\tWaiting here for a motion event trigger\n");
while (true) {
k_sleep(K_MSEC(2000));
}
#else /* CONFIG_LIS2DW12_TRIGGER */
while (true) {
trigger_and_display(sensor);
k_sleep(K_MSEC(2000));
}
#endif /* CONFIG_LIS2DW12_TRIGGER */
}