mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-03 08:37:52 +00:00
apps/blemesh_models_example_2: Sync with Zephyr
This patch combines all the changes made to this application in Zephyr. It features a lot of improvements and updates. With these changes some of the PTS Mesh Model testcases pass.
This commit is contained in:
@@ -10,6 +10,8 @@ which Root element has following models
|
||||
- Generic OnOff Client
|
||||
- Generic Level Server
|
||||
- Generic Level Client
|
||||
- Generic Default Transition Time Server
|
||||
- Generic Default Transition Time Client
|
||||
- Generic Power OnOff Server
|
||||
- Generic Power OnOff Setup Server
|
||||
- Generic Power OnOff Client
|
||||
@@ -23,8 +25,6 @@ which Root element has following models
|
||||
|
||||
And Secondary element has following models
|
||||
|
||||
- Generic OnOff Server
|
||||
- Generic OnOff Client
|
||||
- Generic Level Server
|
||||
- Generic Level Client
|
||||
- Light CTL Temperature Server
|
||||
|
||||
@@ -27,6 +27,8 @@ pkg.deps:
|
||||
- "@apache-mynewt-core/sys/console/full"
|
||||
- "@apache-mynewt-core/sys/log/full"
|
||||
- "@apache-mynewt-core/sys/stats/full"
|
||||
- "@apache-mynewt-core/encoding/base64"
|
||||
- "@apache-mynewt-core/sys/config"
|
||||
- nimble/controller
|
||||
- nimble/host
|
||||
- nimble/host/services/gap
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "bsp/bsp.h"
|
||||
#include "console/console.h"
|
||||
#include "hal/hal_gpio.h"
|
||||
#include "mesh/mesh.h"
|
||||
|
||||
#include "app_gpio.h"
|
||||
#include "publisher.h"
|
||||
|
||||
int button_device[] = {
|
||||
BUTTON_1,
|
||||
BUTTON_2,
|
||||
BUTTON_3,
|
||||
BUTTON_4,
|
||||
};
|
||||
|
||||
int led_device[] = {
|
||||
LED_1,
|
||||
LED_2,
|
||||
LED_3,
|
||||
LED_4,
|
||||
};
|
||||
|
||||
static struct ble_npl_callout button_work;
|
||||
|
||||
static void button_pressed(struct os_event *ev)
|
||||
{
|
||||
k_work_submit(&button_work);
|
||||
}
|
||||
|
||||
static struct os_event button_event;
|
||||
|
||||
static void gpio_irq_handler(void *arg)
|
||||
{
|
||||
button_event.ev_arg = arg;
|
||||
os_eventq_put(os_eventq_dflt_get(), &button_event);
|
||||
}
|
||||
|
||||
void app_gpio_init(void)
|
||||
{
|
||||
/* LEDs configiuratin & setting */
|
||||
|
||||
hal_gpio_init_out(led_device[0], 1);
|
||||
hal_gpio_init_out(led_device[1], 1);
|
||||
hal_gpio_init_out(led_device[2], 1);
|
||||
hal_gpio_init_out(led_device[3], 1);
|
||||
|
||||
/* Buttons configiuratin & setting */
|
||||
|
||||
k_work_init(&button_work, publish);
|
||||
|
||||
button_event.ev_cb = button_pressed;
|
||||
|
||||
hal_gpio_irq_init(button_device[0], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[0]);
|
||||
|
||||
hal_gpio_irq_init(button_device[1], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[1]);
|
||||
|
||||
hal_gpio_irq_init(button_device[2], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[2]);
|
||||
|
||||
hal_gpio_irq_init(button_device[3], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[3]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _APP_GPIO_H
|
||||
#define _APP_GPIO_H
|
||||
|
||||
/* GPIO */
|
||||
extern int button_device[];
|
||||
extern int led_device[];
|
||||
|
||||
void app_gpio_init(void);
|
||||
|
||||
#endif
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "console/console.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
|
||||
@@ -30,6 +31,7 @@ static int output_string(const char *str)
|
||||
|
||||
static void prov_complete(u16_t net_idx, u16_t addr)
|
||||
{
|
||||
printk("Local node provisioned, primary address 0x%04x\n", addr);
|
||||
}
|
||||
|
||||
static void prov_reset(void)
|
||||
@@ -90,4 +92,6 @@ void blemesh_on_sync(void)
|
||||
bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
|
||||
|
||||
console_printf("Mesh initialized\n");
|
||||
|
||||
bt_initialized();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,26 @@
|
||||
#define BT_MESH_MODEL_OP_GEN_MOVE_SET BT_MESH_MODEL_OP_2(0x82, 0x0B)
|
||||
#define BT_MESH_MODEL_OP_GEN_MOVE_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x0C)
|
||||
|
||||
#define BT_MESH_MODEL_GEN_DEF_TRANS_TIME_STATUS BT_MESH_MODEL_OP_2(0x82, 0x10)
|
||||
|
||||
#define BT_MESH_MODEL_GEN_ONPOWERUP_STATUS BT_MESH_MODEL_OP_2(0x82, 0x12)
|
||||
|
||||
#define BT_MESH_MODEL_LIGHT_LIGHTNESS_STATUS BT_MESH_MODEL_OP_2(0x82, 0x4E)
|
||||
#define BT_MESH_MODEL_LIGHT_LIGHTNESS_LINEAR_STATUS \
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x52)
|
||||
#define BT_MESH_MODEL_LIGHT_LIGHTNESS_LAST_STATUS \
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x54)
|
||||
#define BT_MESH_MODEL_LIGHT_LIGHTNESS_DEFAULT_STATUS \
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x56)
|
||||
#define BT_MESH_MODEL_LIGHT_LIGHTNESS_RANGE_STATUS \
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x58)
|
||||
|
||||
#define BT_MESH_MODEL_LIGHT_CTL_STATUS BT_MESH_MODEL_OP_2(0x82, 0x60)
|
||||
#define BT_MESH_MODEL_LIGHT_CTL_TEMP_RANGE_STATUS \
|
||||
BT_MESH_MODEL_OP_2(0x82, 0x63)
|
||||
#define BT_MESH_MODEL_LIGHT_CTL_TEMP_STATUS BT_MESH_MODEL_OP_2(0x82, 0x66)
|
||||
#define BT_MESH_MODEL_LIGHT_CTL_DEFAULT_STATUS BT_MESH_MODEL_OP_2(0x82, 0x68)
|
||||
|
||||
void blemesh_on_reset(int reason);
|
||||
void blemesh_on_sync(void);
|
||||
void init_pub(void);
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
extern int button_device[];
|
||||
extern int led_device[];
|
||||
|
||||
void update_light_state(void);
|
||||
void bt_initialized(void);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,38 +26,18 @@
|
||||
#define CANNOT_SET_RANGE_MIN 0x01
|
||||
#define CANNOT_SET_RANGE_MAX 0x02
|
||||
|
||||
enum lightness {
|
||||
ONPOWERUP = 0x01,
|
||||
ONOFF,
|
||||
LEVEL,
|
||||
DELTA_LEVEL,
|
||||
ACTUAL,
|
||||
LINEAR,
|
||||
CTL,
|
||||
IGNORE
|
||||
};
|
||||
|
||||
enum temperature {
|
||||
ONOFF_TEMP = 0x01,
|
||||
LEVEL_TEMP,
|
||||
CTL_TEMP,
|
||||
IGNORE_TEMP
|
||||
};
|
||||
|
||||
struct generic_onoff_state {
|
||||
u8_t onoff;
|
||||
u8_t target_onoff;
|
||||
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
u16_t last_src_addr;
|
||||
u16_t last_dst_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
s32_t tt_delta;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
struct transition *transition;
|
||||
};
|
||||
|
||||
struct generic_level_state {
|
||||
@@ -68,24 +48,17 @@ struct generic_level_state {
|
||||
s32_t last_delta;
|
||||
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
u16_t last_src_addr;
|
||||
u16_t last_dst_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
|
||||
s32_t tt_delta;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
u32_t tt_counter_delta;
|
||||
u32_t tt_counter_move;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
struct transition *transition;
|
||||
};
|
||||
|
||||
struct generic_onpowerup_state {
|
||||
u8_t onpowerup;
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
};
|
||||
|
||||
struct gen_def_trans_time_state {
|
||||
@@ -96,7 +69,8 @@ struct vendor_state {
|
||||
int current;
|
||||
u32_t response;
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
u16_t last_src_addr;
|
||||
u16_t last_dst_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
};
|
||||
|
||||
@@ -113,20 +87,17 @@ struct light_lightness_state {
|
||||
u8_t status_code;
|
||||
u16_t light_range_min;
|
||||
u16_t light_range_max;
|
||||
u32_t lightness_range;
|
||||
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
u16_t last_src_addr;
|
||||
u16_t last_dst_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
|
||||
s32_t tt_delta_actual;
|
||||
s32_t tt_delta_linear;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter_actual;
|
||||
u32_t tt_counter_linear;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
struct transition *transition;
|
||||
};
|
||||
|
||||
struct light_ctl_state {
|
||||
@@ -142,27 +113,25 @@ struct light_ctl_state {
|
||||
u8_t status_code;
|
||||
u16_t temp_range_min;
|
||||
u16_t temp_range_max;
|
||||
u32_t temperature_range;
|
||||
|
||||
u16_t lightness_def;
|
||||
u16_t temp_def;
|
||||
u32_t lightness_temp_def;
|
||||
s16_t delta_uv_def;
|
||||
|
||||
u16_t temp_last;
|
||||
u32_t lightness_temp_last;
|
||||
|
||||
u8_t last_tid;
|
||||
u16_t last_tx_addr;
|
||||
u16_t last_src_addr;
|
||||
u16_t last_dst_addr;
|
||||
s64_t last_msg_timestamp;
|
||||
|
||||
s32_t tt_lightness_delta;
|
||||
s32_t tt_temp_delta;
|
||||
s32_t tt_duv_delta;
|
||||
u8_t tt;
|
||||
u32_t cal_tt;
|
||||
u8_t delay;
|
||||
u32_t tt_counter;
|
||||
u32_t tt_counter_temp;
|
||||
s32_t tt_delta_lightness;
|
||||
s32_t tt_delta_temp;
|
||||
s32_t tt_delta_duv;
|
||||
|
||||
u8_t is_optional_para_available;
|
||||
struct transition *transition;
|
||||
};
|
||||
|
||||
extern struct generic_onoff_state gen_onoff_srv_root_user_data;
|
||||
@@ -179,4 +148,11 @@ extern struct bt_mesh_model s0_models[];
|
||||
|
||||
extern const struct bt_mesh_comp comp;
|
||||
|
||||
void gen_onoff_publish(struct bt_mesh_model *model);
|
||||
void gen_level_publish(struct bt_mesh_model *model);
|
||||
void light_lightness_publish(struct bt_mesh_model *model);
|
||||
void light_lightness_linear_publish(struct bt_mesh_model *model);
|
||||
void light_ctl_publish(struct bt_mesh_model *model);
|
||||
void light_ctl_temp_publish(struct bt_mesh_model *model);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,88 +5,32 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "bsp/bsp.h"
|
||||
|
||||
#include "console/console.h"
|
||||
#include "hal/hal_gpio.h"
|
||||
#include "mesh/mesh.h"
|
||||
|
||||
#include "app_gpio.h"
|
||||
#include "storage.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
#include "no_transition_work_handler.h"
|
||||
#include "publisher.h"
|
||||
#include "state_binding.h"
|
||||
#include "transition.h"
|
||||
|
||||
int button_device[] = {
|
||||
BUTTON_1,
|
||||
BUTTON_2,
|
||||
BUTTON_3,
|
||||
BUTTON_4,
|
||||
};
|
||||
static bool reset;
|
||||
|
||||
int led_device[] = {
|
||||
LED_1,
|
||||
LED_2,
|
||||
LED_3,
|
||||
LED_4,
|
||||
};
|
||||
|
||||
static struct ble_npl_callout button_work;
|
||||
|
||||
static void button_pressed(struct os_event *ev)
|
||||
static void light_default_var_init(void)
|
||||
{
|
||||
k_work_submit(&button_work);
|
||||
}
|
||||
gen_def_trans_time_srv_user_data.tt = 0x00;
|
||||
|
||||
static struct os_event button_event;
|
||||
|
||||
static void
|
||||
gpio_irq_handler(void *arg)
|
||||
{
|
||||
button_event.ev_arg = arg;
|
||||
os_eventq_put(os_eventq_dflt_get(), &button_event);
|
||||
}
|
||||
|
||||
static void gpio_init(void)
|
||||
{
|
||||
/* LEDs configiuratin & setting */
|
||||
|
||||
hal_gpio_init_out(led_device[0], 1);
|
||||
hal_gpio_init_out(led_device[1], 1);
|
||||
hal_gpio_init_out(led_device[2], 1);
|
||||
hal_gpio_init_out(led_device[3], 1);
|
||||
|
||||
/* Buttons configiuratin & setting */
|
||||
|
||||
k_work_init(&button_work, publish);
|
||||
|
||||
button_event.ev_cb = button_pressed;
|
||||
|
||||
hal_gpio_irq_init(button_device[0], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[0]);
|
||||
|
||||
hal_gpio_irq_init(button_device[1], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[1]);
|
||||
|
||||
hal_gpio_irq_init(button_device[2], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[2]);
|
||||
|
||||
hal_gpio_irq_init(button_device[3], gpio_irq_handler, NULL,
|
||||
HAL_GPIO_TRIG_FALLING, HAL_GPIO_PULL_UP);
|
||||
hal_gpio_irq_enable(button_device[3]);
|
||||
}
|
||||
|
||||
void light_default_status_init(void)
|
||||
{
|
||||
/* Assume vaules are retrived from Persistence Storage (Start).
|
||||
* These had saved by respective Setup Servers.
|
||||
*/
|
||||
gen_power_onoff_srv_user_data.onpowerup = STATE_DEFAULT;
|
||||
|
||||
light_lightness_srv_user_data.light_range_min = LIGHTNESS_MIN;
|
||||
light_lightness_srv_user_data.light_range_max = LIGHTNESS_MAX;
|
||||
light_lightness_srv_user_data.last = LIGHTNESS_MAX;
|
||||
light_lightness_srv_user_data.def = LIGHTNESS_MAX;
|
||||
|
||||
/* Following 2 values are as per specification */
|
||||
@@ -94,50 +38,89 @@ void light_default_status_init(void)
|
||||
light_ctl_srv_user_data.temp_range_max = TEMP_MAX;
|
||||
|
||||
light_ctl_srv_user_data.temp_def = TEMP_MIN;
|
||||
/* (End) */
|
||||
|
||||
/* Assume following values are retrived from Persistence
|
||||
* Storage (Start).
|
||||
* These values had saved before power down.
|
||||
*/
|
||||
light_lightness_srv_user_data.last = LIGHTNESS_MAX;
|
||||
light_ctl_srv_user_data.temp_last = TEMP_MIN;
|
||||
/* (End) */
|
||||
light_ctl_srv_user_data.lightness_temp_last =
|
||||
(u32_t) ((LIGHTNESS_MAX << 16) | TEMP_MIN);
|
||||
}
|
||||
|
||||
static void light_default_status_init(void)
|
||||
{
|
||||
u16_t lightness;
|
||||
|
||||
lightness = (u16_t) (light_ctl_srv_user_data.lightness_temp_last >> 16);
|
||||
|
||||
if (lightness) {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
} else {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
|
||||
}
|
||||
|
||||
/* Retrieve Default Lightness & Temperature Values */
|
||||
|
||||
if (light_ctl_srv_user_data.lightness_temp_def) {
|
||||
light_ctl_srv_user_data.lightness_def = (u16_t)
|
||||
(light_ctl_srv_user_data.lightness_temp_def >> 16);
|
||||
|
||||
light_ctl_srv_user_data.temp_def = (u16_t)
|
||||
(light_ctl_srv_user_data.lightness_temp_def);
|
||||
}
|
||||
|
||||
light_lightness_srv_user_data.def =
|
||||
light_ctl_srv_user_data.lightness_def;
|
||||
|
||||
light_ctl_srv_user_data.temp = light_ctl_srv_user_data.temp_def;
|
||||
|
||||
if (gen_power_onoff_srv_user_data.onpowerup == STATE_OFF) {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
|
||||
state_binding(ONOFF, ONOFF_TEMP);
|
||||
} else if (gen_power_onoff_srv_user_data.onpowerup == STATE_DEFAULT) {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
state_binding(ONOFF, ONOFF_TEMP);
|
||||
} else if (gen_power_onoff_srv_user_data.onpowerup == STATE_RESTORE) {
|
||||
/* Assume following values is retrived from Persistence
|
||||
* Storage (Start).
|
||||
* This value had saved before power down.
|
||||
*/
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
/* (End) */
|
||||
/* Retrieve Range of Lightness & Temperature */
|
||||
|
||||
light_ctl_srv_user_data.temp =
|
||||
light_ctl_srv_user_data.temp_last;
|
||||
if (light_lightness_srv_user_data.lightness_range) {
|
||||
light_lightness_srv_user_data.light_range_max = (u16_t)
|
||||
(light_lightness_srv_user_data.lightness_range >> 16);
|
||||
|
||||
state_binding(ONPOWERUP, ONOFF_TEMP);
|
||||
light_lightness_srv_user_data.light_range_min = (u16_t)
|
||||
(light_lightness_srv_user_data.lightness_range);
|
||||
}
|
||||
|
||||
if (light_ctl_srv_user_data.temperature_range) {
|
||||
light_ctl_srv_user_data.temp_range_max = (u16_t)
|
||||
(light_ctl_srv_user_data.temperature_range >> 16);
|
||||
|
||||
light_ctl_srv_user_data.temp_range_min = (u16_t)
|
||||
(light_ctl_srv_user_data.temperature_range);
|
||||
}
|
||||
|
||||
switch (gen_power_onoff_srv_user_data.onpowerup) {
|
||||
case STATE_OFF:
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
|
||||
state_binding(ONOFF, ONOFF_TEMP);
|
||||
break;
|
||||
case STATE_DEFAULT:
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
state_binding(ONOFF, ONOFF_TEMP);
|
||||
break;
|
||||
case STATE_RESTORE:
|
||||
light_lightness_srv_user_data.last = (u16_t)
|
||||
(light_ctl_srv_user_data.lightness_temp_last >> 16);
|
||||
|
||||
light_ctl_srv_user_data.temp =
|
||||
(u16_t) (light_ctl_srv_user_data.lightness_temp_last);
|
||||
|
||||
state_binding(ONPOWERUP, ONOFF_TEMP);
|
||||
break;
|
||||
}
|
||||
|
||||
default_tt = gen_def_trans_time_srv_user_data.tt;
|
||||
}
|
||||
|
||||
void update_light_state(void)
|
||||
{
|
||||
u8_t power, color;
|
||||
|
||||
power = 100 * ((float) light_lightness_srv_user_data.actual / 65535);
|
||||
color = 100 * ((float) (gen_level_srv_s0_user_data.level + 32768)
|
||||
/ 65535);
|
||||
power = 100 * ((float) lightness / 65535);
|
||||
color = 100 * ((float) (temperature + 32768) / 65535);
|
||||
|
||||
printk("power-> %d, color-> %d\n", power, color);
|
||||
|
||||
if (gen_onoff_srv_root_user_data.onoff == STATE_ON) {
|
||||
if (lightness) {
|
||||
/* LED1 On */
|
||||
hal_gpio_write(led_device[0], 0);
|
||||
} else {
|
||||
@@ -160,6 +143,56 @@ void update_light_state(void)
|
||||
/* LED4 Off */
|
||||
hal_gpio_write(led_device[3], 1);
|
||||
}
|
||||
|
||||
if (*ptr_counter == 0 || reset == false) {
|
||||
reset = true;
|
||||
k_work_submit(&no_transition_work);
|
||||
}
|
||||
}
|
||||
|
||||
static void short_time_multireset_bt_mesh_unprovisioning(void)
|
||||
{
|
||||
if (reset_counter >= 4) {
|
||||
reset_counter = 0;
|
||||
printk("BT Mesh reset\n");
|
||||
bt_mesh_reset();
|
||||
} else {
|
||||
printk("Reset Counter -> %d\n", reset_counter);
|
||||
reset_counter++;
|
||||
}
|
||||
|
||||
save_on_flash(RESET_COUNTER);
|
||||
}
|
||||
|
||||
static void reset_counter_timer_handler(struct ble_npl_event *dummy)
|
||||
{
|
||||
reset_counter = 0;
|
||||
save_on_flash(RESET_COUNTER);
|
||||
printk("Reset Counter set to Zero\n");
|
||||
}
|
||||
|
||||
struct ble_npl_callout reset_counter_timer;
|
||||
|
||||
static void init_timers(void)
|
||||
{
|
||||
|
||||
ble_npl_callout_init(&reset_counter_timer, ble_npl_eventq_dflt_get(),
|
||||
reset_counter_timer_handler, NULL);
|
||||
ble_npl_callout_reset(&reset_counter_timer,
|
||||
ble_npl_time_ms_to_ticks32(K_MSEC(7000)));
|
||||
|
||||
no_transition_work_init();
|
||||
}
|
||||
|
||||
void bt_initialized(void)
|
||||
{
|
||||
light_default_status_init();
|
||||
|
||||
update_light_state();
|
||||
|
||||
randomize_publishers_TID();
|
||||
|
||||
short_time_multireset_bt_mesh_unprovisioning();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
@@ -171,16 +204,18 @@ int main(void)
|
||||
/* Initialize OS */
|
||||
sysinit();
|
||||
|
||||
light_default_status_init();
|
||||
light_default_var_init();
|
||||
|
||||
app_gpio_init();
|
||||
|
||||
init_timers();
|
||||
|
||||
transition_timers_init();
|
||||
|
||||
gpio_init();
|
||||
|
||||
update_light_state();
|
||||
|
||||
init_pub();
|
||||
|
||||
ps_settings_init();
|
||||
|
||||
printk("Initializing...\n");
|
||||
|
||||
/* Initialize the NimBLE host configuration. */
|
||||
@@ -188,8 +223,6 @@ int main(void)
|
||||
ble_hs_cfg.sync_cb = blemesh_on_sync;
|
||||
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
|
||||
|
||||
randomize_publishers_TID();
|
||||
|
||||
while (1) {
|
||||
os_eventq_run(os_eventq_dflt_get());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
|
||||
#include "storage.h"
|
||||
|
||||
static void unsolicitedly_publish_states_work_handler(struct ble_npl_event *work)
|
||||
{
|
||||
gen_onoff_publish(&root_models[2]);
|
||||
gen_level_publish(&root_models[4]);
|
||||
light_lightness_publish(&root_models[11]);
|
||||
light_lightness_linear_publish(&root_models[11]);
|
||||
light_ctl_publish(&root_models[14]);
|
||||
|
||||
gen_level_publish(&s0_models[0]);
|
||||
light_ctl_temp_publish(&s0_models[2]);
|
||||
}
|
||||
|
||||
struct ble_npl_callout unsolicitedly_publish_states_work;
|
||||
|
||||
static void unsolicitedly_publish_states_timer_handler(struct ble_npl_event *dummy)
|
||||
{
|
||||
k_work_submit(&unsolicitedly_publish_states_work);
|
||||
}
|
||||
|
||||
struct ble_npl_callout unsolicitedly_publish_states_timer;
|
||||
|
||||
static void save_lightness_temp_last_values_timer_handler(struct ble_npl_event *dummy)
|
||||
{
|
||||
save_on_flash(LIGHTNESS_TEMP_LAST_STATE);
|
||||
}
|
||||
|
||||
struct ble_npl_callout save_lightness_temp_last_values_timer;
|
||||
|
||||
static void no_transition_work_handler(struct ble_npl_event *work)
|
||||
{
|
||||
ble_npl_callout_reset(&unsolicitedly_publish_states_timer,
|
||||
ble_npl_time_ms_to_ticks32(K_MSEC(5000)));
|
||||
|
||||
/* If Lightness & Temperature values remains stable for
|
||||
* 10 Seconds then & then only get stored on SoC flash.
|
||||
*/
|
||||
if (gen_power_onoff_srv_user_data.onpowerup == STATE_RESTORE) {
|
||||
ble_npl_callout_reset(&save_lightness_temp_last_values_timer,
|
||||
ble_npl_time_ms_to_ticks32(
|
||||
K_MSEC(10000)));
|
||||
}
|
||||
}
|
||||
|
||||
struct ble_npl_callout no_transition_work;
|
||||
|
||||
void no_transition_work_init(void)
|
||||
{
|
||||
ble_npl_callout_init(&no_transition_work, ble_npl_eventq_dflt_get(),
|
||||
no_transition_work_handler, NULL);
|
||||
ble_npl_callout_init(&save_lightness_temp_last_values_timer,
|
||||
ble_npl_eventq_dflt_get(),
|
||||
save_lightness_temp_last_values_timer_handler,
|
||||
NULL);
|
||||
ble_npl_callout_init(&unsolicitedly_publish_states_work, ble_npl_eventq_dflt_get(),
|
||||
unsolicitedly_publish_states_work_handler, NULL);
|
||||
ble_npl_callout_init(&unsolicitedly_publish_states_timer, ble_npl_eventq_dflt_get(),
|
||||
unsolicitedly_publish_states_timer_handler, NULL);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _NO_TRANSITION_WORK_HANDLER_H
|
||||
#define _NO_TRANSITION_WORK_HANDLER_H
|
||||
|
||||
extern struct ble_npl_callout no_transition_work;
|
||||
|
||||
void no_transition_work_init(void);
|
||||
|
||||
#endif
|
||||
@@ -8,10 +8,11 @@
|
||||
#include "console/console.h"
|
||||
#include "hal/hal_gpio.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "app_gpio.h"
|
||||
|
||||
#include "ble_mesh.h"
|
||||
#include "publisher.h"
|
||||
#include "device_composition.h"
|
||||
#include "publisher.h"
|
||||
|
||||
#define ONOFF
|
||||
#define GENERIC_LEVEL
|
||||
@@ -20,7 +21,7 @@
|
||||
|
||||
static bool is_randomization_of_TIDs_done;
|
||||
|
||||
#if defined(ONOFF)
|
||||
#if (defined(ONOFF) || defined(ONOFF_TT))
|
||||
static u8_t tid_onoff;
|
||||
#elif defined(VND_MODEL_TEST)
|
||||
static u8_t tid_vnd;
|
||||
@@ -30,7 +31,7 @@ static u8_t tid_level;
|
||||
|
||||
void randomize_publishers_TID(void)
|
||||
{
|
||||
#if defined(ONOFF)
|
||||
#if (defined(ONOFF) || defined(ONOFF_TT))
|
||||
bt_rand(&tid_onoff, sizeof(tid_onoff));
|
||||
#elif defined(VND_MODEL_TEST)
|
||||
bt_rand(&tid_vnd, sizeof(tid_vnd));
|
||||
@@ -71,7 +72,7 @@ void publish(struct ble_npl_event *work)
|
||||
err = bt_mesh_model_publish(&root_models[3]);
|
||||
#elif defined(VND_MODEL_TEST)
|
||||
bt_mesh_model_msg_init(vnd_models[0].pub->msg,
|
||||
BT_MESH_MODEL_OP_3(0x02, CID_RUNTIME));
|
||||
BT_MESH_MODEL_OP_3(0x03, CID_RUNTIME));
|
||||
net_buf_simple_add_le16(vnd_models[0].pub->msg, 0x0001);
|
||||
net_buf_simple_add_u8(vnd_models[0].pub->msg, tid_vnd++);
|
||||
err = bt_mesh_model_publish(&vnd_models[0]);
|
||||
@@ -94,7 +95,7 @@ void publish(struct ble_npl_event *work)
|
||||
err = bt_mesh_model_publish(&root_models[3]);
|
||||
#elif defined(VND_MODEL_TEST)
|
||||
bt_mesh_model_msg_init(vnd_models[0].pub->msg,
|
||||
BT_MESH_MODEL_OP_3(0x02, CID_RUNTIME));
|
||||
BT_MESH_MODEL_OP_3(0x03, CID_RUNTIME));
|
||||
net_buf_simple_add_le16(vnd_models[0].pub->msg, 0x0000);
|
||||
net_buf_simple_add_u8(vnd_models[0].pub->msg, tid_vnd++);
|
||||
err = bt_mesh_model_publish(&vnd_models[0]);
|
||||
@@ -107,6 +108,10 @@ void publish(struct ble_npl_event *work)
|
||||
net_buf_simple_add_le16(root_models[5].pub->msg, LEVEL_S25);
|
||||
net_buf_simple_add_u8(root_models[5].pub->msg, tid_level++);
|
||||
err = bt_mesh_model_publish(&root_models[5]);
|
||||
#elif defined(ONOFF_GET)
|
||||
bt_mesh_model_msg_init(root_models[3].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_ONOFF_GET);
|
||||
err = bt_mesh_model_publish(&root_models[3]);
|
||||
#elif defined(GENERIC_DELTA_LEVEL)
|
||||
bt_mesh_model_msg_init(root_models[5].pub->msg,
|
||||
BT_MESH_MODEL_OP_GEN_DELTA_SET_UNACK);
|
||||
@@ -239,3 +244,4 @@ void publish(struct ble_npl_event *work)
|
||||
printk("bt_mesh_model_publish: err: %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,14 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
#include "state_binding.h"
|
||||
#include "transition.h"
|
||||
|
||||
|
||||
u16_t lightness, target_lightness;
|
||||
s16_t temperature, target_temperature;
|
||||
|
||||
static s32_t ceiling(float num)
|
||||
{
|
||||
@@ -23,161 +28,262 @@ static s32_t ceiling(float num)
|
||||
return inum + 1;
|
||||
}
|
||||
|
||||
static bool constrain_light_actual_state(u16_t var)
|
||||
u16_t actual_to_linear(u16_t val)
|
||||
{
|
||||
bool is_value_within_range;
|
||||
float tmp;
|
||||
|
||||
is_value_within_range = false;
|
||||
tmp = ((float) val / 65535);
|
||||
|
||||
return (u16_t) ceiling(65535 * tmp * tmp);
|
||||
}
|
||||
|
||||
u16_t linear_to_actual(u16_t val)
|
||||
{
|
||||
return (u16_t) (65535 * sqrt(((float) val / 65535)));
|
||||
}
|
||||
|
||||
static void constrain_lightness(u16_t var)
|
||||
{
|
||||
if (var > 0 && var < light_lightness_srv_user_data.light_range_min) {
|
||||
var = light_lightness_srv_user_data.light_range_min;
|
||||
} else if (var > light_lightness_srv_user_data.light_range_max) {
|
||||
var = light_lightness_srv_user_data.light_range_max;
|
||||
}
|
||||
|
||||
lightness = var;
|
||||
}
|
||||
|
||||
static void constrain_lightness2(u16_t var)
|
||||
{
|
||||
/* This is as per Mesh Model Specification 3.3.2.2.3 */
|
||||
if (var > 0 && var < light_lightness_srv_user_data.light_range_min) {
|
||||
if (gen_level_srv_root_user_data.last_delta < 0) {
|
||||
var = 0U;
|
||||
} else {
|
||||
var = light_lightness_srv_user_data.light_range_min;
|
||||
}
|
||||
} else if (var > light_lightness_srv_user_data.light_range_max) {
|
||||
var = light_lightness_srv_user_data.light_range_max;
|
||||
}
|
||||
|
||||
lightness = var;
|
||||
}
|
||||
|
||||
static void constrain_target_lightness(u16_t var)
|
||||
{
|
||||
if (var > 0 &&
|
||||
var < light_lightness_srv_user_data.light_range_min) {
|
||||
var = light_lightness_srv_user_data.light_range_min;
|
||||
} else if (var > light_lightness_srv_user_data.light_range_max) {
|
||||
var = light_lightness_srv_user_data.light_range_max;
|
||||
} else {
|
||||
is_value_within_range = true;
|
||||
}
|
||||
|
||||
light_lightness_srv_user_data.actual = var;
|
||||
|
||||
return is_value_within_range;
|
||||
target_lightness = var;
|
||||
}
|
||||
|
||||
static void update_gen_onoff_state(void)
|
||||
static s16_t light_ctl_temp_to_level(u16_t temp)
|
||||
{
|
||||
if (light_lightness_srv_user_data.actual == 0) {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
|
||||
} else {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
}
|
||||
}
|
||||
|
||||
void state_binding(u8_t lightness, u8_t temperature)
|
||||
{
|
||||
bool is_value_within_range;
|
||||
u16_t tmp16;
|
||||
float tmp;
|
||||
|
||||
switch (temperature) {
|
||||
case ONOFF_TEMP:/* Temp. update as per Light CTL temp. default state */
|
||||
case CTL_TEMP: /* Temp. update as per Light CTL temp. state */
|
||||
/* Mesh Model Specification 6.1.3.1.1 2nd formula start */
|
||||
tmp = (light_ctl_srv_user_data.temp -
|
||||
light_ctl_srv_user_data.temp_range_min) * 65535;
|
||||
tmp = tmp / (light_ctl_srv_user_data.temp_range_max -
|
||||
light_ctl_srv_user_data.temp_range_min);
|
||||
gen_level_srv_s0_user_data.level = tmp - 32768;
|
||||
/* 6.1.3.1.1 2nd formula end */
|
||||
/* Mesh Model Specification 6.1.3.1.1 2nd formula start */
|
||||
|
||||
tmp = (temp - light_ctl_srv_user_data.temp_range_min) * 65535;
|
||||
|
||||
tmp = tmp / (light_ctl_srv_user_data.temp_range_max -
|
||||
light_ctl_srv_user_data.temp_range_min);
|
||||
|
||||
return (s16_t) (tmp - 32768);
|
||||
|
||||
/* 6.1.3.1.1 2nd formula end */
|
||||
}
|
||||
|
||||
static u16_t level_to_light_ctl_temp(s16_t level)
|
||||
{
|
||||
u16_t tmp;
|
||||
float diff;
|
||||
|
||||
/* Mesh Model Specification 6.1.3.1.1 1st formula start */
|
||||
diff = (float) (light_ctl_srv_user_data.temp_range_max -
|
||||
light_ctl_srv_user_data.temp_range_min) / 65535;
|
||||
|
||||
|
||||
tmp = (u16_t) ((level + 32768) * diff);
|
||||
|
||||
return (light_ctl_srv_user_data.temp_range_min + tmp);
|
||||
|
||||
/* 6.1.3.1.1 1st formula end */
|
||||
}
|
||||
|
||||
void state_binding(u8_t light, u8_t temp)
|
||||
{
|
||||
switch (temp) {
|
||||
case ONOFF_TEMP:
|
||||
case CTL_TEMP:
|
||||
temperature =
|
||||
light_ctl_temp_to_level(light_ctl_srv_user_data.temp);
|
||||
|
||||
gen_level_srv_s0_user_data.level = temperature;
|
||||
break;
|
||||
case LEVEL_TEMP:/* Temp. update as per Generic Level (s0) state */
|
||||
/* Mesh Model Specification 6.1.3.1.1 1st formula start */
|
||||
tmp = (float) (light_ctl_srv_user_data.temp_range_max -
|
||||
light_ctl_srv_user_data.temp_range_min) / 65535;
|
||||
tmp = (gen_level_srv_s0_user_data.level + 32768) * tmp;
|
||||
case LEVEL_TEMP:
|
||||
temperature = gen_level_srv_s0_user_data.level;
|
||||
light_ctl_srv_user_data.temp =
|
||||
light_ctl_srv_user_data.temp_range_min + tmp;
|
||||
/* 6.1.3.1.1 1st formula end */
|
||||
level_to_light_ctl_temp(temperature);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tmp16 = 0;
|
||||
|
||||
switch (lightness) {
|
||||
case ONPOWERUP: /* Lightness update as per Generic OnPowerUp state */
|
||||
switch (light) {
|
||||
case ONPOWERUP:
|
||||
if (gen_onoff_srv_root_user_data.onoff == STATE_OFF) {
|
||||
light_lightness_srv_user_data.actual = 0;
|
||||
light_lightness_srv_user_data.linear = 0;
|
||||
gen_level_srv_root_user_data.level = -32768;
|
||||
light_ctl_srv_user_data.lightness = 0;
|
||||
return;
|
||||
lightness = 0U;
|
||||
} else if (gen_onoff_srv_root_user_data.onoff == STATE_ON) {
|
||||
light_lightness_srv_user_data.actual =
|
||||
light_lightness_srv_user_data.last;
|
||||
lightness = light_lightness_srv_user_data.last;
|
||||
}
|
||||
|
||||
break;
|
||||
case ONOFF: /* Lightness update as per Generic OnOff (root) state */
|
||||
case ONOFF:
|
||||
if (gen_onoff_srv_root_user_data.onoff == STATE_OFF) {
|
||||
light_lightness_srv_user_data.actual = 0;
|
||||
light_lightness_srv_user_data.linear = 0;
|
||||
gen_level_srv_root_user_data.level = -32768;
|
||||
light_ctl_srv_user_data.lightness = 0;
|
||||
return;
|
||||
lightness = 0U;
|
||||
} else if (gen_onoff_srv_root_user_data.onoff == STATE_ON) {
|
||||
if (light_lightness_srv_user_data.def == 0) {
|
||||
light_lightness_srv_user_data.actual =
|
||||
light_lightness_srv_user_data.last;
|
||||
lightness = light_lightness_srv_user_data.last;
|
||||
} else {
|
||||
light_lightness_srv_user_data.actual =
|
||||
light_lightness_srv_user_data.def;
|
||||
lightness = light_lightness_srv_user_data.def;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LEVEL:
|
||||
lightness = gen_level_srv_root_user_data.level + 32768;
|
||||
break;
|
||||
case DELTA_LEVEL:
|
||||
lightness = gen_level_srv_root_user_data.level + 32768;
|
||||
constrain_lightness2(lightness);
|
||||
goto jump;
|
||||
case ACTUAL:
|
||||
lightness = light_lightness_srv_user_data.actual;
|
||||
break;
|
||||
case LINEAR:
|
||||
lightness =
|
||||
linear_to_actual(light_lightness_srv_user_data.linear);
|
||||
break;
|
||||
case CTL:
|
||||
lightness = light_ctl_srv_user_data.lightness;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case LEVEL: /* Lightness update as per Generic Level (root) state */
|
||||
tmp16 = gen_level_srv_root_user_data.level + 32768;
|
||||
constrain_light_actual_state(tmp16);
|
||||
update_gen_onoff_state();
|
||||
break;
|
||||
case DELTA_LEVEL: /* Lightness update as per Gen. Level (root) state */
|
||||
/* This is as per Mesh Model Specification 3.3.2.2.3 */
|
||||
tmp16 = gen_level_srv_root_user_data.level + 32768;
|
||||
if (tmp16 > 0 &&
|
||||
tmp16 < light_lightness_srv_user_data.light_range_min) {
|
||||
if (gen_level_srv_root_user_data.last_delta < 0) {
|
||||
tmp16 = 0;
|
||||
constrain_lightness(lightness);
|
||||
|
||||
jump:
|
||||
if (lightness != 0) {
|
||||
light_lightness_srv_user_data.last = lightness;
|
||||
}
|
||||
|
||||
if (lightness) {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||
} else {
|
||||
gen_onoff_srv_root_user_data.onoff = STATE_OFF;
|
||||
}
|
||||
|
||||
gen_level_srv_root_user_data.level = lightness - 32768;
|
||||
light_lightness_srv_user_data.actual = lightness;
|
||||
light_lightness_srv_user_data.linear = actual_to_linear(lightness);
|
||||
light_ctl_srv_user_data.lightness = lightness;
|
||||
}
|
||||
|
||||
void calculate_lightness_target_values(u8_t type)
|
||||
{
|
||||
bool set_light_ctl_temp_target_value;
|
||||
u16_t tmp;
|
||||
|
||||
set_light_ctl_temp_target_value = true;
|
||||
|
||||
switch (type) {
|
||||
case ONOFF:
|
||||
if (gen_onoff_srv_root_user_data.target_onoff == 0) {
|
||||
tmp = 0U;
|
||||
} else {
|
||||
if (light_lightness_srv_user_data.def == 0) {
|
||||
tmp = light_lightness_srv_user_data.last;
|
||||
} else {
|
||||
tmp16 =
|
||||
light_lightness_srv_user_data.light_range_min;
|
||||
tmp = light_lightness_srv_user_data.def;
|
||||
}
|
||||
} else if (tmp16 >
|
||||
light_lightness_srv_user_data.light_range_max) {
|
||||
tmp16 =
|
||||
light_lightness_srv_user_data.light_range_max;
|
||||
}
|
||||
|
||||
light_lightness_srv_user_data.actual = tmp16;
|
||||
|
||||
update_gen_onoff_state();
|
||||
break;
|
||||
case ACTUAL: /* Lightness update as per Light Lightness Actual state */
|
||||
update_gen_onoff_state();
|
||||
case LEVEL:
|
||||
tmp = gen_level_srv_root_user_data.target_level + 32768;
|
||||
break;
|
||||
case LINEAR: /* Lightness update as per Light Lightness Linear state */
|
||||
tmp16 = (u16_t) 65535 *
|
||||
sqrt(((float) light_lightness_srv_user_data.linear /
|
||||
65535));
|
||||
|
||||
is_value_within_range = constrain_light_actual_state(tmp16);
|
||||
update_gen_onoff_state();
|
||||
|
||||
if (is_value_within_range) {
|
||||
goto ignore_linear_update_others;
|
||||
}
|
||||
|
||||
case ACTUAL:
|
||||
tmp = light_lightness_srv_user_data.target_actual;
|
||||
break;
|
||||
case CTL: /* Lightness update as per Light CTL Lightness state */
|
||||
constrain_light_actual_state(light_ctl_srv_user_data.lightness);
|
||||
update_gen_onoff_state();
|
||||
case LINEAR:
|
||||
tmp = linear_to_actual(light_lightness_srv_user_data.target_linear);
|
||||
break;
|
||||
case CTL:
|
||||
set_light_ctl_temp_target_value = false;
|
||||
|
||||
tmp = light_ctl_srv_user_data.target_lightness;
|
||||
|
||||
target_temperature = light_ctl_temp_to_level(light_ctl_srv_user_data.target_temp);
|
||||
gen_level_srv_s0_user_data.target_level = target_temperature;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = ((float) light_lightness_srv_user_data.actual / 65535);
|
||||
light_lightness_srv_user_data.linear = ceiling(65535 * tmp * tmp);
|
||||
constrain_target_lightness(tmp);
|
||||
|
||||
ignore_linear_update_others:
|
||||
if (light_lightness_srv_user_data.actual != 0) {
|
||||
light_lightness_srv_user_data.last =
|
||||
light_lightness_srv_user_data.actual;
|
||||
if (target_lightness) {
|
||||
gen_onoff_srv_root_user_data.target_onoff = STATE_ON;
|
||||
} else {
|
||||
gen_onoff_srv_root_user_data.target_onoff = STATE_OFF;
|
||||
}
|
||||
|
||||
gen_level_srv_root_user_data.level =
|
||||
light_lightness_srv_user_data.actual - 32768;
|
||||
gen_level_srv_root_user_data.target_level = target_lightness - 32768;
|
||||
|
||||
light_ctl_srv_user_data.lightness =
|
||||
light_lightness_srv_user_data.actual;
|
||||
light_lightness_srv_user_data.target_actual = target_lightness;
|
||||
|
||||
light_lightness_srv_user_data.target_linear =
|
||||
actual_to_linear(target_lightness);
|
||||
|
||||
light_ctl_srv_user_data.target_lightness = target_lightness;
|
||||
|
||||
if (set_light_ctl_temp_target_value) {
|
||||
target_temperature = light_ctl_srv_user_data.temp;
|
||||
light_ctl_srv_user_data.target_temp = target_temperature;
|
||||
}
|
||||
}
|
||||
|
||||
void calculate_temp_target_values(u8_t type)
|
||||
{
|
||||
bool set_light_ctl_delta_uv_target_value;
|
||||
|
||||
set_light_ctl_delta_uv_target_value = true;
|
||||
|
||||
switch (type) {
|
||||
case LEVEL_TEMP:
|
||||
target_temperature = gen_level_srv_s0_user_data.target_level;
|
||||
light_ctl_srv_user_data.target_temp =
|
||||
level_to_light_ctl_temp(target_temperature);
|
||||
break;
|
||||
case CTL_TEMP:
|
||||
set_light_ctl_delta_uv_target_value = false;
|
||||
|
||||
target_temperature = light_ctl_temp_to_level(light_ctl_srv_user_data.target_temp);
|
||||
gen_level_srv_s0_user_data.target_level = target_temperature;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
target_lightness = light_ctl_srv_user_data.lightness;
|
||||
light_ctl_srv_user_data.target_lightness = target_lightness;
|
||||
|
||||
if (set_light_ctl_delta_uv_target_value) {
|
||||
|
||||
light_ctl_srv_user_data.target_delta_uv =
|
||||
light_ctl_srv_user_data.delta_uv;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,27 @@
|
||||
#ifndef _STATE_BINDING_H
|
||||
#define _STATE_BINDING_H
|
||||
|
||||
enum state_binding {
|
||||
ONPOWERUP = 0x01,
|
||||
ONOFF,
|
||||
LEVEL,
|
||||
DELTA_LEVEL,
|
||||
ACTUAL,
|
||||
LINEAR,
|
||||
CTL,
|
||||
IGNORE,
|
||||
|
||||
ONOFF_TEMP,
|
||||
LEVEL_TEMP,
|
||||
CTL_TEMP,
|
||||
IGNORE_TEMP
|
||||
};
|
||||
|
||||
extern u16_t lightness, target_lightness;
|
||||
extern s16_t temperature, target_temperature;
|
||||
|
||||
void state_binding(u8_t lightness, u8_t temperature);
|
||||
void calculate_lightness_target_values(u8_t type);
|
||||
void calculate_temp_target_values(u8_t type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "base64/base64.h"
|
||||
#include "console/console.h"
|
||||
#include "mesh/mesh.h"
|
||||
|
||||
#include "ble_mesh.h"
|
||||
#include "device_composition.h"
|
||||
#include "storage.h"
|
||||
|
||||
static u8_t storage_id;
|
||||
u8_t reset_counter;
|
||||
|
||||
static void save_reset_counter(void)
|
||||
{
|
||||
char buf[5];
|
||||
|
||||
settings_str_from_bytes(&reset_counter, sizeof(reset_counter), buf,
|
||||
sizeof(buf));
|
||||
|
||||
settings_save_one("ps/rc", buf);
|
||||
}
|
||||
|
||||
static void save_gen_def_trans_time_state(void)
|
||||
{
|
||||
char buf[5];
|
||||
|
||||
settings_str_from_bytes(&gen_def_trans_time_srv_user_data.tt,
|
||||
sizeof(gen_def_trans_time_srv_user_data.tt),
|
||||
buf, sizeof(buf));
|
||||
|
||||
settings_save_one("ps/gdtt", buf);
|
||||
}
|
||||
|
||||
static void save_gen_onpowerup_state(void)
|
||||
{
|
||||
char buf[5];
|
||||
|
||||
settings_str_from_bytes(&gen_power_onoff_srv_user_data.onpowerup,
|
||||
sizeof(gen_power_onoff_srv_user_data.onpowerup),
|
||||
buf, sizeof(buf));
|
||||
|
||||
settings_save_one("ps/gpo", buf);
|
||||
|
||||
if (gen_power_onoff_srv_user_data.onpowerup == 0x02) {
|
||||
save_on_flash(LIGHTNESS_TEMP_LAST_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
static void save_lightness_temp_def_state(void)
|
||||
{
|
||||
char buf[12];
|
||||
|
||||
light_ctl_srv_user_data.lightness_temp_def =
|
||||
(u32_t) ((light_ctl_srv_user_data.lightness_def << 16) |
|
||||
light_ctl_srv_user_data.temp_def);
|
||||
|
||||
settings_str_from_bytes(&light_ctl_srv_user_data.lightness_temp_def,
|
||||
sizeof(light_ctl_srv_user_data.lightness_temp_def),
|
||||
buf, sizeof(buf));
|
||||
|
||||
settings_save_one("ps/ltd", buf);
|
||||
}
|
||||
|
||||
static void save_lightness_temp_last_state(void)
|
||||
{
|
||||
char buf[12];
|
||||
|
||||
light_ctl_srv_user_data.lightness_temp_last =
|
||||
(u32_t) ((light_ctl_srv_user_data.lightness << 16) |
|
||||
light_ctl_srv_user_data.temp);
|
||||
|
||||
settings_str_from_bytes(&light_ctl_srv_user_data.lightness_temp_last,
|
||||
sizeof(light_ctl_srv_user_data.lightness_temp_last),
|
||||
buf, sizeof(buf));
|
||||
|
||||
settings_save_one("ps/ltl", buf);
|
||||
|
||||
printk("Light CTL Last values have beed saved !!\n");
|
||||
}
|
||||
|
||||
static void save_lightness_range(void)
|
||||
{
|
||||
char buf[12];
|
||||
|
||||
light_lightness_srv_user_data.lightness_range =
|
||||
(u32_t) ((light_lightness_srv_user_data.light_range_max << 16) |
|
||||
light_lightness_srv_user_data.light_range_min);
|
||||
|
||||
settings_str_from_bytes(&light_lightness_srv_user_data.lightness_range,
|
||||
sizeof(light_lightness_srv_user_data.lightness_range),
|
||||
buf, sizeof(buf));
|
||||
|
||||
settings_save_one("ps/lr", buf);
|
||||
}
|
||||
|
||||
static void save_temperature_range(void)
|
||||
{
|
||||
char buf[12];
|
||||
|
||||
light_ctl_srv_user_data.temperature_range =
|
||||
(u32_t) ((light_ctl_srv_user_data.temp_range_max << 16) |
|
||||
light_ctl_srv_user_data.temp_range_min);
|
||||
|
||||
settings_str_from_bytes(&light_ctl_srv_user_data.temperature_range,
|
||||
sizeof(light_ctl_srv_user_data.temperature_range),
|
||||
buf, sizeof(buf));
|
||||
|
||||
settings_save_one("ps/tr", buf);
|
||||
}
|
||||
|
||||
static void storage_work_handler(struct ble_npl_event *work)
|
||||
{
|
||||
switch (storage_id) {
|
||||
case RESET_COUNTER:
|
||||
save_reset_counter();
|
||||
break;
|
||||
case GEN_DEF_TRANS_TIME_STATE:
|
||||
save_gen_def_trans_time_state();
|
||||
break;
|
||||
case GEN_ONPOWERUP_STATE:
|
||||
save_gen_onpowerup_state();
|
||||
break;
|
||||
case LIGHTNESS_TEMP_DEF_STATE:
|
||||
save_lightness_temp_def_state();
|
||||
break;
|
||||
case LIGHTNESS_TEMP_LAST_STATE:
|
||||
save_lightness_temp_last_state();
|
||||
break;
|
||||
case LIGHTNESS_RANGE:
|
||||
save_lightness_range();
|
||||
break;
|
||||
case TEMPERATURE_RANGE:
|
||||
save_temperature_range();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct ble_npl_callout storage_work;
|
||||
|
||||
void save_on_flash(u8_t id)
|
||||
{
|
||||
storage_id = id;
|
||||
k_work_submit(&storage_work);
|
||||
ble_npl_callout_reset(&storage_work, 0);
|
||||
}
|
||||
|
||||
static int ps_set(int argc, char **argv, char *val)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (argc == 1) {
|
||||
if (!strcmp(argv[0], "rc")) {
|
||||
len = sizeof(reset_counter);
|
||||
|
||||
return settings_bytes_from_str(val, &reset_counter,
|
||||
&len);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "gdtt")) {
|
||||
len = sizeof(gen_def_trans_time_srv_user_data.tt);
|
||||
|
||||
return settings_bytes_from_str(val,
|
||||
&gen_def_trans_time_srv_user_data.tt, &len);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "gpo")) {
|
||||
len = sizeof(gen_power_onoff_srv_user_data.onpowerup);
|
||||
|
||||
return settings_bytes_from_str(val,
|
||||
&gen_power_onoff_srv_user_data.onpowerup, &len);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "ltd")) {
|
||||
len = sizeof(light_ctl_srv_user_data.lightness_temp_def);
|
||||
|
||||
return settings_bytes_from_str(val,
|
||||
&light_ctl_srv_user_data.lightness_temp_def,
|
||||
&len);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "ltl")) {
|
||||
len = sizeof(light_ctl_srv_user_data.
|
||||
lightness_temp_last);
|
||||
|
||||
return settings_bytes_from_str(val,
|
||||
&light_ctl_srv_user_data.lightness_temp_last,
|
||||
&len);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "lr")) {
|
||||
len = sizeof(light_lightness_srv_user_data.
|
||||
lightness_range);
|
||||
|
||||
return settings_bytes_from_str(val,
|
||||
&light_lightness_srv_user_data.lightness_range,
|
||||
&len);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "tr")) {
|
||||
len = sizeof(light_ctl_srv_user_data.
|
||||
temperature_range);
|
||||
|
||||
return settings_bytes_from_str(val,
|
||||
&light_ctl_srv_user_data. temperature_range,
|
||||
&len);
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static struct conf_handler ps_settings = {
|
||||
.ch_name = "ps",
|
||||
.ch_set = ps_set,
|
||||
};
|
||||
|
||||
int ps_settings_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
ble_npl_callout_init(&storage_work, ble_npl_eventq_dflt_get(),
|
||||
storage_work_handler, NULL);
|
||||
|
||||
err = conf_register(&ps_settings);
|
||||
if (err) {
|
||||
printk("ps_settings_register failed (err %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/* Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models
|
||||
*
|
||||
* Copyright (c) 2018 Vikrant More
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _STORAGE_H
|
||||
#define _STORAGE_H
|
||||
|
||||
enum ps_variables_id {
|
||||
RESET_COUNTER = 0x01,
|
||||
GEN_DEF_TRANS_TIME_STATE,
|
||||
GEN_ONPOWERUP_STATE,
|
||||
LIGHTNESS_TEMP_DEF_STATE,
|
||||
LIGHTNESS_TEMP_LAST_STATE,
|
||||
LIGHTNESS_RANGE,
|
||||
TEMPERATURE_RANGE
|
||||
};
|
||||
|
||||
extern u8_t reset_counter;
|
||||
|
||||
extern struct ble_npl_callout storage_work;
|
||||
|
||||
int ps_settings_init(void);
|
||||
void save_on_flash(u8_t id);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,42 +8,52 @@
|
||||
#ifndef _TRANSITION_H
|
||||
#define _TRANSITION_H
|
||||
|
||||
#define UNKNOWN_VALUE 0x3F
|
||||
#define DEVICE_SPECIFIC_RESOLUTION 10
|
||||
|
||||
enum transition_time {
|
||||
DISABLE_TRANSITION = 0x00,
|
||||
ONOFF_TT = 0x01,
|
||||
enum level_transition_types {
|
||||
LEVEL_TT,
|
||||
LEVEL_TT_DELTA,
|
||||
LEVEL_TT_MOVE,
|
||||
LIGTH_LIGHTNESS_ACTUAL_TT,
|
||||
LIGTH_LIGHTNESS_LINEAR_TT,
|
||||
LIGTH_CTL_TT,
|
||||
|
||||
LEVEL_TEMP_TT,
|
||||
LEVEL_TEMP_TT_DELTA,
|
||||
LEVEL_TEMP_TT_MOVE,
|
||||
LIGHT_CTL_TEMP_TT
|
||||
};
|
||||
|
||||
extern u8_t enable_transition;
|
||||
extern u8_t default_tt;
|
||||
struct transition {
|
||||
bool just_started;
|
||||
u8_t tt;
|
||||
u8_t rt;
|
||||
u8_t delay;
|
||||
u32_t quo_tt;
|
||||
u32_t counter;
|
||||
u32_t total_duration;
|
||||
s64_t start_timestamp;
|
||||
|
||||
extern struct ble_npl_callout onoff_transition_timer;
|
||||
extern struct ble_npl_callout level_lightness_transition_timer;
|
||||
extern struct ble_npl_callout level_temp_transition_timer;
|
||||
extern struct ble_npl_callout light_lightness_actual_transition_timer;
|
||||
extern struct ble_npl_callout light_lightness_linear_transition_timer;
|
||||
extern struct ble_npl_callout light_ctl_transition_timer;
|
||||
extern struct ble_npl_callout light_ctl_temp_transition_timer;
|
||||
struct ble_npl_callout timer;
|
||||
};
|
||||
|
||||
void onoff_tt_values(struct generic_onoff_state *state);
|
||||
void level_tt_values(struct generic_level_state *state);
|
||||
void delta_level_tt_values(struct generic_level_state *state);
|
||||
void move_level_tt_values(struct generic_level_state *state);
|
||||
void light_lightnes_actual_tt_values(struct light_lightness_state *state);
|
||||
void light_lightnes_linear_tt_values(struct light_lightness_state *state);
|
||||
void light_ctl_tt_values(struct light_ctl_state *state);
|
||||
void light_ctl_temp_tt_values(struct light_ctl_state *state);
|
||||
extern u8_t transition_type, default_tt;
|
||||
extern u32_t *ptr_counter;
|
||||
extern struct ble_npl_callout *ptr_timer;
|
||||
|
||||
extern struct transition lightness_transition, temp_transition;
|
||||
|
||||
extern struct ble_npl_callout dummy_timer;
|
||||
|
||||
void calculate_rt(struct transition *transition);
|
||||
|
||||
|
||||
void onoff_tt_values(struct generic_onoff_state *state, u8_t tt, u8_t delay);
|
||||
void level_tt_values(struct generic_level_state *state, u8_t tt, u8_t delay);
|
||||
void light_lightness_actual_tt_values(struct light_lightness_state *state,
|
||||
u8_t tt, u8_t delay);
|
||||
void light_lightness_linear_tt_values(struct light_lightness_state *state,
|
||||
u8_t tt, u8_t delay);
|
||||
void light_ctl_tt_values(struct light_ctl_state *state, u8_t tt, u8_t delay);
|
||||
void light_ctl_temp_tt_values(struct light_ctl_state *state,
|
||||
u8_t tt, u8_t delay);
|
||||
|
||||
void onoff_handler(struct generic_onoff_state *state);
|
||||
void level_lightness_handler(struct generic_level_state *state);
|
||||
|
||||
@@ -21,7 +21,7 @@ syscfg.vals:
|
||||
LOG_LEVEL: 1
|
||||
|
||||
# Default task settings
|
||||
OS_MAIN_STACK_SIZE: 768
|
||||
OS_MAIN_STACK_SIZE: 4096
|
||||
|
||||
# Newtmgr is not supported in this app, so disable newtmgr-over-shell.
|
||||
SHELL_NEWTMGR: 0
|
||||
@@ -31,14 +31,33 @@ syscfg.vals:
|
||||
FLOAT_USER: 1
|
||||
HARD_FLOAT: 1
|
||||
|
||||
BLE_MESH_ADV_BUF_COUNT: 20
|
||||
BLE_MESH_TX_SEG_MAX: 9
|
||||
BLE_MESH_DEV_UUID: "((uint8_t[16]){0xdd, 0xdd, 0})"
|
||||
BLE_MESH_ADV_BUF_COUNT: 60
|
||||
BLE_MESH_TX_SEG_MAX: 6
|
||||
BLE_MESH_TX_SEG_MSG_COUNT: 3
|
||||
BLE_MESH_RX_SEG_MSG_COUNT: 3
|
||||
BLE_MESH_CRPL: 128
|
||||
BLE_MESH_RPL_STORE_TIMEOUT: 120
|
||||
BLE_MESH_MSG_CACHE_SIZE: 100
|
||||
|
||||
BLE_MESH_SETTINGS: 1
|
||||
CONFIG_FCB: 1
|
||||
|
||||
BLE_MESH: 1
|
||||
BLE_MESH_CFG_CLI: 1
|
||||
BLE_MESH_DEV_UUID: "((uint8_t[16]){0xdd, 0xdd, 0})"
|
||||
BLE_MESH_SETTINGS: 0
|
||||
CONFIG_NFFS: 0
|
||||
BLE_MESH_RELAY: 1
|
||||
BLE_MESH_LOW_POWER: 0
|
||||
BLE_MESH_LPN_AUTO: 0
|
||||
BLE_MESH_FRIEND: 0
|
||||
|
||||
BLE_MESH_PROV: 1
|
||||
BLE_MESH_PB_ADV: 1
|
||||
BLE_MESH_PB_GATT: 1
|
||||
BLE_MESH_GATT_PROXY: 1
|
||||
|
||||
BLE_MESH_SUBNET_COUNT: 2
|
||||
BLE_MESH_APP_KEY_COUNT: 2
|
||||
BLE_MESH_MODEL_GROUP_COUNT: 2
|
||||
BLE_MESH_LABEL_COUNT: 3
|
||||
|
||||
BLE_MESH_DEBUG: 0
|
||||
BLE_MESH_DEBUG_NET: 0
|
||||
|
||||
Reference in New Issue
Block a user