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