mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
feat: replace lightdriver, and support more chips in ble mesh examples
This commit is contained in:
@@ -23,6 +23,7 @@ menu "AliGenie Example Configuration"
|
||||
menu "light driver config"
|
||||
config LIGHT_GPIO_RED
|
||||
int "Light red pin GPIO number"
|
||||
range -1 48 if IDF_TARGET_ESP32S3
|
||||
range -1 33
|
||||
default 25
|
||||
help
|
||||
@@ -33,6 +34,7 @@ menu "AliGenie Example Configuration"
|
||||
|
||||
config LIGHT_GPIO_GREEN
|
||||
int "Light green pin GPIO number"
|
||||
range -1 48 if IDF_TARGET_ESP32S3
|
||||
range -1 33
|
||||
default 26
|
||||
help
|
||||
@@ -43,6 +45,7 @@ menu "AliGenie Example Configuration"
|
||||
|
||||
config LIGHT_GPIO_BLUE
|
||||
int "Light blue pin GPIO number"
|
||||
range -1 48 if IDF_TARGET_ESP32S3
|
||||
range -1 33
|
||||
default 27
|
||||
help
|
||||
@@ -53,6 +56,7 @@ menu "AliGenie Example Configuration"
|
||||
|
||||
config LIGHT_GPIO_COLD
|
||||
int "Light cold colors pin GPIO number"
|
||||
range -1 48 if IDF_TARGET_ESP32S3
|
||||
range -1 33
|
||||
default -1
|
||||
help
|
||||
@@ -63,6 +67,7 @@ menu "AliGenie Example Configuration"
|
||||
|
||||
config LIGHT_GPIO_WARM
|
||||
int "Light warm color pin GPIO number"
|
||||
range -1 48 if IDF_TARGET_ESP32S3
|
||||
range -1 33
|
||||
default -1
|
||||
help
|
||||
|
@@ -37,6 +37,7 @@ static const char *TAG = "genie_demo";
|
||||
|
||||
#define MESH_ELEM_COUNT 1
|
||||
#define MESH_ELEM_STATE_COUNT MESH_ELEM_COUNT
|
||||
#define LIGHT_STATUS_STORE_KEY "light_status"
|
||||
|
||||
nvs_handle_t NVS_HANDLE;
|
||||
|
||||
@@ -416,12 +417,34 @@ void user_genie_event_handle(genie_event_t event, void *p_arg)
|
||||
switch (event) {
|
||||
case GENIE_EVT_RESET_BY_REPEAT_NOTIFY:
|
||||
ESP_LOGI(TAG, "GENIE_EVT_RESET_BY_REPEAT_NOTIFY");
|
||||
light_driver_breath_start(0, 255, 0); /**< green blink */
|
||||
lightbulb_set_switch(false);
|
||||
lightbulb_effect_config_t effect1 = {
|
||||
.red = 0,
|
||||
.green = 255,
|
||||
.blue = 0,
|
||||
.max_brightness = 100,
|
||||
.min_brightness = 0,
|
||||
.effect_cycle_ms = CONFIG_LIGHT_BLINK_PERIOD_MS,
|
||||
.effect_type = EFFECT_BLINK,
|
||||
.mode = WORK_COLOR,
|
||||
};
|
||||
lightbulb_basic_effect_start(&effect1); /**< green blink */
|
||||
break;
|
||||
case GENIE_EVT_SW_RESET:
|
||||
case GENIE_EVT_HW_RESET_START:
|
||||
ESP_LOGI(TAG, "GENIE_EVT_HW_RESET_START");
|
||||
light_driver_breath_start(0, 255, 0); /**< green blink */
|
||||
lightbulb_set_switch(false);
|
||||
lightbulb_effect_config_t effect2 = {
|
||||
.red = 0,
|
||||
.green = 255,
|
||||
.blue = 0,
|
||||
.max_brightness = 100,
|
||||
.min_brightness = 0,
|
||||
.effect_cycle_ms = CONFIG_LIGHT_BLINK_PERIOD_MS,
|
||||
.effect_type = EFFECT_BLINK,
|
||||
.mode = WORK_COLOR,
|
||||
};
|
||||
lightbulb_basic_effect_start(&effect2); /**< green blink */
|
||||
ble_mesh_nvs_erase(NVS_HANDLE, LIGHT_STATUS_STORE_KEY); // erase led status
|
||||
reset_light_para();
|
||||
break;
|
||||
@@ -442,7 +465,7 @@ void user_genie_event_handle(genie_event_t event, void *p_arg)
|
||||
g_indication_flag |= INDICATION_FLAG_CTL;
|
||||
#endif
|
||||
ESP_LOGI(TAG, "light_driver_breath_stop %s", __FUNCTION__);
|
||||
light_driver_breath_stop();
|
||||
lightbulb_basic_effect_stop();
|
||||
// update led status
|
||||
genie_event(GENIE_EVT_SDK_ANALYZE_MSG, &g_elem_state[0]);
|
||||
break;
|
||||
@@ -1290,7 +1313,18 @@ static esp_err_t ble_mesh_init(void)
|
||||
ESP_LOGW(TAG, "node already provisioned");
|
||||
} else {
|
||||
ESP_LOGW(TAG, "node not provisioned");
|
||||
light_driver_breath_start(0, 255, 0); /**< green blink */
|
||||
lightbulb_set_switch(false);
|
||||
lightbulb_effect_config_t effect3 = {
|
||||
.red = 0,
|
||||
.green = 255,
|
||||
.blue = 0,
|
||||
.max_brightness = 100,
|
||||
.min_brightness = 0,
|
||||
.effect_cycle_ms = CONFIG_LIGHT_BLINK_PERIOD_MS,
|
||||
.effect_type = EFFECT_BLINK,
|
||||
.mode = WORK_COLOR,
|
||||
};
|
||||
lightbulb_basic_effect_start(&effect3); /**< green blink */
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@@ -13,11 +13,15 @@
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "iot_button.h"
|
||||
#include "light_driver.h"
|
||||
#include "lightbulb.h"
|
||||
|
||||
#include "genie_event.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#define BUTTON_ON_OFF 9 /* on/off button */
|
||||
#else
|
||||
#define BUTTON_ON_OFF 0 /* on/off button */
|
||||
#endif
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
|
||||
static const char *TAG = "board";
|
||||
@@ -38,22 +42,37 @@ static void board_led_init(void)
|
||||
* If the module has SPI flash, GPIOs 6-11 are connected to the module’s integrated SPI flash and PSRAM.
|
||||
* If the module has PSRAM, GPIOs 16 and 17 are connected to the module’s integrated PSRAM.
|
||||
*/
|
||||
light_driver_config_t driver_config = {
|
||||
.gpio_red = CONFIG_LIGHT_GPIO_RED,
|
||||
.gpio_green = CONFIG_LIGHT_GPIO_GREEN,
|
||||
.gpio_blue = CONFIG_LIGHT_GPIO_BLUE,
|
||||
.gpio_cold = CONFIG_LIGHT_GPIO_COLD,
|
||||
.gpio_warm = CONFIG_LIGHT_GPIO_WARM,
|
||||
.fade_period_ms = CONFIG_LIGHT_FADE_PERIOD_MS,
|
||||
.blink_period_ms = CONFIG_LIGHT_BLINK_PERIOD_MS,
|
||||
lightbulb_config_t config = {
|
||||
.type = DRIVER_ESP_PWM,
|
||||
.driver_conf.pwm.freq_hz = 4000,
|
||||
.capability.enable_fades = true,
|
||||
.capability.fades_ms = CONFIG_LIGHT_FADE_PERIOD_MS,
|
||||
.capability.enable_lowpower = false,
|
||||
.capability.enable_mix_cct = false,
|
||||
.capability.enable_status_storage = false,
|
||||
.capability.mode_mask = COLOR_MODE,
|
||||
.capability.storage_cb = NULL,
|
||||
.capability.sync_change_brightness_value = true,
|
||||
.io_conf.pwm_io.red = CONFIG_LIGHT_GPIO_RED,
|
||||
.io_conf.pwm_io.green = CONFIG_LIGHT_GPIO_GREEN,
|
||||
.io_conf.pwm_io.blue = CONFIG_LIGHT_GPIO_BLUE,
|
||||
.io_conf.pwm_io.cold_cct = CONFIG_LIGHT_GPIO_COLD,
|
||||
.io_conf.pwm_io.warm_brightness = CONFIG_LIGHT_GPIO_WARM,
|
||||
.external_limit = NULL,
|
||||
.gamma_conf = NULL,
|
||||
.init_status.mode = WORK_COLOR,
|
||||
.init_status.on = true,
|
||||
.init_status.hue = 0,
|
||||
.init_status.saturation = 100,
|
||||
.init_status.value = 100,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Light driver initialization
|
||||
*/
|
||||
ESP_ERROR_CHECK(light_driver_init(&driver_config));
|
||||
light_driver_set_mode(MODE_HSL);
|
||||
// light_driver_set_switch(true);
|
||||
ESP_ERROR_CHECK(lightbulb_init(&config));
|
||||
vTaskDelay(pdMS_TO_TICKS(1000) * 1);
|
||||
lightbulb_set_switch(true);
|
||||
|
||||
button_handle_t dev_on_off_btn = iot_button_create(BUTTON_ON_OFF, BUTTON_ACTIVE_LEVEL);
|
||||
iot_button_set_evt_cb(dev_on_off_btn, BUTTON_CB_TAP, button_tap_cb, &dev_on_btn_num);
|
||||
@@ -64,6 +83,62 @@ void board_init(void)
|
||||
board_led_init();
|
||||
}
|
||||
|
||||
static esp_err_t board_led_hsl2rgb(uint16_t hue, uint8_t saturation, uint8_t lightness,
|
||||
uint8_t *red, uint8_t *green, uint8_t *blue)
|
||||
{
|
||||
uint16_t hi = (hue / 60) % 6;
|
||||
uint16_t C = (100 - abs(2 * lightness - 100)) * saturation / 100;
|
||||
uint16_t M = 100 * (lightness - 0.5 * C) / 100;
|
||||
uint16_t X = C * (100 - abs((hue * 100 / 60 ) % 200 - 100)) / 100;
|
||||
|
||||
switch (hi) {
|
||||
case 0: /* hue 0~60 */
|
||||
*red = C + M;
|
||||
*green = X + M;
|
||||
*blue = M;
|
||||
break;
|
||||
|
||||
case 1: /* hue 60~120 */
|
||||
*red = X + M;
|
||||
*green = C + M;
|
||||
*blue = M;
|
||||
break;
|
||||
|
||||
case 2: /* hue 120~180 */
|
||||
*red = M;
|
||||
*green = C + M;
|
||||
*blue = X + M;
|
||||
break;
|
||||
|
||||
case 3: /* hue 180~240 */
|
||||
*red = M;
|
||||
*green = X + M;
|
||||
*blue = C + M;
|
||||
break;
|
||||
|
||||
case 4: /* hue 240~300 */
|
||||
*red = X + M;
|
||||
*green = M;
|
||||
*blue = C + M;
|
||||
break;
|
||||
|
||||
case 5: /* hue 300~360 */
|
||||
*red = C + M;
|
||||
*green = M;
|
||||
*blue = X + M;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
*red = *red * 255 / 100;
|
||||
*green = *green * 255 / 100;
|
||||
*blue = *blue * 255 / 100;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* hsl
|
||||
*/
|
||||
@@ -86,8 +161,14 @@ void board_led_hsl(uint8_t elem_index, uint16_t hue, uint16_t saturation, uint16
|
||||
uint8_t actual_saturation = (float)last_saturation / (UINT16_MAX / 100.0);
|
||||
uint8_t actual_lightness = (float)last_lightness / (UINT16_MAX / 100.0);
|
||||
|
||||
uint8_t r, g, b;
|
||||
uint16_t h;
|
||||
uint8_t s, v;
|
||||
|
||||
ESP_LOGD(TAG, "hsl: %d, %d, %d operation", actual_hue, actual_saturation, actual_lightness);
|
||||
light_driver_set_hsl(actual_hue, actual_saturation, actual_lightness);
|
||||
board_led_hsl2rgb(actual_hue, actual_saturation, actual_lightness, &r, &g, &b);
|
||||
lightbulb_rgb2hsv(r, g, b, &h, &s, &v);
|
||||
lightbulb_set_hsv(h, s, v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +186,7 @@ void board_led_temperature(uint8_t elem_index, uint16_t temperature)
|
||||
|
||||
uint16_t actual_temperature = (float)last_temperature / (UINT16_MAX / 100.0);
|
||||
ESP_LOGD(TAG, "temperature %d %%%d operation", last_temperature, actual_temperature);
|
||||
light_driver_set_color_temperature(actual_temperature);
|
||||
lightbulb_set_cct(actual_temperature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +204,7 @@ void board_led_lightness(uint8_t elem_index, uint16_t actual)
|
||||
|
||||
uint16_t actual_lightness = (float)last_acual / (UINT16_MAX / 100.0);
|
||||
ESP_LOGD(TAG, "lightness %d %%%d operation", last_acual, actual_lightness);
|
||||
light_driver_set_lightness(actual_lightness);
|
||||
lightbulb_set_brightness(actual_lightness);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,10 +220,10 @@ void board_led_switch(uint8_t elem_index, uint8_t onoff)
|
||||
last_onoff = onoff;
|
||||
if (last_onoff) {
|
||||
ESP_LOGD(TAG, "onoff %d operation", last_onoff);
|
||||
light_driver_set_switch(true);
|
||||
lightbulb_set_switch(true);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "onoff %d operation", last_onoff);
|
||||
light_driver_set_switch(false);
|
||||
lightbulb_set_switch(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ extern "C" {
|
||||
#endif /**< __cplusplus */
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "light_driver.h"
|
||||
#include "lightbulb.h"
|
||||
|
||||
#define LED_ON 1
|
||||
#define LED_OFF 0
|
||||
|
@@ -35,3 +35,9 @@ CONFIG_BLE_MESH_MODEL_KEY_COUNT=5
|
||||
CONFIG_BLE_MESH_MODEL_GROUP_COUNT=5
|
||||
CONFIG_BLE_MESH_MSG_CACHE_SIZE=20
|
||||
CONFIG_BLE_MESH_ADV_BUF_COUNT=256
|
||||
|
||||
#
|
||||
# light driver config
|
||||
#
|
||||
CONFIG_PWM_ENABLE_HW_FADE=n
|
||||
# end of light driver config
|
||||
|
@@ -1,15 +1,3 @@
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
|
||||
#
|
||||
# Serial flasher config
|
||||
#
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
||||
|
||||
# Override some defaults so BT stack is enabled
|
||||
# by default in this example
|
||||
CONFIG_BT_ENABLED=y
|
||||
@@ -18,20 +6,8 @@ CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN=y
|
||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y
|
||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4512
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
|
||||
# Override some defaults of ESP BLE Mesh
|
||||
CONFIG_BLE_MESH=y
|
||||
CONFIG_BLE_MESH_NODE=y
|
||||
CONFIG_BLE_MESH_PB_GATT=y
|
||||
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=10
|
||||
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=10
|
||||
CONFIG_BLE_MESH_SETTINGS=y
|
||||
CONFIG_BLE_MESH_SUBNET_COUNT=5
|
||||
CONFIG_BLE_MESH_APP_KEY_COUNT=5
|
||||
CONFIG_BLE_MESH_MODEL_KEY_COUNT=5
|
||||
CONFIG_BLE_MESH_MODEL_GROUP_COUNT=5
|
||||
CONFIG_BLE_MESH_MSG_CACHE_SIZE=20
|
||||
CONFIG_BLE_MESH_ADV_BUF_COUNT=256
|
||||
CONFIG_BT_BLE_50_FEATURES_SUPPORTED=n
|
||||
CONFIG_BT_LE_50_FEATURE_SUPPORT=n
|
||||
|
||||
#
|
||||
# light driver config
|
||||
|
@@ -0,0 +1,19 @@
|
||||
# Override some defaults so BT stack is enabled
|
||||
# by default in this example
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE=y
|
||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y
|
||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4512
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
CONFIG_BT_BLE_50_FEATURES_SUPPORTED=n
|
||||
CONFIG_BT_LE_50_FEATURE_SUPPORT=n
|
||||
|
||||
#
|
||||
# light driver config
|
||||
#
|
||||
CONFIG_LIGHT_GPIO_RED=4
|
||||
CONFIG_LIGHT_GPIO_GREEN=5
|
||||
CONFIG_LIGHT_GPIO_BLUE=6
|
||||
CONFIG_LIGHT_GPIO_COLD=7
|
||||
CONFIG_LIGHT_GPIO_WARM=10
|
||||
# end of light driver config
|
@@ -0,0 +1,19 @@
|
||||
# Override some defaults so BT stack is enabled
|
||||
# by default in this example
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE=y
|
||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y
|
||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4512
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
CONFIG_BT_BLE_50_FEATURES_SUPPORTED=n
|
||||
CONFIG_BT_LE_50_FEATURE_SUPPORT=n
|
||||
|
||||
#
|
||||
# light driver config
|
||||
#
|
||||
CONFIG_LIGHT_GPIO_RED=4
|
||||
CONFIG_LIGHT_GPIO_GREEN=5
|
||||
CONFIG_LIGHT_GPIO_BLUE=11
|
||||
CONFIG_LIGHT_GPIO_COLD=12
|
||||
CONFIG_LIGHT_GPIO_WARM=10
|
||||
# end of light driver config
|
@@ -0,0 +1,21 @@
|
||||
# Override some defaults so BT stack is enabled
|
||||
# by default in this example
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
|
||||
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
|
||||
CONFIG_BTDM_CTRL_MODE_BTDM=n
|
||||
CONFIG_CTRL_BTDM_MODEM_SLEEP=n
|
||||
CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE=y
|
||||
CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN=y
|
||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y
|
||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4512
|
||||
|
||||
#
|
||||
# light driver config
|
||||
#
|
||||
CONFIG_LIGHT_GPIO_RED=14
|
||||
CONFIG_LIGHT_GPIO_GREEN=13
|
||||
CONFIG_LIGHT_GPIO_BLUE=12
|
||||
CONFIG_LIGHT_GPIO_COLD=11
|
||||
CONFIG_LIGHT_GPIO_WARM=10
|
||||
# end of light driver config
|
@@ -1,10 +1,5 @@
|
||||
|
||||
set(COMPONENT_SRCS "light_driver.c"
|
||||
"iot_led.c")
|
||||
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ". include")
|
||||
|
||||
# requirements can't depend on config
|
||||
set(COMPONENT_REQUIRES example_nvs driver)
|
||||
set(COMPONENT_REQUIRES example_nvs driver lightbulb_driver)
|
||||
|
||||
register_component()
|
||||
|
@@ -1,22 +1,3 @@
|
||||
# Component: Light
|
||||
# Source
|
||||
|
||||
* This component defines a light as a well encapsulated object.
|
||||
* A light device is defined by:
|
||||
* ledc timer which is used to control the pwm channels of light
|
||||
* mode of the ledc timer
|
||||
* frequency of the ledc timer
|
||||
* pwm channel number of the light
|
||||
* bit number of the ledc timer
|
||||
* A light device can provide:
|
||||
* iot_light_channel_regist function to add channel to corresponding channel id
|
||||
* iot_light_duty_write function to set the duty of corresponding channel and it support setting duty directly or gradually
|
||||
* iot_light_breath_write function to set the corresponding channel to breath mode and breath period can be set
|
||||
* iot_light_blink_starte and iot_light_blink_stop function to make some of channels to blink in appointed period. Note that if any channel works in blink mode, all the other channels would be turned off.
|
||||
|
||||
* To use the light device, you need to:
|
||||
* create a light object returned by iot_light_create()
|
||||
* regist the light channels according the channel number by iot_light_channel_regist()
|
||||
* To free the object, you can call iot_light_delete to delete the button object and free the memory.
|
||||
|
||||
### NOTE:
|
||||
> If any channel(s) work(s) in blink mode, all the other channels would be turned off. iot_light_blink_stop() must be called before setting any channel to other mode(write duty or breath).
|
||||
The `light_driver` component is taken from https://github.com/espressif/esp-iot-solution/tree/master/components/led/lightbulb_driver via idf_component.yml
|
@@ -0,0 +1,3 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/lightbulb_driver: "==0.5.5"
|
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __IOT_LED_H__
|
||||
#define __IOT_LED_H__
|
||||
|
||||
#include "driver/ledc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GAMMA_CORRECTION 0.8 /**< Gamma curve parameter */
|
||||
#define GAMMA_TABLE_SIZE 256 /**< Gamma table size, used for led fade*/
|
||||
#define DUTY_SET_CYCLE (20) /**< Set duty cycle */
|
||||
|
||||
/**
|
||||
* Macro which can be used to check the error code,
|
||||
* and terminate the program in case the code is not ESP_OK.
|
||||
* Prints the error code, error location, and the failed statement to serial output.
|
||||
*
|
||||
* Disabled if assertions are disabled.
|
||||
*/
|
||||
#define LIGHT_ERROR_CHECK(con, err, format, ...) do { \
|
||||
if (con) { \
|
||||
if(*format != '\0') \
|
||||
ESP_LOGW(TAG, "<%s> " format, esp_err_to_name(err), ##__VA_ARGS__); \
|
||||
return err; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define LIGHT_PARAM_CHECK(con) do { \
|
||||
if (!(con)) { \
|
||||
ESP_LOGE(TAG, "<ESP_ERR_INVALID_ARG> !(%s)", #con); \
|
||||
return ESP_ERR_INVALID_ARG; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Initialize and set the ledc timer for the iot led
|
||||
*
|
||||
* @param timer_num The timer index of ledc timer group used for iot led
|
||||
* This parameter can be one of LEDC_TIMER_x where x can be (0 .. 3)
|
||||
*
|
||||
* @param speed_mode speed mode of ledc timer
|
||||
* This parameter can be one of LEDC_x_SPEED_MODE where x can be (LOW, HIGH)
|
||||
*
|
||||
* @param freq_hz frequency of ledc timer
|
||||
* This parameter must be less than 5000
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if sucess
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_FAIL Can not find a proper pre-divider number base on the given frequency
|
||||
* and the current duty_resolution.
|
||||
*/
|
||||
esp_err_t iot_led_init(ledc_timer_t timer_num, ledc_mode_t speed_mode, uint32_t freq_hz);
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the iot led and free resource
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if sucess
|
||||
*/
|
||||
esp_err_t iot_led_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Set the ledc channel used by iot led and associate the gpio port used
|
||||
* for output
|
||||
*
|
||||
* @param channel The ledc channel
|
||||
* This parameter can be LEDC_CHANNEL_x where x can be (0 .. 15)
|
||||
* @param gpio_num the ledc output gpio_num
|
||||
* This parameter can be GPIO_NUM_x where x can be (0, 33)
|
||||
*
|
||||
* @note If the operation of esp32 depends on SPI FLASH or PSRAM, then these related
|
||||
* pins should not be set to output.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if sucess
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t iot_led_regist_channel(ledc_channel_t channel, gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Returns the channel value
|
||||
* @note before calling this function, you need to call iot_led_regist_channel() to
|
||||
* set the channel
|
||||
*
|
||||
* @param channel The ledc channel
|
||||
* This parameter can be LEDC_CHANNEL_x where x can be (0 .. 15)
|
||||
* @param dst The address where the channel value is stored
|
||||
* @return
|
||||
* - ESP_OK if sucess
|
||||
* - ESP_ERR_INVALID_ARG if dst is NULL
|
||||
*/
|
||||
esp_err_t iot_led_get_channel(ledc_channel_t channel, uint8_t *dst);
|
||||
|
||||
/**
|
||||
* @brief Set the fade state for the specified channel
|
||||
* @note before calling this function, you need to call iot_led_regist_channel() to
|
||||
* set the channel
|
||||
*
|
||||
* @param channel The ledc channel
|
||||
* This parameter can be LEDC_CHANNEL_x where x can be (0 .. 15)
|
||||
* @param value The target output brightness of iot led
|
||||
* This parameter can be (0 .. 255)
|
||||
* @param fade_ms The time from the current value to the target value
|
||||
* @return
|
||||
* - ESP_OK if sucess
|
||||
*/
|
||||
esp_err_t iot_led_set_channel(ledc_channel_t channel, uint8_t value, uint32_t fade_ms);
|
||||
|
||||
/**
|
||||
* @brief Set the blink state or loop fade for the specified channel
|
||||
* @note before calling this function, you need to call iot_led_regist_channel() to
|
||||
* set the channel
|
||||
*
|
||||
* @param channel The ledc channel
|
||||
* This parameter can be LEDC_CHANNEL_x where x can be (0 .. 15)
|
||||
* @param value The output brightness of iot led
|
||||
* This parameter can be (0 .. 255)
|
||||
* @param period_ms Blink cycle
|
||||
* @param fade_flag select loop fade or blink
|
||||
* 1 for loop fade
|
||||
* 0 for blink
|
||||
* @return
|
||||
* - ESP_OK if sucess
|
||||
*/
|
||||
esp_err_t iot_led_start_blink(ledc_channel_t channel, uint8_t value, uint32_t period_ms, bool fade_flag);
|
||||
|
||||
/**
|
||||
* @brief Stop the blink state or loop fade for the specified channel
|
||||
*
|
||||
* @param channel The ledc channel
|
||||
* This parameter can be LEDC_CHANNEL_x where x can be (0 .. 15)
|
||||
* @return
|
||||
* - ESP_OK if sucess
|
||||
*/
|
||||
esp_err_t iot_led_stop_blink(ledc_channel_t channel);
|
||||
|
||||
/**
|
||||
* @brief Set the specified gamma_table to control the fade effect, usually
|
||||
* no need to set
|
||||
*
|
||||
* @param gamma_table[GAMMA_TABLE_SIZE] Expected gamma table value
|
||||
*
|
||||
* @note Gamma_table is the dimming curve used by the iot_led driver.
|
||||
* The element type is uint16_t. Each element is treated as a binary
|
||||
* fixed-point number. The decimal point is before the eighth bit
|
||||
* and after the ninth bit, so the range of expressions can be
|
||||
* 0x00.00 ~ 0xff.ff.
|
||||
* @note default gamma_table is created in iot_led_init()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if sucess
|
||||
*/
|
||||
esp_err_t iot_led_set_gamma_table(const uint16_t gamma_table[GAMMA_TABLE_SIZE]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /**< __IOT_LED_H__ */
|
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __IOT_LIGHT_H__
|
||||
#define __IOT_LIGHT_H__
|
||||
|
||||
#include "driver/ledc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *light_handle_t;
|
||||
|
||||
#define DUTY_SET_CYCLE (20) /**< Set duty cycle */
|
||||
#define DUTY_SET_GAMMA (0.6) /**< Set the Gamma value for the fade curve, default value is 0.6 */
|
||||
|
||||
#define LIGHT_MAX_CHANNEL_NUM (5)
|
||||
|
||||
/**
|
||||
* @brief light initialize
|
||||
*
|
||||
* @param timer the LEDC timer used by light
|
||||
* @param speed_mode speed mode of LEDC timer
|
||||
* @param freq_hz frequency of LEDC timer
|
||||
* @param channel_num decide how many channels the light contains
|
||||
* @param timer_bit LEDC PWM duty resolution
|
||||
*
|
||||
* @return the handle of light
|
||||
*/
|
||||
light_handle_t iot_light_create(ledc_timer_t timer, ledc_mode_t speed_mode, uint32_t freq_hz, uint8_t channel_num, ledc_timer_bit_t timer_bit);
|
||||
|
||||
/**
|
||||
* @brief add an output channel to light
|
||||
*
|
||||
* @param light_handle light handle
|
||||
* @param channel_idx the id of channel (0 ~ channel_num-1)
|
||||
* @param io_num the IO number use to output LEDC PWM
|
||||
* @param channel the ledc channel you want to use
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: fail
|
||||
*/
|
||||
esp_err_t iot_light_channel_regist(light_handle_t light_handle, uint8_t channel_idx, gpio_num_t io_num, ledc_channel_t channel);
|
||||
|
||||
/**
|
||||
* @brief free the memory of light
|
||||
*
|
||||
* @param light_handle light handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: fail
|
||||
*/
|
||||
esp_err_t iot_light_delete(light_handle_t light_handle);
|
||||
|
||||
/**
|
||||
* @brief get channel duty
|
||||
*
|
||||
* @param light_handle light handle
|
||||
* @param channel_id the id of channel (0 ~ channel_num-1)
|
||||
*
|
||||
* @return
|
||||
* - LEDC_ERR_DUTY if parameter error
|
||||
* - Others Current LEDC duty
|
||||
*/
|
||||
uint32_t iot_light_duty_get(light_handle_t light_handle, uint8_t channel_id);
|
||||
|
||||
/**
|
||||
* @brief set light fade with time. if set fade_period_ms as 0, set the duty directly.
|
||||
*
|
||||
* @param light_handle light handle
|
||||
* @param channel_id the id of channel (0 ~ channel_num-1)
|
||||
* @param duty target duty
|
||||
* @param fade_period_ms fade time (uint: ms)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: fail
|
||||
*/
|
||||
esp_err_t iot_light_fade_with_time(light_handle_t light_handle, uint8_t channel_id, uint32_t duty, uint32_t fade_period_ms);
|
||||
|
||||
/**
|
||||
* @brief set breath config of a light channel, call `iot_light_operate_start` to start breath operation
|
||||
*
|
||||
* @param light_handle light handle
|
||||
* @param channel_id the id of channel (0 ~ channel_num-1)
|
||||
* @param duty the maximum duty when breath
|
||||
* @param breath_period_ms breath period (uint: ms)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: fail
|
||||
*/
|
||||
esp_err_t iot_light_breath_config(light_handle_t light_handle, uint8_t channel_id, uint32_t duty, uint32_t breath_period_ms);
|
||||
|
||||
/**
|
||||
* @brief set blink config of a light channel, call `iot_light_operate_start` to start blink operation
|
||||
*
|
||||
* @param light_handle light handle
|
||||
* @param channel_id the id of channel (0 ~ channel_num-1)
|
||||
* @param blink_period_ms blink period (uint: ms)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: fail
|
||||
*/
|
||||
esp_err_t iot_light_blink_config(light_handle_t light_handle, uint8_t channel_id, uint32_t blink_period_ms);
|
||||
|
||||
/**
|
||||
* @brief start breath or blink operation, user need to set breath or blink config before call this API
|
||||
*
|
||||
* @param light_handle light handle
|
||||
* @param channel_id the id of channel (0 ~ channel_num-1)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: fail
|
||||
*/
|
||||
esp_err_t iot_light_operate_start(light_handle_t light_handle, uint8_t channel_id);
|
||||
|
||||
/**
|
||||
* @brief stop breath or blink operation
|
||||
*
|
||||
* @param light_handle light handle
|
||||
* @param channel_id the id of channel (0 ~ channel_num-1)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: fail
|
||||
*/
|
||||
esp_err_t iot_light_operate_stop(light_handle_t light_handle, uint8_t channel_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /**< __IOT_LIGHT_H__ */
|
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __LIGHT_DRIVER_H__
|
||||
#define __LIGHT_DRIVER_H__
|
||||
|
||||
#include "iot_led.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LIGHT_STATUS_STORE_KEY "light_status"
|
||||
|
||||
/**
|
||||
* @brief The mode of the five-color light
|
||||
*/
|
||||
typedef enum light_mode {
|
||||
MODE_NONE = 0,
|
||||
MODE_RGB = 1,
|
||||
MODE_HSV = 2,
|
||||
MODE_CTB = 3,
|
||||
MODE_ON = 4,
|
||||
MODE_OFF = 5,
|
||||
MODE_HUE_INCREASE = 4,
|
||||
MODE_HUE_DECREASE = 5,
|
||||
MODE_WARM_INCREASE = 6,
|
||||
MODE_WARM_DECREASE = 7,
|
||||
MODE_BRIGHTNESS_INCREASE = 8,
|
||||
MODE_BRIGHTNESS_DECREASE = 9,
|
||||
MODE_HSL = 10,
|
||||
} light_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Light driven configuration
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_num_t gpio_red; /**< Red corresponds to GPIO */
|
||||
gpio_num_t gpio_green; /**< Green corresponds to GPIO */
|
||||
gpio_num_t gpio_blue; /**< Blue corresponds to GPIO */
|
||||
gpio_num_t gpio_cold; /**< Cool corresponds to GPIO */
|
||||
gpio_num_t gpio_warm; /**< Warm corresponds to GPIO */
|
||||
uint32_t fade_period_ms; /**< The time from the current color to the next color */
|
||||
uint32_t blink_period_ms; /**< Period of flashing lights */
|
||||
} light_driver_config_t;
|
||||
|
||||
/**
|
||||
* @brief Light initialize
|
||||
*
|
||||
* @param config [description]
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
*/
|
||||
esp_err_t light_driver_init(light_driver_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Light deinitialize
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
*/
|
||||
esp_err_t light_driver_deinit(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the fade time of the light
|
||||
*
|
||||
* @param fade_period_ms The time from the current color to the next color
|
||||
* @param blink_period_ms Light flashing frequency
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_FAIL
|
||||
*/
|
||||
esp_err_t light_driver_config(uint32_t fade_period_ms, uint32_t blink_period_ms);
|
||||
|
||||
/**@{*/
|
||||
/**
|
||||
* @brief Set the status of the light
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
*/
|
||||
esp_err_t light_driver_set_hue(uint16_t hue);
|
||||
esp_err_t light_driver_set_saturation(uint8_t saturation);
|
||||
esp_err_t light_driver_set_value(uint8_t value);
|
||||
esp_err_t light_driver_set_color_temperature(uint8_t color_temperature);
|
||||
esp_err_t light_driver_set_brightness(uint8_t brightness);
|
||||
esp_err_t light_driver_set_hsv(uint16_t hue, uint8_t saturation, uint8_t value);
|
||||
esp_err_t light_driver_set_hsl(uint16_t hue, uint8_t saturation, uint8_t lightness);
|
||||
esp_err_t light_driver_set_lightness(uint8_t lightness);
|
||||
esp_err_t light_driver_set_ctb(uint8_t color_temperature, uint8_t brightness);
|
||||
esp_err_t light_driver_set_switch(bool status);
|
||||
esp_err_t light_driver_set_mode(light_mode_t mode);
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**@{*/
|
||||
/**
|
||||
* @brief Set the status of the light
|
||||
*/
|
||||
uint16_t light_driver_get_hue(void);
|
||||
uint8_t light_driver_get_saturation(void);
|
||||
uint8_t light_driver_get_value(void);
|
||||
esp_err_t light_driver_get_hsv(uint16_t *hue, uint8_t *saturation, uint8_t *value);
|
||||
uint8_t light_driver_get_lightness(void);
|
||||
esp_err_t light_driver_get_hsl(uint16_t *hue, uint8_t *saturation, uint8_t *lightness);
|
||||
uint8_t light_driver_get_color_temperature(void);
|
||||
uint8_t light_driver_get_brightness(void);
|
||||
esp_err_t light_driver_get_ctb(uint8_t *color_temperature, uint8_t *brightness);
|
||||
bool light_driver_get_switch(void);
|
||||
uint8_t light_driver_get_mode(void);
|
||||
/**@}*/
|
||||
|
||||
/**@{*/
|
||||
/**
|
||||
* @brief Used to indicate the operating mode, such as configuring the network mode, upgrading mode
|
||||
*
|
||||
* @note The state of the light is not saved in nvs
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
*/
|
||||
esp_err_t light_driver_set_rgb(uint8_t red, uint8_t green, uint8_t blue);
|
||||
esp_err_t light_driver_breath_start(uint8_t red, uint8_t green, uint8_t blue);
|
||||
esp_err_t light_driver_breath_stop(void);
|
||||
esp_err_t light_driver_blink_start(uint8_t red, uint8_t green, uint8_t blue);
|
||||
esp_err_t light_driver_blink_stop(void);
|
||||
/**@}*/
|
||||
|
||||
/**@{*/
|
||||
/**
|
||||
* @brief Color gradient
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK
|
||||
* - ESP_ERR_INVALID_ARG
|
||||
*/
|
||||
esp_err_t light_driver_fade_brightness(uint8_t brightness);
|
||||
esp_err_t light_driver_fade_hue(uint16_t hue);
|
||||
esp_err_t light_driver_fade_warm(uint8_t color_temperature);
|
||||
esp_err_t light_driver_fade_stop(void);
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif/**< __LIGHT_DRIVER_H__ */
|
@@ -1,459 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/ledc_reg.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "driver/gptimer.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "iot_light.h"
|
||||
|
||||
static const char *TAG = "light";
|
||||
|
||||
#define IOT_CHECK(tag, a, ret) if(!(a)) { \
|
||||
return (ret); \
|
||||
}
|
||||
#define ERR_ASSERT(tag, param, ret) IOT_CHECK(tag, (param) == ESP_OK, ret)
|
||||
#define POINT_ASSERT(tag, param) IOT_CHECK(tag, (param) != NULL, ESP_FAIL)
|
||||
#define LIGHT_NUM_MAX 4
|
||||
|
||||
#define GPTIMER_RESOLUTION_HZ 1000000 // 1MHz, 1 tick=1us
|
||||
|
||||
typedef enum {
|
||||
LIGHT_CH_NUM_1 = 1, /*!< Light channel number */
|
||||
LIGHT_CH_NUM_2 = 2, /*!< Light channel number */
|
||||
LIGHT_CH_NUM_3 = 3, /*!< Light channel number */
|
||||
LIGHT_CH_NUM_4 = 4, /*!< Light channel number */
|
||||
LIGHT_CH_NUM_5 = 5, /*!< Light channel number */
|
||||
LIGHT_CH_NUM_MAX, /*!< user shouldn't use this */
|
||||
} light_channel_num_t;
|
||||
|
||||
typedef struct {
|
||||
gpio_num_t io_num;
|
||||
ledc_mode_t mode;
|
||||
ledc_channel_t channel;
|
||||
int breath_period;
|
||||
int blink_period;
|
||||
uint32_t fade_step_num;
|
||||
uint32_t *fade_duty_step;
|
||||
int fade_duty_counter;
|
||||
bool fade_step_up;
|
||||
bool fade_once;
|
||||
bool fade_start;
|
||||
} light_channel_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t channel_num;
|
||||
ledc_mode_t mode;
|
||||
ledc_timer_t ledc_timer;
|
||||
uint32_t full_duty;
|
||||
uint32_t freq_hz;
|
||||
ledc_timer_bit_t timer_bit;
|
||||
gptimer_handle_t gptimer;
|
||||
light_channel_t *channel_group[];
|
||||
} light_t;
|
||||
|
||||
static bool g_fade_installed = false;
|
||||
static bool g_hw_timer_started = false;
|
||||
static light_t *g_light_group[LIGHT_NUM_MAX] = {NULL};
|
||||
static esp_err_t iot_light_duty_set(light_handle_t light_handle, uint8_t channel_id, uint32_t duty);
|
||||
|
||||
static IRAM_ATTR void iot_ledc_ls_channel_update(ledc_mode_t speed_mode, ledc_channel_t channel_num)
|
||||
{
|
||||
if (speed_mode == LEDC_LOW_SPEED_MODE) {
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR esp_err_t iot_ledc_duty_config(ledc_mode_t speed_mode, ledc_channel_t channel_num, int hpoint_val, int duty_val,
|
||||
uint32_t duty_direction, uint32_t duty_num, uint32_t duty_cycle, uint32_t duty_scale)
|
||||
{
|
||||
if (hpoint_val >= 0) {
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val & LEDC_HPOINT_HSCH1_V;
|
||||
}
|
||||
|
||||
if (duty_val >= 0) {
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].duty.duty = duty_val;
|
||||
}
|
||||
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].conf1.val = ((duty_direction & LEDC_DUTY_INC_HSCH0_V) << LEDC_DUTY_INC_HSCH0_S) |
|
||||
((duty_num & LEDC_DUTY_NUM_HSCH0_V) << LEDC_DUTY_NUM_HSCH0_S) |
|
||||
((duty_cycle & LEDC_DUTY_CYCLE_HSCH0_V) << LEDC_DUTY_CYCLE_HSCH0_S) |
|
||||
((duty_scale & LEDC_DUTY_SCALE_HSCH0_V) << LEDC_DUTY_SCALE_HSCH0_S);
|
||||
iot_ledc_ls_channel_update(speed_mode, channel_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static IRAM_ATTR esp_err_t iot_ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty)
|
||||
{
|
||||
return iot_ledc_duty_config(speed_mode,
|
||||
channel, //uint32_t chan_num,
|
||||
-1,
|
||||
duty << 4, //uint32_t duty_val,the least 4 bits are decimal part
|
||||
1, //uint32_t increase,
|
||||
1, //uint32_t duty_num,
|
||||
1, //uint32_t duty_cycle,
|
||||
0 //uint32_t duty_scale
|
||||
);
|
||||
}
|
||||
|
||||
static IRAM_ATTR esp_err_t iot_ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 1;
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf1.duty_start = 1;
|
||||
iot_ledc_ls_channel_update(speed_mode, channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool breath_timer_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
|
||||
{
|
||||
for (int i = 0; i < LIGHT_NUM_MAX; i++) {
|
||||
if (g_light_group[i] != NULL) {
|
||||
light_t *light = g_light_group[i];
|
||||
|
||||
for (int j = 0; j < light->channel_num; j++) {
|
||||
light_channel_t *l_chn = light->channel_group[j];
|
||||
|
||||
if (l_chn->fade_start == true) {
|
||||
if (l_chn->fade_step_up == true) {
|
||||
l_chn->fade_duty_counter++;
|
||||
} else {
|
||||
l_chn->fade_duty_counter--;
|
||||
}
|
||||
|
||||
if ((l_chn->fade_duty_counter >= 0) && (l_chn->fade_duty_counter < l_chn->fade_step_num)) {
|
||||
iot_ledc_set_duty(l_chn->mode, l_chn->channel, l_chn->fade_duty_step[l_chn->fade_duty_counter]);
|
||||
iot_ledc_update_duty(l_chn->mode, l_chn->channel);
|
||||
} else {
|
||||
if (l_chn->fade_once != true) {
|
||||
l_chn->fade_step_up = 1 - l_chn->fade_step_up;
|
||||
} else {
|
||||
l_chn->fade_start = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static light_channel_t *light_channel_create(gpio_num_t io_num, ledc_channel_t channel, ledc_mode_t mode, ledc_timer_t timer)
|
||||
{
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.channel = channel,
|
||||
.duty = 0,
|
||||
.gpio_num = io_num,
|
||||
.intr_type = LEDC_INTR_FADE_END,
|
||||
.speed_mode = mode,
|
||||
.timer_sel = timer
|
||||
};
|
||||
ERR_ASSERT(TAG, ledc_channel_config(&ledc_channel), NULL);
|
||||
light_channel_t *pwm = (light_channel_t *)calloc(1, sizeof(light_channel_t));
|
||||
pwm->io_num = io_num;
|
||||
pwm->channel = channel;
|
||||
pwm->mode = mode;
|
||||
pwm->breath_period = 0;
|
||||
pwm->blink_period = 0;
|
||||
pwm->fade_step_num = 0;
|
||||
pwm->fade_duty_step = NULL;
|
||||
pwm->fade_duty_counter = 0;
|
||||
pwm->fade_step_up = true;
|
||||
pwm->fade_once = false;
|
||||
pwm->fade_start = false;
|
||||
return pwm;
|
||||
}
|
||||
|
||||
static esp_err_t light_channel_delete(light_channel_t *light_channel)
|
||||
{
|
||||
POINT_ASSERT(TAG, light_channel);
|
||||
|
||||
if (light_channel->fade_duty_step != NULL) {
|
||||
heap_caps_free(light_channel->fade_duty_step);
|
||||
light_channel->fade_duty_step = NULL;
|
||||
}
|
||||
|
||||
free(light_channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t light_channel_fade_clear(light_channel_t *light_channel)
|
||||
{
|
||||
light_channel->fade_start = false;
|
||||
light_channel->fade_step_num = 0;
|
||||
light_channel->fade_duty_counter = 0;
|
||||
light_channel->fade_step_up = true;
|
||||
light_channel->fade_once = false;
|
||||
|
||||
if (light_channel->fade_duty_step != NULL) {
|
||||
heap_caps_free(light_channel->fade_duty_step);
|
||||
light_channel->fade_duty_step = NULL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
light_handle_t iot_light_create(ledc_timer_t timer, ledc_mode_t speed_mode, uint32_t freq_hz, uint8_t channel_num, ledc_timer_bit_t timer_bit)
|
||||
{
|
||||
IOT_CHECK(TAG, channel_num != 0, NULL);
|
||||
ledc_timer_config_t timer_conf = {
|
||||
.timer_num = timer,
|
||||
.speed_mode = speed_mode,
|
||||
.freq_hz = freq_hz,
|
||||
.bit_num = timer_bit
|
||||
};
|
||||
ERR_ASSERT(TAG, ledc_timer_config(&timer_conf), NULL);
|
||||
light_t *light_ptr = (light_t *)calloc(1, sizeof(light_t) + sizeof(light_channel_t *) * channel_num);
|
||||
light_ptr->channel_num = channel_num;
|
||||
light_ptr->ledc_timer = timer;
|
||||
light_ptr->full_duty = (1 << timer_bit) - 1;
|
||||
light_ptr->freq_hz = freq_hz;
|
||||
light_ptr->mode = speed_mode;
|
||||
light_ptr->timer_bit = timer_bit;
|
||||
|
||||
if (g_hw_timer_started == false) {
|
||||
gptimer_config_t timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = GPTIMER_RESOLUTION_HZ,
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &light_ptr->gptimer));
|
||||
gptimer_alarm_config_t alarm_config = {
|
||||
.alarm_count = DUTY_SET_CYCLE / 1000 * GPTIMER_RESOLUTION_HZ,
|
||||
.reload_count = 0,
|
||||
.flags.auto_reload_on_alarm = true,
|
||||
};
|
||||
gptimer_event_callbacks_t cbs = {
|
||||
.on_alarm = breath_timer_callback,
|
||||
};
|
||||
gptimer_register_event_callbacks(light_ptr->gptimer, &cbs, NULL);
|
||||
gptimer_set_alarm_action(light_ptr->gptimer, &alarm_config);
|
||||
gptimer_enable(light_ptr->gptimer);
|
||||
gptimer_start(light_ptr->gptimer);
|
||||
g_hw_timer_started = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < channel_num; i++) {
|
||||
light_ptr->channel_group[i] = NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < LIGHT_NUM_MAX; i++) {
|
||||
if (g_light_group[i] == NULL) {
|
||||
g_light_group[i] = light_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (light_handle_t)light_ptr;
|
||||
}
|
||||
|
||||
esp_err_t iot_light_delete(light_handle_t light_handle)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
|
||||
for (int i = 0; i < light->channel_num; i++) {
|
||||
if (light->channel_group[i] != NULL) {
|
||||
iot_light_duty_set(light, i, 0);
|
||||
light_channel_delete(light->channel_group[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < LIGHT_NUM_MAX; i++) {
|
||||
if (g_light_group[i] == light) {
|
||||
g_light_group[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < LIGHT_NUM_MAX; i++) {
|
||||
if (g_light_group[i] != NULL) {
|
||||
goto FREE_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
ledc_fade_func_uninstall();
|
||||
g_fade_installed = false;
|
||||
g_hw_timer_started = false;
|
||||
gptimer_stop(light->gptimer);
|
||||
gptimer_disable(light->gptimer);
|
||||
gptimer_del_timer(light->gptimer);
|
||||
FREE_MEM:
|
||||
free(light_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_light_channel_regist(light_handle_t light_handle, uint8_t channel_idx, gpio_num_t io_num, ledc_channel_t channel)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_idx < light->channel_num, FAIL);
|
||||
|
||||
if (light->channel_group[channel_idx] != NULL) {
|
||||
ESP_LOGE(TAG, "this channel index has been registered");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
light->channel_group[channel_idx] = light_channel_create(io_num, channel, light->mode, light->ledc_timer);
|
||||
|
||||
if (g_fade_installed == false) {
|
||||
ledc_fade_func_install(0);
|
||||
g_fade_installed = true;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t iot_light_duty_set(light_handle_t light_handle, uint8_t channel_id, uint32_t duty)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL);
|
||||
POINT_ASSERT(TAG, light->channel_group[channel_id]);
|
||||
light_channel_t *l_chn = light->channel_group[channel_id];
|
||||
|
||||
light_channel_fade_clear(l_chn);
|
||||
|
||||
iot_ledc_set_duty(l_chn->mode, l_chn->channel, duty);
|
||||
iot_ledc_update_duty(l_chn->mode, l_chn->channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t iot_light_duty_get(light_handle_t light_handle, uint8_t channel_id)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL);
|
||||
POINT_ASSERT(TAG, light->channel_group[channel_id]);
|
||||
light_channel_t *l_chn = light->channel_group[channel_id];
|
||||
|
||||
return ledc_get_duty(l_chn->mode, l_chn->channel);
|
||||
}
|
||||
|
||||
esp_err_t iot_light_fade_with_time(light_handle_t light_handle, uint8_t channel_id, uint32_t duty, uint32_t fade_period_ms)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL);
|
||||
POINT_ASSERT(TAG, light->channel_group[channel_id]);
|
||||
light_channel_t *l_chn = light->channel_group[channel_id];
|
||||
|
||||
if (fade_period_ms == 0) {
|
||||
return iot_light_duty_set(light, channel_id, duty);
|
||||
}
|
||||
|
||||
light_channel_fade_clear(l_chn);
|
||||
|
||||
l_chn->fade_step_num = fade_period_ms / DUTY_SET_CYCLE + 1;
|
||||
l_chn->fade_duty_step = (uint32_t *)heap_caps_malloc(l_chn->fade_step_num * sizeof(uint32_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
|
||||
uint32_t duty_cur = iot_light_duty_get(light, channel_id);
|
||||
int duty_delta = duty - duty_cur;
|
||||
|
||||
if (duty_delta > 0) {
|
||||
float coe = (duty_delta / pow((double)l_chn->fade_step_num, (double)1 / DUTY_SET_GAMMA));
|
||||
|
||||
for (int i = 0; i < l_chn->fade_step_num; i++) {
|
||||
l_chn->fade_duty_step[i] = duty_cur + (int)(coe * pow((double)i, (double)1 / DUTY_SET_GAMMA));
|
||||
}
|
||||
|
||||
l_chn->fade_step_up = true;
|
||||
} else {
|
||||
duty_delta = 0 - duty_delta;
|
||||
float coe = (duty_delta / pow((double)l_chn->fade_step_num, (double)1 / DUTY_SET_GAMMA));
|
||||
|
||||
for (int i = 0; i < l_chn->fade_step_num; i++) {
|
||||
l_chn->fade_duty_step[i] = duty + (int)(coe * pow((double)i, (double)1 / DUTY_SET_GAMMA));
|
||||
}
|
||||
|
||||
l_chn->fade_duty_counter = l_chn->fade_step_num;
|
||||
l_chn->fade_step_up = false;
|
||||
}
|
||||
|
||||
l_chn->fade_once = true;
|
||||
l_chn->fade_start = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_light_breath_config(light_handle_t light_handle, uint8_t channel_id, uint32_t duty, uint32_t breath_period_ms)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL);
|
||||
POINT_ASSERT(TAG, light->channel_group[channel_id]);
|
||||
light_channel_t *l_chn = light->channel_group[channel_id];
|
||||
|
||||
light_channel_fade_clear(l_chn);
|
||||
|
||||
/**
|
||||
* @brief control light with nonlinearity fade, the duty and the fade step
|
||||
* conform to gamma curve. gamma curve formula: y=a*x^(1/gm) firstly,
|
||||
* use the target duty and step number to calculate coefficient `a`,
|
||||
* secondly, calculate the duty for every step
|
||||
*/
|
||||
|
||||
l_chn->fade_step_num = (breath_period_ms / 2) / DUTY_SET_CYCLE + 1;
|
||||
float coe = (duty / pow((double)l_chn->fade_step_num, (double)1 / DUTY_SET_GAMMA));
|
||||
|
||||
l_chn->fade_duty_step = (uint32_t *)heap_caps_malloc(l_chn->fade_step_num * sizeof(uint32_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
|
||||
for (int i = 0; i < l_chn->fade_step_num; i++) {
|
||||
l_chn->fade_duty_step[i] = (int)(coe * pow((double)i, (double)1 / DUTY_SET_GAMMA));
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_light_blink_config(light_handle_t light_handle, uint8_t channel_id, uint32_t blink_period_ms)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL);
|
||||
light_channel_t *l_chn = light->channel_group[channel_id];
|
||||
|
||||
light_channel_fade_clear(l_chn);
|
||||
|
||||
l_chn->fade_step_num = (blink_period_ms / 2) / DUTY_SET_CYCLE;
|
||||
l_chn->fade_duty_step = (uint32_t *)heap_caps_malloc(l_chn->fade_step_num * sizeof(uint32_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < (l_chn->fade_step_num / 2); i++) {
|
||||
l_chn->fade_duty_step[i] = 0;
|
||||
}
|
||||
|
||||
for (; i < l_chn->fade_step_num; i++) {
|
||||
l_chn->fade_duty_step[i] = light->full_duty;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_light_operate_start(light_handle_t light_handle, uint8_t channel_id)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL);
|
||||
light->channel_group[channel_id]->fade_start = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t iot_light_operate_stop(light_handle_t light_handle, uint8_t channel_id)
|
||||
{
|
||||
light_t *light = (light_t *)light_handle;
|
||||
POINT_ASSERT(TAG, light_handle);
|
||||
IOT_CHECK(TAG, channel_id < light->channel_num, ESP_FAIL);
|
||||
light->channel_group[channel_id]->fade_start = false;
|
||||
// iot_light_duty_set(light, channel_id, 0);
|
||||
return ESP_OK;
|
||||
}
|
@@ -1,891 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "errno.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_partition.h"
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "sys/param.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#include "light_driver.h"
|
||||
#include "ble_mesh_example_nvs.h"
|
||||
|
||||
/**
|
||||
* @brief The state of the five-color light
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t mode;
|
||||
uint8_t on;
|
||||
uint16_t hue;
|
||||
uint8_t saturation;
|
||||
uint8_t value;
|
||||
uint8_t lightness;
|
||||
uint8_t color_temperature;
|
||||
uint8_t brightness;
|
||||
uint32_t fade_period_ms;
|
||||
uint32_t blink_period_ms;
|
||||
} light_status_t;
|
||||
|
||||
/**
|
||||
* @brief The channel of the five-color light
|
||||
*/
|
||||
enum light_channel {
|
||||
CHANNEL_ID_RED = 0,
|
||||
CHANNEL_ID_GREEN,
|
||||
CHANNEL_ID_BLUE,
|
||||
CHANNEL_ID_WARM,
|
||||
CHANNEL_ID_COLD,
|
||||
};
|
||||
|
||||
#define LIGHT_FADE_PERIOD_MAX_MS (3 * 1000)
|
||||
|
||||
static const char *TAG = "light_driver";
|
||||
static light_status_t g_light_status = {0};
|
||||
static bool g_light_blink_flag = false;
|
||||
static TimerHandle_t g_fade_timer = NULL;
|
||||
static int g_fade_mode = MODE_NONE;
|
||||
static uint16_t g_fade_hue = 0;
|
||||
extern nvs_handle_t NVS_HANDLE;
|
||||
|
||||
esp_err_t light_driver_init(light_driver_config_t *config)
|
||||
{
|
||||
LIGHT_PARAM_CHECK(config);
|
||||
bool exist = false;
|
||||
|
||||
if (ble_mesh_nvs_restore(NVS_HANDLE, LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_status_t), &exist) != ESP_OK) {
|
||||
memset(&g_light_status, 0, sizeof(light_status_t));
|
||||
g_light_status.mode = MODE_HSV;
|
||||
g_light_status.on = 1;
|
||||
g_light_status.hue = 360;
|
||||
g_light_status.saturation = 0;
|
||||
g_light_status.value = 100;
|
||||
g_light_status.lightness = 100;
|
||||
g_light_status.color_temperature = 0;
|
||||
g_light_status.brightness = 30;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
iot_led_init(LEDC_TIMER_0, LEDC_LOW_SPEED_MODE, 1000);
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
iot_led_init(LEDC_TIMER_0, LEDC_HIGH_SPEED_MODE, 1000);
|
||||
#endif
|
||||
|
||||
g_light_status.fade_period_ms = config->fade_period_ms;
|
||||
g_light_status.blink_period_ms = config->blink_period_ms;
|
||||
|
||||
iot_led_regist_channel(CHANNEL_ID_RED, config->gpio_red);
|
||||
iot_led_regist_channel(CHANNEL_ID_GREEN, config->gpio_green);
|
||||
iot_led_regist_channel(CHANNEL_ID_BLUE, config->gpio_blue);
|
||||
iot_led_regist_channel(CHANNEL_ID_WARM, config->gpio_warm);
|
||||
iot_led_regist_channel(CHANNEL_ID_COLD, config->gpio_cold);
|
||||
|
||||
ESP_LOGI(TAG, "hue: %d, saturation: %d, value: %d, lightness: %d",
|
||||
g_light_status.hue, g_light_status.saturation, g_light_status.value, g_light_status.lightness);
|
||||
ESP_LOGI(TAG, "brightness: %d, color_temperature: %d",
|
||||
g_light_status.brightness, g_light_status.color_temperature);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_deinit(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
iot_led_deinit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_config(uint32_t fade_period_ms, uint32_t blink_period_ms)
|
||||
{
|
||||
g_light_status.fade_period_ms = fade_period_ms;
|
||||
g_light_status.blink_period_ms = blink_period_ms;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_rgb(uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
esp_err_t ret = 0;
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_RED, red, 0);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_GREEN, green, 0);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_BLUE, blue, 0);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_WARM, 0, 0);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_COLD, 0, 0);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t light_driver_hsv2rgb(uint16_t hue, uint8_t saturation, uint8_t value,
|
||||
uint8_t *red, uint8_t *green, uint8_t *blue)
|
||||
{
|
||||
uint16_t hi = (hue / 60) % 6;
|
||||
uint16_t F = 100 * hue / 60 - 100 * hi;
|
||||
uint16_t P = value * (100 - saturation) / 100;
|
||||
uint16_t Q = value * (10000 - F * saturation) / 10000;
|
||||
uint16_t T = value * (10000 - saturation * (100 - F)) / 10000;
|
||||
|
||||
switch (hi) {
|
||||
case 0:
|
||||
*red = value;
|
||||
*green = T;
|
||||
*blue = P;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*red = Q;
|
||||
*green = value;
|
||||
*blue = P;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*red = P;
|
||||
*green = value;
|
||||
*blue = T;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
*red = P;
|
||||
*green = Q;
|
||||
*blue = value;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*red = T;
|
||||
*green = P;
|
||||
*blue = value;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
*red = value;
|
||||
*green = P;
|
||||
*blue = Q;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
*red = *red * 255 / 100;
|
||||
*green = *green * 255 / 100;
|
||||
*blue = *blue * 255 / 100;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void light_driver_rgb2hsv(uint16_t red, uint16_t green, uint16_t blue,
|
||||
uint16_t *h, uint8_t *s, uint8_t *v)
|
||||
{
|
||||
double hue, saturation, value;
|
||||
double m_max = MAX(red, MAX(green, blue));
|
||||
double m_min = MIN(red, MIN(green, blue));
|
||||
double m_delta = m_max - m_min;
|
||||
|
||||
value = m_max / 255.0;
|
||||
|
||||
if (m_delta == 0) {
|
||||
hue = 0;
|
||||
saturation = 0;
|
||||
} else {
|
||||
saturation = m_delta / m_max;
|
||||
|
||||
if (red == m_max) {
|
||||
hue = (green - blue) / m_delta;
|
||||
} else if (green == m_max) {
|
||||
hue = 2 + (blue - red) / m_delta;
|
||||
} else {
|
||||
hue = 4 + (red - green) / m_delta;
|
||||
}
|
||||
|
||||
hue = hue * 60;
|
||||
|
||||
if (hue < 0) {
|
||||
hue = hue + 360;
|
||||
}
|
||||
}
|
||||
|
||||
*h = (int)(hue + 0.5);
|
||||
*s = (int)(saturation * 100 + 0.5);
|
||||
*v = (int)(value * 100 + 0.5);
|
||||
}
|
||||
|
||||
// refence: https://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
static esp_err_t light_driver_hsl2rgb(uint16_t hue, uint8_t saturation, uint8_t lightness,
|
||||
uint8_t *red, uint8_t *green, uint8_t *blue)
|
||||
{
|
||||
uint16_t hi = (hue / 60) % 6;
|
||||
uint16_t C = (100 - abs(2 * lightness - 100)) * saturation / 100;
|
||||
uint16_t M = 100 * (lightness - 0.5 * C) / 100;
|
||||
uint16_t X = C * (100 - abs((hue * 100 / 60 ) % 200 - 100)) / 100;
|
||||
|
||||
switch (hi) {
|
||||
case 0: /* hue 0~60 */
|
||||
*red = C + M;
|
||||
*green = X + M;
|
||||
*blue = M;
|
||||
break;
|
||||
|
||||
case 1: /* hue 60~120 */
|
||||
*red = X + M;
|
||||
*green = C + M;
|
||||
*blue = M;
|
||||
break;
|
||||
|
||||
case 2: /* hue 120~180 */
|
||||
*red = M;
|
||||
*green = C + M;
|
||||
*blue = X + M;
|
||||
break;
|
||||
|
||||
case 3: /* hue 180~240 */
|
||||
*red = M;
|
||||
*green = X + M;
|
||||
*blue = C + M;
|
||||
break;
|
||||
|
||||
case 4: /* hue 240~300 */
|
||||
*red = X + M;
|
||||
*green = M;
|
||||
*blue = C + M;
|
||||
break;
|
||||
|
||||
case 5: /* hue 300~360 */
|
||||
*red = C + M;
|
||||
*green = M;
|
||||
*blue = X + M;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
*red = *red * 255 / 100;
|
||||
*green = *green * 255 / 100;
|
||||
*blue = *blue * 255 / 100;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_hsv(uint16_t hue, uint8_t saturation, uint8_t value)
|
||||
{
|
||||
LIGHT_PARAM_CHECK(hue <= 360);
|
||||
LIGHT_PARAM_CHECK(saturation <= 100);
|
||||
LIGHT_PARAM_CHECK(value <= 100);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t red = 0;
|
||||
uint8_t green = 0;
|
||||
uint8_t blue = 0;
|
||||
|
||||
ret = light_driver_hsv2rgb(hue, saturation, value, &red, &green, &blue);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "light_driver_hsv2rgb, ret: %d", ret);
|
||||
|
||||
ESP_LOGV(TAG, "red: %d, green: %d, blue: %d", red, green, blue);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_RED, red, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_GREEN, green, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_BLUE, blue, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
if (g_light_status.mode != MODE_HSV) {
|
||||
ret = iot_led_set_channel(CHANNEL_ID_WARM, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_COLD, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
}
|
||||
|
||||
g_light_status.mode = MODE_HSV;
|
||||
g_light_status.on = 1;
|
||||
g_light_status.hue = hue;
|
||||
g_light_status.value = value;
|
||||
g_light_status.saturation = saturation;
|
||||
|
||||
ret = ble_mesh_nvs_store(NVS_HANDLE, LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_status_t));
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "ble_mesh_nvs_store, ret: %d", ret);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_hue(uint16_t hue)
|
||||
{
|
||||
if (g_light_status.mode == MODE_HSV) {
|
||||
return light_driver_set_hsv(hue, g_light_status.saturation, g_light_status.value);
|
||||
} else if (g_light_status.mode == MODE_HSL) {
|
||||
return light_driver_set_hsl(hue, g_light_status.saturation, g_light_status.lightness);
|
||||
} else {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_saturation(uint8_t saturation)
|
||||
{
|
||||
if (g_light_status.mode == MODE_HSV) {
|
||||
return light_driver_set_hsv(g_light_status.hue, saturation, g_light_status.value);
|
||||
} else if (g_light_status.mode == MODE_HSL) {
|
||||
return light_driver_set_hsl(g_light_status.hue, saturation, g_light_status.lightness);
|
||||
} else {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_value(uint8_t value)
|
||||
{
|
||||
return light_driver_set_hsv(g_light_status.hue, g_light_status.saturation, value);
|
||||
}
|
||||
|
||||
esp_err_t light_driver_get_hsv(uint16_t *hue, uint8_t *saturation, uint8_t *value)
|
||||
{
|
||||
LIGHT_PARAM_CHECK(hue);
|
||||
LIGHT_PARAM_CHECK(saturation);
|
||||
LIGHT_PARAM_CHECK(value);
|
||||
|
||||
*hue = g_light_status.hue;
|
||||
*saturation = g_light_status.saturation;
|
||||
*value = g_light_status.value;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint16_t light_driver_get_hue(void)
|
||||
{
|
||||
return g_light_status.hue;
|
||||
}
|
||||
|
||||
uint8_t light_driver_get_saturation(void)
|
||||
{
|
||||
return g_light_status.saturation;
|
||||
}
|
||||
|
||||
uint8_t light_driver_get_value(void)
|
||||
{
|
||||
return g_light_status.value;
|
||||
}
|
||||
|
||||
uint8_t light_driver_get_mode(void)
|
||||
{
|
||||
return g_light_status.mode;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_ctb(uint8_t color_temperature, uint8_t brightness)
|
||||
{
|
||||
LIGHT_PARAM_CHECK(brightness <= 100);
|
||||
LIGHT_PARAM_CHECK(color_temperature <= 100);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t warm_tmp = color_temperature * brightness / 100;
|
||||
uint8_t cold_tmp = (100 - color_temperature) * brightness / 100;
|
||||
warm_tmp = warm_tmp < 15 ? warm_tmp : 14 + warm_tmp * 86 / 100;
|
||||
cold_tmp = cold_tmp < 15 ? cold_tmp : 14 + cold_tmp * 86 / 100;
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_COLD,
|
||||
cold_tmp * 255 / 100, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_WARM,
|
||||
warm_tmp * 255 / 100, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
if (g_light_status.mode != MODE_CTB) {
|
||||
ret = iot_led_set_channel(CHANNEL_ID_RED, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_GREEN, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_BLUE, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
}
|
||||
|
||||
g_light_status.mode = MODE_CTB;
|
||||
g_light_status.on = 1;
|
||||
g_light_status.brightness = brightness;
|
||||
g_light_status.color_temperature = color_temperature;
|
||||
|
||||
ret = ble_mesh_nvs_store(NVS_HANDLE, LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_status_t));
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "ble_mesh_nvs_store, ret: %d", ret);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_color_temperature(uint8_t color_temperature)
|
||||
{
|
||||
return light_driver_set_ctb(color_temperature, g_light_status.brightness);
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_brightness(uint8_t brightness)
|
||||
{
|
||||
return light_driver_set_ctb(g_light_status.color_temperature, brightness);
|
||||
}
|
||||
|
||||
esp_err_t light_driver_get_ctb(uint8_t *color_temperature, uint8_t *brightness)
|
||||
{
|
||||
LIGHT_PARAM_CHECK(color_temperature);
|
||||
LIGHT_PARAM_CHECK(brightness);
|
||||
|
||||
*brightness = g_light_status.brightness;
|
||||
*color_temperature = g_light_status.color_temperature;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint8_t light_driver_get_color_temperature(void)
|
||||
{
|
||||
return g_light_status.color_temperature;
|
||||
}
|
||||
|
||||
uint8_t light_driver_get_brightness(void)
|
||||
{
|
||||
return g_light_status.brightness;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_hsl(uint16_t hue, uint8_t saturation, uint8_t lightness)
|
||||
{
|
||||
LIGHT_PARAM_CHECK(hue <= 360);
|
||||
LIGHT_PARAM_CHECK(saturation <= 100);
|
||||
LIGHT_PARAM_CHECK(lightness <= 100);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t red = 0;
|
||||
uint8_t green = 0;
|
||||
uint8_t blue = 0;
|
||||
|
||||
ret = light_driver_hsl2rgb(hue, saturation, lightness, &red, &green, &blue);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "light_driver_hsl2rgb, ret: %d", ret);
|
||||
|
||||
ESP_LOGV(TAG, "red: %d, green: %d, blue: %d", red, green, blue);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_RED, red, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_GREEN, green, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_BLUE, blue, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
if (g_light_status.mode != MODE_HSL) {
|
||||
ret = iot_led_set_channel(CHANNEL_ID_WARM, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_COLD, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
}
|
||||
|
||||
g_light_status.mode = MODE_HSL;
|
||||
g_light_status.on = 1;
|
||||
g_light_status.hue = hue;
|
||||
g_light_status.saturation = saturation;
|
||||
g_light_status.lightness = lightness;
|
||||
|
||||
ret = ble_mesh_nvs_store(NVS_HANDLE, LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_status_t));
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "ble_mesh_nvs_store, ret: %d", ret);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_lightness(uint8_t lightness)
|
||||
{
|
||||
return light_driver_set_hsl(g_light_status.hue, g_light_status.saturation, lightness);
|
||||
}
|
||||
|
||||
uint8_t light_driver_get_lightness(void)
|
||||
{
|
||||
return g_light_status.lightness;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_get_hsl(uint16_t *hue, uint8_t *saturation, uint8_t *lightness)
|
||||
{
|
||||
LIGHT_PARAM_CHECK(hue);
|
||||
LIGHT_PARAM_CHECK(saturation);
|
||||
LIGHT_PARAM_CHECK(lightness);
|
||||
|
||||
*hue = g_light_status.hue;
|
||||
*saturation = g_light_status.saturation;
|
||||
*lightness = g_light_status.lightness;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_switch(bool on)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
g_light_status.on = on;
|
||||
|
||||
if (!g_light_status.on) {
|
||||
ret = iot_led_set_channel(CHANNEL_ID_RED, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_GREEN, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_BLUE, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_COLD, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_WARM, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
} else {
|
||||
switch (g_light_status.mode) {
|
||||
case MODE_HSV:
|
||||
g_light_status.value = (g_light_status.value) ? g_light_status.value : 100;
|
||||
ret = light_driver_set_hsv(g_light_status.hue, g_light_status.saturation, g_light_status.value);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "light_driver_set_hsv, ret: %d", ret);
|
||||
break;
|
||||
|
||||
case MODE_HSL:
|
||||
g_light_status.lightness = (g_light_status.lightness) ? g_light_status.lightness : 100;
|
||||
ret = light_driver_set_hsl(g_light_status.hue, g_light_status.saturation, g_light_status.lightness);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "light_driver_set_hsl, ret: %d", ret);
|
||||
break;
|
||||
|
||||
case MODE_CTB:
|
||||
g_light_status.brightness = (g_light_status.brightness) ? g_light_status.brightness : 100;
|
||||
ret = light_driver_set_ctb(g_light_status.color_temperature, g_light_status.brightness);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "light_driver_set_ctb, ret: %d", ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGW(TAG, "This operation is not supported");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ble_mesh_nvs_store(NVS_HANDLE, LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_status_t));
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "ble_mesh_nvs_store, ret: %d", ret);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_set_mode(light_mode_t mode)
|
||||
{
|
||||
g_light_status.mode = mode;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool light_driver_get_switch(void)
|
||||
{
|
||||
return g_light_status.on;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_breath_start(uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
ret = iot_led_start_blink(CHANNEL_ID_RED,
|
||||
red, g_light_status.blink_period_ms, true);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_start_blink, ret: %d", ret);
|
||||
ret = iot_led_start_blink(CHANNEL_ID_GREEN,
|
||||
green, g_light_status.blink_period_ms, true);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_start_blink, ret: %d", ret);
|
||||
ret = iot_led_start_blink(CHANNEL_ID_BLUE,
|
||||
blue, g_light_status.blink_period_ms, true);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_start_blink, ret: %d", ret);
|
||||
|
||||
g_light_blink_flag = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_breath_stop(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (g_light_blink_flag == false) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ret = iot_led_stop_blink(CHANNEL_ID_RED);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_stop_blink, ret: %d", ret);
|
||||
|
||||
ret = iot_led_stop_blink(CHANNEL_ID_GREEN);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_stop_blink, ret: %d", ret);
|
||||
|
||||
ret = iot_led_stop_blink(CHANNEL_ID_BLUE);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_stop_blink, ret: %d", ret);
|
||||
|
||||
light_driver_set_switch(true);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_fade_brightness(uint8_t brightness)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
g_fade_mode = MODE_ON;
|
||||
uint32_t fade_period_ms = 0;
|
||||
|
||||
if (g_light_status.mode == MODE_HSV) {
|
||||
uint8_t red = 0;
|
||||
uint8_t green = 0;
|
||||
uint8_t blue = 0;
|
||||
|
||||
ret = light_driver_hsv2rgb(g_light_status.hue, g_light_status.saturation, g_light_status.value, &red, &green, &blue);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "light_driver_hsv2rgb, ret: %d", ret);
|
||||
|
||||
if (brightness != 0) {
|
||||
ret = iot_led_get_channel((ledc_channel_t)CHANNEL_ID_RED, &red);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_get_channel, ret: %d", ret);
|
||||
ret = iot_led_get_channel((ledc_channel_t)CHANNEL_ID_GREEN, &green);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_get_channel, ret: %d", ret);
|
||||
ret = iot_led_get_channel((ledc_channel_t)CHANNEL_ID_BLUE, &blue);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_get_channel, ret: %d", ret);
|
||||
|
||||
uint8_t max_color = MAX(MAX(red, green), blue);
|
||||
uint8_t change_value = brightness * 255 / 100 - max_color;
|
||||
fade_period_ms = LIGHT_FADE_PERIOD_MAX_MS * change_value / 255;
|
||||
} else {
|
||||
fade_period_ms = LIGHT_FADE_PERIOD_MAX_MS * MAX(MAX(red, green), blue) / 255;
|
||||
red = 0;
|
||||
}
|
||||
|
||||
g_light_status.value = brightness;
|
||||
light_driver_hsv2rgb(g_light_status.hue, g_light_status.saturation, g_light_status.value, &red, &green, &blue);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_RED, red, fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_GREEN, green, fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_BLUE, blue, fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
} else if (g_light_status.mode == MODE_CTB) {
|
||||
uint8_t warm_tmp = 0;
|
||||
uint8_t cold_tmp = 0;
|
||||
fade_period_ms = LIGHT_FADE_PERIOD_MAX_MS * g_light_status.brightness / 100;
|
||||
|
||||
if (brightness != 0) {
|
||||
uint8_t change_value = brightness - g_light_status.brightness;
|
||||
warm_tmp = g_light_status.color_temperature;
|
||||
cold_tmp = (brightness - g_light_status.color_temperature);
|
||||
fade_period_ms = LIGHT_FADE_PERIOD_MAX_MS * change_value / 100;
|
||||
}
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_COLD,
|
||||
cold_tmp * 255 / 100, fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_WARM,
|
||||
warm_tmp * 255 / 100, fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
g_light_status.brightness = brightness;
|
||||
}
|
||||
|
||||
ret = ble_mesh_nvs_store(NVS_HANDLE, LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_status_t));
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "ble_mesh_nvs_store, ret: %d", ret);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void light_fade_timer_stop(void)
|
||||
{
|
||||
if (!g_fade_timer) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (!xTimerStop(g_fade_timer, portMAX_DELAY)) {
|
||||
ESP_LOGW(TAG, "xTimerStop timer: %p", g_fade_timer);
|
||||
}
|
||||
|
||||
if (!xTimerDelete(g_fade_timer, portMAX_DELAY)) {
|
||||
ESP_LOGW(TAG, "xTimerDelete timer: %p", g_fade_timer);
|
||||
}
|
||||
|
||||
g_fade_timer = NULL;
|
||||
}
|
||||
|
||||
static void light_fade_timer_cb(TimerHandle_t timer)
|
||||
{
|
||||
uint8_t red = 0;
|
||||
uint8_t green = 0;
|
||||
uint8_t blue = 0;
|
||||
uint32_t fade_period_ms = LIGHT_FADE_PERIOD_MAX_MS * 2 / 6;
|
||||
int variety = (g_fade_hue > 180) ? 60 : -60;
|
||||
|
||||
if (g_light_status.hue >= 360 || g_light_status.hue <= 0) {
|
||||
light_fade_timer_stop();
|
||||
}
|
||||
|
||||
g_light_status.hue = g_light_status.hue >= 360 ? 360 : g_light_status.hue + variety;
|
||||
g_light_status.hue = g_light_status.hue <= 60 ? 0 : g_light_status.hue + variety;
|
||||
|
||||
light_driver_hsv2rgb(g_light_status.hue, g_light_status.saturation, g_light_status.value, &red, &green, &blue);
|
||||
|
||||
iot_led_set_channel(CHANNEL_ID_RED, red, fade_period_ms);
|
||||
iot_led_set_channel(CHANNEL_ID_GREEN, green, fade_period_ms);
|
||||
iot_led_set_channel(CHANNEL_ID_BLUE, blue, fade_period_ms);
|
||||
}
|
||||
|
||||
esp_err_t light_driver_fade_hue(uint16_t hue)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
g_fade_mode = MODE_HSV;
|
||||
g_fade_hue = hue;
|
||||
|
||||
light_fade_timer_stop();
|
||||
|
||||
if (g_light_status.mode != MODE_HSV) {
|
||||
ret = iot_led_set_channel(CHANNEL_ID_WARM, 0, 0);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_COLD, 0, 0);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
}
|
||||
|
||||
g_light_status.mode = MODE_HSV;
|
||||
g_light_status.value = (g_light_status.value == 0) ? 100 : g_light_status.value;
|
||||
uint32_t fade_period_ms = LIGHT_FADE_PERIOD_MAX_MS * 2 / 6;
|
||||
|
||||
light_fade_timer_cb(NULL);
|
||||
|
||||
g_fade_timer = xTimerCreate("light_timer", fade_period_ms,
|
||||
true, NULL, light_fade_timer_cb);
|
||||
xTimerStart(g_fade_timer, 0);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_fade_warm(uint8_t color_temperature)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
g_fade_mode = MODE_CTB;
|
||||
|
||||
if (g_light_status.mode != MODE_CTB) {
|
||||
ret = iot_led_set_channel(CHANNEL_ID_RED, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_GREEN, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_BLUE, 0, g_light_status.fade_period_ms);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
}
|
||||
|
||||
uint8_t warm_tmp = color_temperature * g_light_status.brightness / 100;
|
||||
uint8_t cold_tmp = (100 - color_temperature) * g_light_status.brightness / 100;
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_COLD, cold_tmp * 255 / 100, LIGHT_FADE_PERIOD_MAX_MS);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
ret = iot_led_set_channel(CHANNEL_ID_WARM, warm_tmp * 255 / 100, LIGHT_FADE_PERIOD_MAX_MS);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "iot_led_set_channel, ret: %d", ret);
|
||||
|
||||
g_light_status.mode = MODE_CTB;
|
||||
g_light_status.color_temperature = color_temperature;
|
||||
ret = ble_mesh_nvs_store(NVS_HANDLE, LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_status_t));
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "ble_mesh_nvs_store, ret: %d", ret);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t light_driver_fade_stop(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
light_fade_timer_stop();
|
||||
|
||||
if (g_light_status.mode != MODE_CTB) {
|
||||
uint16_t hue = 0;
|
||||
uint8_t saturation = 0;
|
||||
uint8_t value = 0;
|
||||
|
||||
ret = iot_led_stop_blink(CHANNEL_ID_RED);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_stop_blink, ret: %d", ret);
|
||||
|
||||
ret = iot_led_stop_blink(CHANNEL_ID_GREEN);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_stop_blink, ret: %d", ret);
|
||||
|
||||
ret = iot_led_stop_blink(CHANNEL_ID_BLUE);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_stop_blink, ret: %d", ret);
|
||||
|
||||
uint8_t red, green, blue;
|
||||
|
||||
ret = iot_led_get_channel(CHANNEL_ID_RED, &red);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_get_channel, ret: %d", ret);
|
||||
ret = iot_led_get_channel(CHANNEL_ID_GREEN, &green);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_get_channel, ret: %d", ret);
|
||||
ret = iot_led_get_channel(CHANNEL_ID_BLUE, &blue);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_get_channel, ret: %d", ret);
|
||||
|
||||
light_driver_rgb2hsv(red, green, blue, &hue, &saturation, &value);
|
||||
|
||||
g_light_status.hue = (g_fade_mode == MODE_HSV) ? hue : g_light_status.hue;
|
||||
g_light_status.value = (g_fade_mode == MODE_OFF || g_fade_mode == MODE_ON) ? value : g_light_status.value;
|
||||
} else {
|
||||
uint8_t color_temperature = 0;
|
||||
uint8_t brightness = 0;
|
||||
|
||||
ret = iot_led_stop_blink(CHANNEL_ID_COLD);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_stop_blink, ret: %d", ret);
|
||||
|
||||
ret = iot_led_stop_blink(CHANNEL_ID_WARM);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_stop_blink, ret: %d", ret);
|
||||
|
||||
uint8_t warm_tmp, cold_tmp;
|
||||
uint8_t tmp;
|
||||
|
||||
ret = iot_led_get_channel(CHANNEL_ID_WARM, &tmp);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_get_channel, ret: %d", ret);
|
||||
warm_tmp = (int32_t)tmp * 100 / 255;
|
||||
|
||||
ret = iot_led_get_channel(CHANNEL_ID_COLD, &tmp);
|
||||
LIGHT_ERROR_CHECK(ret < 0, ESP_FAIL, "iot_led_get_channel, ret: %d", ret);
|
||||
cold_tmp = (int32_t)tmp * 100 / 255;
|
||||
|
||||
color_temperature = (!warm_tmp) ? 0 : 100 / (cold_tmp / warm_tmp + 1);
|
||||
brightness = (!color_temperature) ? cold_tmp : warm_tmp * 100 / color_temperature;
|
||||
|
||||
g_light_status.brightness = (g_fade_mode == MODE_OFF || g_fade_mode == MODE_ON) ? brightness : g_light_status.brightness;
|
||||
g_light_status.color_temperature = (g_fade_mode == MODE_CTB) ? color_temperature : g_light_status.color_temperature;
|
||||
}
|
||||
|
||||
ret = ble_mesh_nvs_store(NVS_HANDLE, LIGHT_STATUS_STORE_KEY, &g_light_status, sizeof(light_status_t));
|
||||
LIGHT_ERROR_CHECK(ret < 0, ret, "ble_mesh_nvs_store, ret: %d", ret);
|
||||
|
||||
g_fade_mode = MODE_NONE;
|
||||
return ESP_OK;
|
||||
}
|
@@ -0,0 +1,105 @@
|
||||
/* board.c - Board-specific hooks */
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "iot_button.h"
|
||||
#include "board.h"
|
||||
#include "esp_timer.h"
|
||||
#include "lightbulb.h"
|
||||
|
||||
#define TAG "BOARD"
|
||||
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
|
||||
extern void example_ble_mesh_start_example_configuration(void);
|
||||
extern void example_ble_mesh_send_gen_onoff_set(bool by_df);
|
||||
extern uint8_t in_configuration_phase;
|
||||
esp_timer_handle_t led_timer_hdl;
|
||||
|
||||
void board_led_operation(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
ws2812_set_rgb_channel(r, g, b);
|
||||
}
|
||||
|
||||
static void led_timer_callback(void* arg)
|
||||
{
|
||||
board_led_operation(0,0,0);
|
||||
}
|
||||
|
||||
static void esp_led_timer_init(void)
|
||||
{
|
||||
const esp_timer_create_args_t led_timer_args = {
|
||||
.callback = &led_timer_callback,
|
||||
.arg = NULL,
|
||||
.name = "led timer",
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_timer_create(&led_timer_args, &led_timer_hdl));
|
||||
}
|
||||
|
||||
void board_led_operation_auto_close(uint8_t r, uint8_t g, uint8_t b, uint32_t ms)
|
||||
{
|
||||
esp_timer_stop(led_timer_hdl);
|
||||
board_led_operation(r,g,b);
|
||||
esp_timer_start_once(led_timer_hdl, ms * 1000);
|
||||
}
|
||||
|
||||
|
||||
static void board_led_init(void)
|
||||
{
|
||||
lightbulb_config_t config = {
|
||||
.type = DRIVER_WS2812,
|
||||
.driver_conf.ws2812.led_num = 3,
|
||||
.driver_conf.ws2812.ctrl_io = 8,
|
||||
.capability.enable_fades = true,
|
||||
.capability.fades_ms = 800,
|
||||
.capability.enable_status_storage = false,
|
||||
.capability.mode_mask = COLOR_MODE,
|
||||
.capability.storage_cb = NULL,
|
||||
.external_limit = NULL,
|
||||
.gamma_conf = NULL,
|
||||
.init_status.mode = WORK_COLOR,
|
||||
.init_status.on = false,
|
||||
.init_status.hue = 0,
|
||||
.init_status.saturation = 100,
|
||||
.init_status.value = 100,
|
||||
};
|
||||
lightbulb_init(&config);
|
||||
esp_led_timer_init();
|
||||
}
|
||||
|
||||
static void button_tap_cb(void* arg)
|
||||
{
|
||||
ESP_LOGI(TAG, "tap cb (%s)", (char *)arg);
|
||||
static bool use_df = true;
|
||||
if (in_configuration_phase) {
|
||||
example_ble_mesh_start_example_configuration();
|
||||
} else {
|
||||
example_ble_mesh_send_gen_onoff_set(use_df);
|
||||
use_df = !use_df;
|
||||
}
|
||||
}
|
||||
|
||||
static void board_button_init(void)
|
||||
{
|
||||
button_handle_t btn_handle = iot_button_create(BUTTON_IO_NUM, BUTTON_ACTIVE_LEVEL);
|
||||
if (btn_handle) {
|
||||
iot_button_set_evt_cb(btn_handle, BUTTON_CB_RELEASE, button_tap_cb, "RELEASE");
|
||||
}
|
||||
}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
board_led_init();
|
||||
board_button_init();
|
||||
}
|
@@ -0,0 +1,95 @@
|
||||
/* board.c - Board-specific hooks */
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "board.h"
|
||||
#include "esp_timer.h"
|
||||
#include "lightbulb.h"
|
||||
#include "iot_button.h"
|
||||
|
||||
#include "mesh/adapter.h"
|
||||
|
||||
#define TAG "BOARD"
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
|
||||
esp_timer_handle_t led_timer_hdl;
|
||||
|
||||
void board_led_operation(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
ws2812_set_rgb_channel(r, g, b);
|
||||
}
|
||||
|
||||
static void led_timer_callback(void* arg)
|
||||
{
|
||||
board_led_operation(0,0,0);
|
||||
}
|
||||
|
||||
static void esp_led_timer_init(void)
|
||||
{
|
||||
const esp_timer_create_args_t led_timer_args = {
|
||||
.callback = &led_timer_callback,
|
||||
.arg = NULL,
|
||||
.name = "led timer",
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_timer_create(&led_timer_args, &led_timer_hdl));
|
||||
}
|
||||
|
||||
void board_led_operation_auto_close(uint8_t r, uint8_t g, uint8_t b, uint32_t ms)
|
||||
{
|
||||
esp_timer_stop(led_timer_hdl);
|
||||
board_led_operation(r,g,b);
|
||||
esp_timer_start_once(led_timer_hdl, ms * 1000);
|
||||
}
|
||||
|
||||
static void board_led_init(void)
|
||||
{
|
||||
lightbulb_config_t config = {
|
||||
.type = DRIVER_WS2812,
|
||||
.driver_conf.ws2812.led_num = 3,
|
||||
.driver_conf.ws2812.ctrl_io = 8,
|
||||
.capability.enable_fades = true,
|
||||
.capability.fades_ms = 800,
|
||||
.capability.enable_status_storage = false,
|
||||
.capability.mode_mask = COLOR_MODE,
|
||||
.capability.storage_cb = NULL,
|
||||
.external_limit = NULL,
|
||||
.gamma_conf = NULL,
|
||||
.init_status.mode = WORK_COLOR,
|
||||
.init_status.on = false,
|
||||
.init_status.hue = 0,
|
||||
.init_status.saturation = 100,
|
||||
.init_status.value = 100,
|
||||
};
|
||||
lightbulb_init(&config);
|
||||
esp_led_timer_init();
|
||||
}
|
||||
|
||||
static void button_tap_cb(void* arg)
|
||||
{
|
||||
ESP_LOGI(TAG, "tap cb (%s)", (char *)arg);
|
||||
}
|
||||
|
||||
static void board_button_init(void)
|
||||
{
|
||||
button_handle_t btn_handle = iot_button_create(BUTTON_IO_NUM, BUTTON_ACTIVE_LEVEL);
|
||||
if (btn_handle) {
|
||||
iot_button_set_evt_cb(btn_handle, BUTTON_CB_RELEASE, button_tap_cb, "RELEASE");
|
||||
}
|
||||
}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
board_led_init();
|
||||
board_button_init();
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
/* board.c - Board-specific hooks */
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "iot_button.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "lightbulb.h"
|
||||
#include "esp_log.h"
|
||||
#include "board.h"
|
||||
|
||||
#define TAG "BOARD"
|
||||
|
||||
#define BUTTON_ACTIVE_LEVEL 0
|
||||
|
||||
extern uint8_t click_to_send_onoff_set;
|
||||
extern void example_ble_mesh_send_gen_onoff_set(uint8_t onoff);
|
||||
extern void example_ble_mesh_send_remote_provisioning_scan_start(void);
|
||||
|
||||
void board_led_operation(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
#ifdef BLE_MESH_LED_STRIP_IO
|
||||
ws2812_set_rgb_channel(r, g, b);
|
||||
#else
|
||||
gpio_set_level(LED_R, r);
|
||||
gpio_set_level(LED_G, g);
|
||||
gpio_set_level(LED_B, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void board_led_init(void)
|
||||
{
|
||||
#ifdef BLE_MESH_LED_STRIP_IO
|
||||
lightbulb_config_t config = {
|
||||
.type = DRIVER_WS2812,
|
||||
.driver_conf.ws2812.led_num = 3,
|
||||
.driver_conf.ws2812.ctrl_io = 8,
|
||||
.capability.enable_fades = true,
|
||||
.capability.fades_ms = 800,
|
||||
.capability.enable_status_storage = false,
|
||||
.capability.mode_mask = COLOR_MODE,
|
||||
.capability.storage_cb = NULL,
|
||||
.external_limit = NULL,
|
||||
.gamma_conf = NULL,
|
||||
.init_status.mode = WORK_COLOR,
|
||||
.init_status.on = false,
|
||||
.init_status.hue = 0,
|
||||
.init_status.saturation = 100,
|
||||
.init_status.value = 100,
|
||||
};
|
||||
lightbulb_init(&config);
|
||||
ws2812_set_rgb_channel(LED_OFF, LED_OFF, LED_OFF);
|
||||
#else
|
||||
gpio_set_level(LED_R, LED_OFF);
|
||||
gpio_set_level(LED_G, LED_OFF);
|
||||
gpio_set_level(LED_B, LED_OFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void button_tap_cb(void* arg)
|
||||
{
|
||||
static uint8_t onoff = 1;
|
||||
ESP_LOGI(TAG, "tap cb (%s)", (char *)arg);
|
||||
if (click_to_send_onoff_set) {
|
||||
example_ble_mesh_send_gen_onoff_set(onoff);
|
||||
onoff = !onoff;
|
||||
} else {
|
||||
example_ble_mesh_send_remote_provisioning_scan_start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void board_button_init(void)
|
||||
{
|
||||
button_handle_t btn_handle = iot_button_create(BUTTON_IO_NUM, BUTTON_ACTIVE_LEVEL);
|
||||
if (btn_handle) {
|
||||
iot_button_set_evt_cb(btn_handle, BUTTON_CB_RELEASE, button_tap_cb, "RELEASE");
|
||||
}
|
||||
}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
board_led_init();
|
||||
board_button_init();
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/* board.c - Board-specific hooks */
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "lightbulb.h"
|
||||
#include "esp_log.h"
|
||||
#include "board.h"
|
||||
|
||||
#define TAG "BOARD"
|
||||
|
||||
void board_led_operation(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
#ifdef BLE_MESH_LED_STRIP_IO
|
||||
ws2812_set_rgb_channel(r, g, b);
|
||||
#else
|
||||
gpio_set_level(LED_R, r);
|
||||
gpio_set_level(LED_G, g);
|
||||
gpio_set_level(LED_B, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void board_led_init(void)
|
||||
{
|
||||
#ifdef BLE_MESH_LED_STRIP_IO
|
||||
lightbulb_config_t config = {
|
||||
.type = DRIVER_WS2812,
|
||||
.driver_conf.ws2812.led_num = 3,
|
||||
.driver_conf.ws2812.ctrl_io = 8,
|
||||
.capability.enable_fades = true,
|
||||
.capability.fades_ms = 800,
|
||||
.capability.enable_status_storage = false,
|
||||
.capability.mode_mask = COLOR_MODE,
|
||||
.capability.storage_cb = NULL,
|
||||
.external_limit = NULL,
|
||||
.gamma_conf = NULL,
|
||||
.init_status.mode = WORK_COLOR,
|
||||
.init_status.on = false,
|
||||
.init_status.hue = 0,
|
||||
.init_status.saturation = 100,
|
||||
.init_status.value = 100,
|
||||
};
|
||||
lightbulb_init(&config);
|
||||
ws2812_set_rgb_channel(LED_OFF, LED_OFF, LED_OFF);
|
||||
#else
|
||||
gpio_set_level(LED_R, LED_OFF);
|
||||
gpio_set_level(LED_G, LED_OFF);
|
||||
gpio_set_level(LED_B, LED_OFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
board_led_init();
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/* board.c - Board-specific hooks */
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "lightbulb.h"
|
||||
#include "esp_log.h"
|
||||
#include "board.h"
|
||||
|
||||
#define TAG "BOARD"
|
||||
|
||||
void board_led_operation(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
#ifdef BLE_MESH_LED_STRIP_IO
|
||||
ws2812_set_rgb_channel(r, g, b);
|
||||
#else
|
||||
gpio_set_level(LED_R, r);
|
||||
gpio_set_level(LED_G, g);
|
||||
gpio_set_level(LED_B, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void board_led_init(void)
|
||||
{
|
||||
#ifdef BLE_MESH_LED_STRIP_IO
|
||||
lightbulb_config_t config = {
|
||||
.type = DRIVER_WS2812,
|
||||
.driver_conf.ws2812.led_num = 3,
|
||||
.driver_conf.ws2812.ctrl_io = 8,
|
||||
.capability.enable_fades = true,
|
||||
.capability.fades_ms = 800,
|
||||
.capability.enable_status_storage = false,
|
||||
.capability.mode_mask = COLOR_MODE,
|
||||
.capability.storage_cb = NULL,
|
||||
.external_limit = NULL,
|
||||
.gamma_conf = NULL,
|
||||
.init_status.mode = WORK_COLOR,
|
||||
.init_status.on = false,
|
||||
.init_status.hue = 0,
|
||||
.init_status.saturation = 100,
|
||||
.init_status.value = 100,
|
||||
};
|
||||
lightbulb_init(&config);
|
||||
ws2812_set_rgb_channel(LED_OFF, LED_OFF, LED_OFF);
|
||||
#else
|
||||
gpio_set_level(LED_R, LED_OFF);
|
||||
gpio_set_level(LED_G, LED_OFF);
|
||||
gpio_set_level(LED_B, LED_OFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
board_led_init();
|
||||
}
|
Reference in New Issue
Block a user