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 <zephyr/drivers/sensor/tdk_apex.h>
12 #include <stdio.h>
13
14 static struct sensor_trigger data_trigger;
15
16 /* Flag set from IMU device irq handler */
17 static volatile int irq_from_device;
18
19 /*
20 * Get a device structure from a devicetree node from alias
21 * "tdk_apex_sensor0".
22 */
get_tdk_apex_device(void)23 static const struct device *get_tdk_apex_device(void)
24 {
25 const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(tdk_apex_sensor0));
26
27 if (!device_is_ready(dev)) {
28 printk("\nError: Device \"%s\" is not ready; "
29 "check the driver initialization logs for errors.\n",
30 dev->name);
31 return NULL;
32 }
33
34 printk("Found device \"%s\", getting sensor data\n", dev->name);
35 return dev;
36 }
37
now_str(void)38 static const char *now_str(void)
39 {
40 static char buf[16]; /* ...HH:MM:SS.MMM */
41 uint32_t now = k_uptime_get_32();
42 unsigned int ms = now % MSEC_PER_SEC;
43 unsigned int s;
44 unsigned int min;
45 unsigned int h;
46
47 now /= MSEC_PER_SEC;
48 s = now % 60U;
49 now /= 60U;
50 min = now % 60U;
51 now /= 60U;
52 h = now;
53
54 snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u", h, min, s, ms);
55 return buf;
56 }
57
handle_tdk_apex_drdy(const struct device * dev,const struct sensor_trigger * trig)58 static void handle_tdk_apex_drdy(const struct device *dev, const struct sensor_trigger *trig)
59 {
60 if (trig->type == SENSOR_TRIG_MOTION) {
61 int rc = sensor_sample_fetch_chan(dev, trig->chan);
62
63 if (rc < 0) {
64 printf("sample fetch failed: %d\n", rc);
65 printf("cancelling trigger due to failure: %d\n", rc);
66 (void)sensor_trigger_set(dev, trig, NULL);
67 return;
68 } else if (rc == 0) {
69 irq_from_device = 1;
70 }
71 }
72 }
73
main(void)74 int main(void)
75 {
76 const struct device *dev = get_tdk_apex_device();
77 struct sensor_value apex_mode;
78
79 if (dev == NULL) {
80 return 0;
81 }
82
83 sensor_attr_get(dev, SENSOR_CHAN_APEX_MOTION, SENSOR_ATTR_CONFIGURATION, &apex_mode);
84 if (apex_mode.val1 == TDK_APEX_PEDOMETER) {
85 printf("Pedometer data sample.\n");
86 } else if (apex_mode.val1 == TDK_APEX_TILT) {
87 printf("Tilt data sample.\n");
88 } else if (apex_mode.val1 == TDK_APEX_WOM) {
89 printf("WOM data sample.\n");
90 } else if (apex_mode.val1 == TDK_APEX_SMD) {
91 printf("SMD data sample.\n");
92 }
93 apex_mode.val2 = 0;
94 sensor_attr_set(dev, SENSOR_CHAN_APEX_MOTION, SENSOR_ATTR_CONFIGURATION, &apex_mode);
95
96 data_trigger = (struct sensor_trigger){
97 .type = SENSOR_TRIG_MOTION,
98 .chan = SENSOR_CHAN_APEX_MOTION,
99 };
100 if (sensor_trigger_set(dev, &data_trigger, handle_tdk_apex_drdy) < 0) {
101 printf("Cannot configure data trigger!!!\n");
102 return 0;
103 }
104
105 printf("Configured for APEX data collecting.\n");
106
107 k_sleep(K_MSEC(1000));
108
109 while (1) {
110
111 if (irq_from_device) {
112 if (apex_mode.val1 == TDK_APEX_PEDOMETER) {
113 struct sensor_value apex_pedometer[3];
114
115 sensor_channel_get(dev, SENSOR_CHAN_APEX_MOTION, apex_pedometer);
116
117 printf("[%s]: STEP_DET count: %d steps cadence: %.1f steps/s "
118 "activity: %s\n",
119 now_str(), apex_pedometer[0].val1,
120 sensor_value_to_double(&apex_pedometer[2]),
121 apex_pedometer[1].val1 == 1 ? "Walk"
122 : apex_pedometer[1].val1 == 2 ? "Run"
123 : "Unknown");
124 } else if (apex_mode.val1 == TDK_APEX_TILT) {
125 struct sensor_value apex_tilt;
126
127 sensor_channel_get(dev, SENSOR_CHAN_APEX_MOTION, &apex_tilt);
128
129 printf("[%s]: %s\n", now_str(),
130 apex_tilt.val1 ? "TILT" : "Unknown trig");
131 } else if (apex_mode.val1 == TDK_APEX_WOM) {
132 struct sensor_value apex_wom[3];
133
134 sensor_channel_get(dev, SENSOR_CHAN_APEX_MOTION, apex_wom);
135
136 printf("[%s]: WOM x=%d y=%d z=%d\n", now_str(), apex_wom[0].val1,
137 apex_wom[1].val1, apex_wom[2].val1);
138 } else if (apex_mode.val1 == TDK_APEX_SMD) {
139 struct sensor_value apex_smd;
140
141 sensor_channel_get(dev, SENSOR_CHAN_APEX_MOTION, &apex_smd);
142
143 printf("[%s]: %s\n", now_str(),
144 apex_smd.val1 ? "SMD" : "Unknown trig");
145 }
146 irq_from_device = 0;
147 }
148 }
149 return 0;
150 }
151