xref: /nrf52832-nimble/packages/NimBLE-latest/apps/blemesh_light/src/light_model.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include "syscfg/syscfg.h"
21 
22 #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
23 
24 #include "mesh/mesh.h"
25 #include "bsp.h"
26 #include "pwm/pwm.h"
27 #include "light_model.h"
28 #include "ws2812.h"
29 
30 #if (!MYNEWT_VAL(USE_NEOPIXEL))
31 #if MYNEWT_VAL(PWM_0)
32 struct pwm_dev *pwm0;
33 #endif
34 #if MYNEWT_VAL(PWM_1)
35 struct pwm_dev *pwm1;
36 #endif
37 #if MYNEWT_VAL(PWM_2)
38 struct pwm_dev *pwm2;
39 #endif
40 #if MYNEWT_VAL(PWM_3)
41 struct pwm_dev *pwm3;
42 #endif
43 
44 static uint16_t top_val;
45 #endif
46 
47 #if (MYNEWT_VAL(USE_NEOPIXEL))
48 static uint32_t neopixel[WS2812_NUM_LED];
49 #endif
50 
51 static u8_t gen_onoff_state;
52 static s16_t gen_level_state;
53 
light_set_lightness(u8_t percentage)54 static void light_set_lightness(u8_t percentage)
55 {
56 #if (!MYNEWT_VAL(USE_NEOPIXEL))
57 	int rc;
58 
59 	uint16_t pwm_val = (uint16_t) (percentage * top_val / 100);
60 
61 #if MYNEWT_VAL(PWM_0)
62 	rc = pwm_set_duty_cycle(pwm0, 0, pwm_val);
63 	assert(rc == 0);
64 #endif
65 #if MYNEWT_VAL(PWM_1)
66 	rc = pwm_set_duty_cycle(pwm1, 0, pwm_val);
67 	assert(rc == 0);
68 #endif
69 #if MYNEWT_VAL(PWM_2)
70 	rc = pwm_set_duty_cycle(pwm2, 0, pwm_val);
71 	assert(rc == 0);
72 #endif
73 #if MYNEWT_VAL(PWM_3)
74 	rc = pwm_set_duty_cycle(pwm3, 0, pwm_val);
75 	assert(rc == 0);
76 #endif
77 #else
78 	int i;
79 	u32_t lightness;
80 	u8_t max_lightness = 0x1f;
81 
82 	lightness = (u8_t) (percentage * max_lightness / 100);
83 
84 	for (i = 0; i < WS2812_NUM_LED; i++) {
85 		neopixel[i] = (lightness | lightness << 8 | lightness << 16);
86 	}
87 	ws2812_write(neopixel);
88 #endif
89 }
90 
update_light_state(void)91 static void update_light_state(void)
92 {
93 	u16_t level = (u16_t)gen_level_state;
94 	int percent = 100 * level / 0xffff;
95 
96 	if (gen_onoff_state == 0) {
97 		percent = 0;
98 	}
99 	light_set_lightness((uint8_t) percent);
100 }
101 
light_model_gen_onoff_get(struct bt_mesh_model * model,u8_t * state)102 int light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state)
103 {
104 	*state = gen_onoff_state;
105 	return 0;
106 }
107 
light_model_gen_onoff_set(struct bt_mesh_model * model,u8_t state)108 int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state)
109 {
110 	gen_onoff_state = state;
111 	update_light_state();
112 	return 0;
113 }
114 
light_model_gen_level_get(struct bt_mesh_model * model,s16_t * level)115 int light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level)
116 {
117 	*level = gen_level_state;
118 	return 0;
119 }
120 
light_model_gen_level_set(struct bt_mesh_model * model,s16_t level)121 int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level)
122 {
123 	gen_level_state = level;
124 	if ((u16_t)gen_level_state > 0x0000) {
125 		gen_onoff_state = 1;
126 	}
127 	if ((u16_t)gen_level_state == 0x0000) {
128 		gen_onoff_state = 0;
129 	}
130 	update_light_state();
131 	return 0;
132 }
133 
light_model_light_lightness_get(struct bt_mesh_model * model,s16_t * lightness)134 int light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness)
135 {
136 	return light_model_gen_level_get(model, lightness);
137 }
138 
light_model_light_lightness_set(struct bt_mesh_model * model,s16_t lightness)139 int light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness)
140 {
141 	return light_model_gen_level_set(model, lightness);
142 }
143 
144 #if (!MYNEWT_VAL(USE_NEOPIXEL))
145 struct pwm_dev_cfg dev_conf = {
146 	.n_cycles = 0,
147 	.int_prio = 3,
148 };
149 
150 #if MYNEWT_VAL(PWM_0)
151 static struct pwm_chan_cfg led1_conf = {
152 	.pin = LED_1,
153 	.inverted = true,
154 };
155 #endif
156 
157 #if MYNEWT_VAL(PWM_1)
158 static struct pwm_chan_cfg led2_conf = {
159 	.pin = LED_2,
160 	.inverted = true,
161 };
162 #endif
163 
164 #if MYNEWT_VAL(PWM_2)
165 static struct pwm_chan_cfg led3_conf = {
166 	.pin = LED_3,
167 	.inverted = true,
168 };
169 #endif
170 #endif
171 
172 #if MYNEWT_VAL(PWM_3)
173 static struct pwm_chan_cfg led4_conf = {
174 	.pin = LED_4,
175 	.inverted = true,
176 };
177 #endif
178 
179 #if (!MYNEWT_VAL(USE_NEOPIXEL))
init_pwm_dev(struct pwm_dev ** pwm,char * dev_name,struct pwm_chan_cfg * chan_cfg)180 void init_pwm_dev(struct pwm_dev **pwm, char *dev_name, struct pwm_chan_cfg *chan_cfg)
181 {
182 	int rc = 0;
183 
184 	*pwm = (struct pwm_dev *) os_dev_open(dev_name, 0, NULL);
185 	assert(pwm);
186 	rc = pwm_configure_device(*pwm, &dev_conf);
187 	assert(rc == 0);
188 	rc = pwm_configure_channel(*pwm, 0, chan_cfg);
189 	assert(rc == 0);
190 	rc = pwm_enable(*pwm);
191 	assert(rc == 0);
192 }
193 
pwm_init(void)194 int pwm_init(void)
195 {
196 
197 #if MYNEWT_VAL(PWM_0)
198 	init_pwm_dev(&pwm0, "pwm0", &led1_conf);
199 #endif
200 
201 #if MYNEWT_VAL(PWM_1)
202 	init_pwm_dev(&pwm1, "pwm1", &led2_conf);
203 #endif
204 
205 #if MYNEWT_VAL(PWM_2)
206 	init_pwm_dev(&pwm2, "pwm2", &led3_conf);
207 #endif
208 
209 #if MYNEWT_VAL(PWM_3)
210 	init_pwm_dev(&pwm3, "pwm3", &led4_conf);
211 #endif
212 
213 	if (!pwm0) {
214 		return 0;
215 	}
216 
217 	top_val = (uint16_t) pwm_get_top_value(pwm0);
218 	update_light_state();
219 
220 	return 0;
221 }
222 #endif
223 #endif
224 
light_model_init(void)225 int light_model_init(void)
226 {
227 #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
228 	int rc;
229 #if (!MYNEWT_VAL(USE_NEOPIXEL))
230 	rc = pwm_init();
231 	assert(rc == 0);
232 #else
233 	rc = ws2812_init();
234 	assert(rc == 0);
235 	update_light_state();
236 #endif
237 	return rc;
238 #else
239 	return 0;
240 #endif
241 }
242 
243