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