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