/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "syscfg/syscfg.h" #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) #include "mesh/mesh.h" #include "bsp.h" #include "pwm/pwm.h" #include "light_model.h" #include "ws2812.h" #if (!MYNEWT_VAL(USE_NEOPIXEL)) #if MYNEWT_VAL(PWM_0) struct pwm_dev *pwm0; #endif #if MYNEWT_VAL(PWM_1) struct pwm_dev *pwm1; #endif #if MYNEWT_VAL(PWM_2) struct pwm_dev *pwm2; #endif #if MYNEWT_VAL(PWM_3) struct pwm_dev *pwm3; #endif static uint16_t top_val; #endif #if (MYNEWT_VAL(USE_NEOPIXEL)) static uint32_t neopixel[WS2812_NUM_LED]; #endif static u8_t gen_onoff_state; static s16_t gen_level_state; static void light_set_lightness(u8_t percentage) { #if (!MYNEWT_VAL(USE_NEOPIXEL)) int rc; uint16_t pwm_val = (uint16_t) (percentage * top_val / 100); #if MYNEWT_VAL(PWM_0) rc = pwm_set_duty_cycle(pwm0, 0, pwm_val); assert(rc == 0); #endif #if MYNEWT_VAL(PWM_1) rc = pwm_set_duty_cycle(pwm1, 0, pwm_val); assert(rc == 0); #endif #if MYNEWT_VAL(PWM_2) rc = pwm_set_duty_cycle(pwm2, 0, pwm_val); assert(rc == 0); #endif #if MYNEWT_VAL(PWM_3) rc = pwm_set_duty_cycle(pwm3, 0, pwm_val); assert(rc == 0); #endif #else int i; u32_t lightness; u8_t max_lightness = 0x1f; lightness = (u8_t) (percentage * max_lightness / 100); for (i = 0; i < WS2812_NUM_LED; i++) { neopixel[i] = (lightness | lightness << 8 | lightness << 16); } ws2812_write(neopixel); #endif } static void update_light_state(void) { u16_t level = (u16_t)gen_level_state; int percent = 100 * level / 0xffff; if (gen_onoff_state == 0) { percent = 0; } light_set_lightness((uint8_t) percent); } int light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state) { *state = gen_onoff_state; return 0; } int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state) { gen_onoff_state = state; update_light_state(); return 0; } int light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level) { *level = gen_level_state; return 0; } int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level) { gen_level_state = level; if ((u16_t)gen_level_state > 0x0000) { gen_onoff_state = 1; } if ((u16_t)gen_level_state == 0x0000) { gen_onoff_state = 0; } update_light_state(); return 0; } int light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness) { return light_model_gen_level_get(model, lightness); } int light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness) { return light_model_gen_level_set(model, lightness); } #if (!MYNEWT_VAL(USE_NEOPIXEL)) struct pwm_dev_cfg dev_conf = { .n_cycles = 0, .int_prio = 3, }; #if MYNEWT_VAL(PWM_0) static struct pwm_chan_cfg led1_conf = { .pin = LED_1, .inverted = true, }; #endif #if MYNEWT_VAL(PWM_1) static struct pwm_chan_cfg led2_conf = { .pin = LED_2, .inverted = true, }; #endif #if MYNEWT_VAL(PWM_2) static struct pwm_chan_cfg led3_conf = { .pin = LED_3, .inverted = true, }; #endif #endif #if MYNEWT_VAL(PWM_3) static struct pwm_chan_cfg led4_conf = { .pin = LED_4, .inverted = true, }; #endif #if (!MYNEWT_VAL(USE_NEOPIXEL)) void init_pwm_dev(struct pwm_dev **pwm, char *dev_name, struct pwm_chan_cfg *chan_cfg) { int rc = 0; *pwm = (struct pwm_dev *) os_dev_open(dev_name, 0, NULL); assert(pwm); rc = pwm_configure_device(*pwm, &dev_conf); assert(rc == 0); rc = pwm_configure_channel(*pwm, 0, chan_cfg); assert(rc == 0); rc = pwm_enable(*pwm); assert(rc == 0); } int pwm_init(void) { #if MYNEWT_VAL(PWM_0) init_pwm_dev(&pwm0, "pwm0", &led1_conf); #endif #if MYNEWT_VAL(PWM_1) init_pwm_dev(&pwm1, "pwm1", &led2_conf); #endif #if MYNEWT_VAL(PWM_2) init_pwm_dev(&pwm2, "pwm2", &led3_conf); #endif #if MYNEWT_VAL(PWM_3) init_pwm_dev(&pwm3, "pwm3", &led4_conf); #endif if (!pwm0) { return 0; } top_val = (uint16_t) pwm_get_top_value(pwm0); update_light_state(); return 0; } #endif #endif int light_model_init(void) { #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) int rc; #if (!MYNEWT_VAL(USE_NEOPIXEL)) rc = pwm_init(); assert(rc == 0); #else rc = ws2812_init(); assert(rc == 0); update_light_state(); #endif return rc; #else return 0; #endif }