1 /* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
2  *
3  * Copyright (c) 2018 Vikrant More
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/drivers/gpio.h>
9 
10 #include "app_gpio.h"
11 #include "ble_mesh.h"
12 #include "device_composition.h"
13 #include "no_transition_work_handler.h"
14 #include "state_binding.h"
15 #include "storage.h"
16 #include "transition.h"
17 
18 static bool reset;
19 
light_default_var_init(void)20 static void light_default_var_init(void)
21 {
22 	ctl->tt = 0x00;
23 
24 	ctl->onpowerup = STATE_DEFAULT;
25 
26 	ctl->light->range_min = LIGHTNESS_MIN;
27 	ctl->light->range_max = LIGHTNESS_MAX;
28 	ctl->light->last = LIGHTNESS_MAX;
29 	ctl->light->def = LIGHTNESS_MAX;
30 	ctl->light->target = ctl->light->def;
31 
32 	ctl->temp->range_min = TEMP_MIN;
33 	ctl->temp->range_max = TEMP_MAX;
34 	ctl->temp->def = TEMP_MAX;
35 	ctl->temp->target = ctl->temp->def;
36 
37 	ctl->duv->def = DELTA_UV_DEF;
38 	ctl->duv->target = ctl->duv->def;
39 }
40 
41 /* This function should only get call after execution of settings_load() */
light_default_status_init(void)42 static void light_default_status_init(void)
43 {
44 	/* Retrieve Range of Lightness */
45 	if (ctl->light->range) {
46 		ctl->light->range_max = (uint16_t) (ctl->light->range >> 16);
47 		ctl->light->range_min = (uint16_t) ctl->light->range;
48 	}
49 
50 	/* Retrieve Range of Temperature */
51 	if (ctl->temp->range) {
52 		ctl->temp->range_max = (uint16_t) (ctl->temp->range >> 16);
53 		ctl->temp->range_min = (uint16_t) ctl->temp->range;
54 	}
55 
56 	ctl->light->last = constrain_lightness(ctl->light->last);
57 	ctl->light->def = constrain_lightness(ctl->light->def);
58 	ctl->light->target = constrain_lightness(ctl->light->target);
59 
60 	ctl->temp->def = constrain_temperature(ctl->temp->def);
61 	ctl->temp->target = constrain_temperature(ctl->temp->target);
62 
63 	ctl->temp->current = ctl->temp->def;
64 	ctl->duv->current = ctl->duv->def;
65 
66 	switch (ctl->onpowerup) {
67 	case STATE_OFF:
68 		ctl->light->current = 0U;
69 		break;
70 	case STATE_DEFAULT:
71 		if (ctl->light->def == 0U) {
72 			ctl->light->current = ctl->light->last;
73 		} else {
74 			ctl->light->current = ctl->light->def;
75 		}
76 		break;
77 	case STATE_RESTORE:
78 		ctl->light->current = ctl->light->target;
79 		ctl->temp->current = ctl->temp->target;
80 		ctl->duv->current = ctl->duv->target;
81 		break;
82 	}
83 
84 	ctl->light->target = ctl->light->current;
85 	ctl->temp->target = ctl->temp->current;
86 	ctl->duv->target = ctl->duv->current;
87 }
88 
update_vnd_led_gpio(void)89 void update_vnd_led_gpio(void)
90 {
91 #ifndef ONE_LED_ONE_BUTTON_BOARD
92 	gpio_pin_set_dt(&led_device[1], vnd_user_data.current == STATE_ON);
93 #endif
94 }
95 
update_led_gpio(void)96 void update_led_gpio(void)
97 {
98 	uint8_t power, color;
99 
100 	power = 100 * ((float) ctl->light->current / 65535);
101 	color = 100 * ((float) (ctl->temp->current - ctl->temp->range_min) /
102 		       (ctl->temp->range_max - ctl->temp->range_min));
103 
104 	printk("power-> %d, color-> %d\n", power, color);
105 
106 	gpio_pin_set_dt(&led_device[0], ctl->light->current);
107 #ifndef ONE_LED_ONE_BUTTON_BOARD
108 	gpio_pin_set_dt(&led_device[2], power < 50);
109 	gpio_pin_set_dt(&led_device[3], color < 50);
110 #endif
111 }
112 
update_light_state(void)113 void update_light_state(void)
114 {
115 	update_led_gpio();
116 
117 	if (ctl->transition->counter == 0 || reset == false) {
118 		reset = true;
119 		k_work_submit(&no_transition_work);
120 	}
121 }
122 
short_time_multireset_bt_mesh_unprovisioning(void)123 static void short_time_multireset_bt_mesh_unprovisioning(void)
124 {
125 	if (reset_counter >= 4U) {
126 		reset_counter = 0U;
127 		printk("BT Mesh reset\n");
128 		bt_mesh_reset();
129 	} else {
130 		printk("Reset Counter -> %d\n", reset_counter);
131 		reset_counter++;
132 	}
133 
134 	save_on_flash(RESET_COUNTER);
135 }
136 
reset_counter_timer_handler(struct k_timer * dummy)137 static void reset_counter_timer_handler(struct k_timer *dummy)
138 {
139 	reset_counter = 0U;
140 	save_on_flash(RESET_COUNTER);
141 	printk("Reset Counter set to Zero\n");
142 }
143 
144 K_TIMER_DEFINE(reset_counter_timer, reset_counter_timer_handler, NULL);
145 
main(void)146 int main(void)
147 {
148 	int err;
149 
150 	light_default_var_init();
151 
152 	app_gpio_init();
153 
154 	printk("Initializing...\n");
155 
156 	ps_settings_init();
157 
158 	/* Initialize the Bluetooth Subsystem */
159 	err = bt_enable(NULL);
160 	if (err) {
161 		printk("Bluetooth init failed (err %d)\n", err);
162 		return 0;
163 	}
164 
165 	bt_ready();
166 
167 	light_default_status_init();
168 
169 	update_light_state();
170 
171 	short_time_multireset_bt_mesh_unprovisioning();
172 	k_timer_start(&reset_counter_timer, K_MSEC(7000), K_NO_WAIT);
173 	return 0;
174 }
175