1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/sensor.h>
9 #include "board.h"
10 #include "mesh.h"
11
12 #include <zephyr/bluetooth/mesh.h>
13
14 static const struct device *const dev_info[] = {
15 DEVICE_DT_GET_ONE(ti_hdc1010),
16 DEVICE_DT_GET_ONE(nxp_mma8652fc),
17 DEVICE_DT_GET_ONE(avago_apds9960),
18 DEVICE_DT_GET(DT_CHOSEN(zephyr_display)),
19 };
20
get_hdc1010_val(struct sensor_value * val)21 int get_hdc1010_val(struct sensor_value *val)
22 {
23 if (sensor_sample_fetch(dev_info[DEV_IDX_HDC1010])) {
24 printk("Failed to fetch sample for device %s\n",
25 dev_info[DEV_IDX_HDC1010]->name);
26 return -1;
27 }
28
29 if (sensor_channel_get(dev_info[DEV_IDX_HDC1010],
30 SENSOR_CHAN_AMBIENT_TEMP, &val[0])) {
31 return -1;
32 }
33
34 if (sensor_channel_get(dev_info[DEV_IDX_HDC1010],
35 SENSOR_CHAN_HUMIDITY, &val[1])) {
36 return -1;
37 }
38
39 return 0;
40 }
41
get_mma8652_val(struct sensor_value * val)42 int get_mma8652_val(struct sensor_value *val)
43 {
44 if (sensor_sample_fetch(dev_info[DEV_IDX_MMA8652])) {
45 printk("Failed to fetch sample for device %s\n",
46 dev_info[DEV_IDX_MMA8652]->name);
47 return -1;
48 }
49
50 if (sensor_channel_get(dev_info[DEV_IDX_MMA8652],
51 SENSOR_CHAN_ACCEL_XYZ, &val[0])) {
52 return -1;
53 }
54
55 return 0;
56 }
57
get_apds9960_val(struct sensor_value * val)58 int get_apds9960_val(struct sensor_value *val)
59 {
60 if (sensor_sample_fetch(dev_info[DEV_IDX_APDS9960])) {
61 printk("Failed to fetch sample for device %s\n",
62 dev_info[DEV_IDX_APDS9960]->name);
63 return -1;
64 }
65
66 if (sensor_channel_get(dev_info[DEV_IDX_APDS9960],
67 SENSOR_CHAN_LIGHT, &val[0])) {
68 return -1;
69 }
70
71 if (sensor_channel_get(dev_info[DEV_IDX_APDS9960],
72 SENSOR_CHAN_PROX, &val[1])) {
73 return -1;
74 }
75
76 return 0;
77 }
78
79 #define MOTION_TIMEOUT K_MINUTES(30)
80
81 static struct k_work_delayable motion_work;
82
motion_timeout(struct k_work * work)83 static void motion_timeout(struct k_work *work)
84 {
85 int err;
86
87 printk("power save\n");
88
89 if (!mesh_is_initialized()) {
90 k_work_schedule(&motion_work, MOTION_TIMEOUT);
91 return;
92 }
93
94 err = bt_mesh_suspend();
95 if (err && err != -EALREADY) {
96 printk("failed to suspend mesh (err %d)\n", err);
97 }
98 }
99
motion_handler(const struct device * dev,const struct sensor_trigger * trig)100 static void motion_handler(const struct device *dev,
101 const struct sensor_trigger *trig)
102 {
103 int err;
104
105 printk("motion!\n");
106
107 if (!mesh_is_initialized()) {
108 return;
109 }
110
111 err = bt_mesh_resume();
112 if (err && err != -EALREADY) {
113 printk("failed to resume mesh (err %d)\n", err);
114 }
115
116 k_work_reschedule(&motion_work, MOTION_TIMEOUT);
117 }
118
configure_accel(void)119 static void configure_accel(void)
120 {
121 const struct device *accel = dev_info[DEV_IDX_MMA8652];
122 struct sensor_trigger trig_motion = {
123 .type = SENSOR_TRIG_DELTA,
124 .chan = SENSOR_CHAN_ACCEL_XYZ,
125 };
126 int err;
127
128 err = sensor_trigger_set(accel, &trig_motion, motion_handler);
129 if (err) {
130 printk("setting motion trigger failed, err %d\n", err);
131 return;
132 }
133
134
135 k_work_init_delayable(&motion_work, motion_timeout);
136 k_work_schedule(&motion_work, MOTION_TIMEOUT);
137 }
138
periphs_init(void)139 int periphs_init(void)
140 {
141 unsigned int i;
142
143 /* Bind sensors */
144 for (i = 0U; i < ARRAY_SIZE(dev_info); i++) {
145 if (!device_is_ready(dev_info[i])) {
146 printk("%s: device not ready.\n", dev_info[i]->name);
147 return -ENODEV;
148 }
149 }
150
151 configure_accel();
152
153 return 0;
154 }
155