From 00cd491ffe4dab2c7d2f4759bfb1ce5100c52f99 Mon Sep 17 00:00:00 2001 From: Vikrant More Date: Thu, 12 Jul 2018 16:08:02 +0530 Subject: [PATCH] samples: mesh: boards: nrf52: modifications as per 3.3.2.2.3 Added extra case under state binding's switch statement for Lightness i.e DELTA_LEVEL. Also upgrade binding between 1. root element's LEVEL state & Light Lightness Actual state. 2. Light Lightness Linear state & Light Lightness Actual state. 3. Light CTL lightness state & Light Lightness Actual state This is as per Bluetooth Mesh Model Specification 3.3.2.2.3. Signed-off-by: Vikrant More --- .../src/mesh/device_composition.c | 90 +++++++++++++++++-- .../src/mesh/device_composition.h | 12 ++- 2 files changed, 94 insertions(+), 8 deletions(-) diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c index c8122ce31fd..2476650a0dc 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.c @@ -109,6 +109,7 @@ static float sqrt(float square) static void state_binding(u8_t lightness, u8_t temperature) { + u16_t tmp16; float tmp; switch (lightness) { @@ -168,8 +169,19 @@ static void state_binding(u8_t lightness, u8_t temperature) break; case LEVEL: /* Lightness update as per Generic Level (root) state */ - light_lightness_srv_user_data.actual = - gen_level_srv_root_user_data.level + 32768; + /* 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.lightness_range_min) { + tmp16 = + light_lightness_srv_user_data.lightness_range_min; + } else if (tmp16 > + light_lightness_srv_user_data.lightness_range_max) { + tmp16 = + light_lightness_srv_user_data.lightness_range_max; + } + + light_lightness_srv_user_data.actual = tmp16; tmp = ((float) light_lightness_srv_user_data.actual / 65535); light_lightness_srv_user_data.linear = @@ -178,6 +190,41 @@ static void state_binding(u8_t lightness, u8_t temperature) light_lightness_srv_user_data.last = light_lightness_srv_user_data.actual; + gen_level_srv_root_user_data.level = + light_lightness_srv_user_data.actual - 32768; + + light_ctl_srv_user_data.lightness = + light_lightness_srv_user_data.actual; + 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.lightness_range_min) { + if (gen_level_srv_root_user_data.last_delta < 0) { + tmp16 = 0; + } else { + tmp16 = + light_lightness_srv_user_data.lightness_range_min; + } + } else if (tmp16 > + light_lightness_srv_user_data.lightness_range_max) { + tmp16 = + light_lightness_srv_user_data.lightness_range_max; + } + + light_lightness_srv_user_data.actual = tmp16; + + tmp = ((float) light_lightness_srv_user_data.actual / 65535); + light_lightness_srv_user_data.linear = + (u16_t) (65535 * tmp * tmp); + + light_lightness_srv_user_data.last = + light_lightness_srv_user_data.actual; + + gen_level_srv_root_user_data.level = + light_lightness_srv_user_data.actual - 32768; + light_ctl_srv_user_data.lightness = light_lightness_srv_user_data.actual; break; @@ -196,11 +243,26 @@ static void state_binding(u8_t lightness, u8_t temperature) light_lightness_srv_user_data.actual; break; case LINEAR: /* Lightness update as per Light Lightness Linear state */ - light_lightness_srv_user_data.actual = - (u16_t) 65535 * + tmp16 = (u16_t) 65535 * sqrt(((float) light_lightness_srv_user_data.linear / 65535)); + if (tmp16 > 0 && tmp16 < + light_lightness_srv_user_data.lightness_range_min) { + tmp16 = + light_lightness_srv_user_data.lightness_range_min; + } else if (tmp16 > + light_lightness_srv_user_data.lightness_range_max) { + tmp16 = + light_lightness_srv_user_data.lightness_range_max; + } + + light_lightness_srv_user_data.actual = tmp16; + + tmp = ((float) light_lightness_srv_user_data.actual / 65535); + light_lightness_srv_user_data.linear = + (u16_t) (65535 * tmp * tmp); + light_lightness_srv_user_data.last = light_lightness_srv_user_data.actual; @@ -211,8 +273,19 @@ static void state_binding(u8_t lightness, u8_t temperature) light_lightness_srv_user_data.actual; break; case CTL: /* Lightness update as per Light CTL Lightness state */ - light_lightness_srv_user_data.actual = - light_ctl_srv_user_data.lightness; + tmp16 = light_ctl_srv_user_data.lightness; + + if (tmp16 > 0 && tmp16 < + light_lightness_srv_user_data.lightness_range_min) { + tmp16 = + light_lightness_srv_user_data.lightness_range_min; + } else if (tmp16 > + light_lightness_srv_user_data.lightness_range_max) { + tmp16 = + light_lightness_srv_user_data.lightness_range_max; + } + + light_lightness_srv_user_data.actual = tmp16; tmp = ((float) light_lightness_srv_user_data.actual / 65535); light_lightness_srv_user_data.linear = @@ -223,6 +296,9 @@ static void state_binding(u8_t lightness, u8_t temperature) gen_level_srv_root_user_data.level = light_lightness_srv_user_data.actual - 32768; + + light_ctl_srv_user_data.lightness = + light_lightness_srv_user_data.actual; break; default: goto update_temp; @@ -515,7 +591,7 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ - state_binding(LEVEL, IGNORE_TEMP); + state_binding(DELTA_LEVEL, IGNORE_TEMP); update_light_state(); } else if (bt_mesh_model_elem(model)->addr == elements[1].addr) { /* Secondary element */ diff --git a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.h b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.h index 071d3d81aa3..ee055e37512 100644 --- a/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.h +++ b/samples/boards/nrf52/mesh/onoff_level_lighting_vnd_app/src/mesh/device_composition.h @@ -26,7 +26,17 @@ #define CANNOT_SET_RANGE_MIN 0x01 #define CANNOT_SET_RANGE_MAX 0x02 -enum lightness { ONPOWERUP = 0x01, ONOFF, LEVEL, ACTUAL, LINEAR, CTL, IGNORE }; +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 {