From bb4f1084dea34758e36c9759335cea088fd12a94 Mon Sep 17 00:00:00 2001 From: Shi Xin Ke Date: Wed, 22 May 2024 17:38:45 +0800 Subject: [PATCH 1/4] feat(lightbulb): The effect interface no longer supports actions with a period of 0ms --- components/led/lightbulb_driver/src/hal_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/led/lightbulb_driver/src/hal_driver.c b/components/led/lightbulb_driver/src/hal_driver.c index a3cf112a1..a817aba2a 100644 --- a/components/led/lightbulb_driver/src/hal_driver.c +++ b/components/led/lightbulb_driver/src/hal_driver.c @@ -822,7 +822,7 @@ esp_err_t hal_set_channel_group(uint16_t value[], uint8_t channel_mask, uint16_t esp_err_t hal_start_channel_action(int channel, uint16_t value_min, uint16_t value_max, uint16_t period_ms, bool fade_flag) { LIGHTBULB_CHECK(s_hal_obj, "init() must be called first", return ESP_ERR_INVALID_STATE); - LIGHTBULB_CHECK((period_ms > CHANGE_RATE_MS * 2) || (period_ms == 0), "period_ms not allowed", return ESP_ERR_INVALID_ARG); + LIGHTBULB_CHECK(period_ms > CHANGE_RATE_MS * 2, "period_ms not allowed", return ESP_ERR_INVALID_ARG); #ifdef FADE_TICKS_FROM_GPTIMER if (s_hal_obj->gptimer_is_active) { @@ -900,7 +900,7 @@ esp_err_t hal_start_channel_action(int channel, uint16_t value_min, uint16_t val esp_err_t hal_start_channel_group_action(uint16_t value_min[], uint16_t value_max[], uint8_t channel_mask, uint16_t period_ms, bool fade_flag) { LIGHTBULB_CHECK(s_hal_obj, "init() must be called first", return ESP_ERR_INVALID_STATE); - LIGHTBULB_CHECK((period_ms > CHANGE_RATE_MS * 2) || (period_ms == 0), "period_ms not allowed", return ESP_ERR_INVALID_ARG); + LIGHTBULB_CHECK(period_ms > CHANGE_RATE_MS * 2, "period_ms not allowed", return ESP_ERR_INVALID_ARG); #ifdef FADE_TICKS_FROM_GPTIMER if (s_hal_obj->gptimer_is_active) { From 6ee803df43e85e20ef651d60b2a0c48f758a6450 Mon Sep 17 00:00:00 2001 From: Shi Xin Ke Date: Wed, 22 May 2024 17:41:02 +0800 Subject: [PATCH 2/4] Refactor(lightbulb): Refactor the KP18058 code to facilitate configuration by referring to the datasheet --- .../drivers/kp18058/kp18058.c | 75 ++++++++++--------- .../drivers/kp18058/kp18058.h | 4 +- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/components/led/lightbulb_driver/drivers/kp18058/kp18058.c b/components/led/lightbulb_driver/drivers/kp18058/kp18058.c index c35f560ed..301b6ca7c 100644 --- a/components/led/lightbulb_driver/drivers/kp18058/kp18058.c +++ b/components/led/lightbulb_driver/drivers/kp18058/kp18058.c @@ -81,8 +81,8 @@ static const char *TAG = "kp18058"; #define BIT_DISABLE_CHOPPING_CONTROL 0x00 /* B[6] */ -#define BIT_ENABLE_RC_FILTER 0x40 -#define BIT_DISABLE_RC_FILTER 0x00 +#define BIT_ENABLE_RC_FILTER 0x00 +#define BIT_DISABLE_RC_FILTER 0x40 /* B[5:1] */ #define BIT_DEFAULT_OUT4_5_CURRENT 0x00 @@ -152,9 +152,9 @@ static esp_err_t set_init_data(void) uint8_t addr = BASE_ADDR | BIT_ALL_CHANNEL | BIT_NEXT_BYTE1; uint8_t value[3] = { 0 }; - memcpy(&value[0], s_kp18058->fixed_bit, sizeof(value)); + memcpy(&value[0], s_kp18058->fixed_bit, sizeof(value) / sizeof(uint8_t)); - return _write(addr, value, sizeof(value)); + return _write(addr, value, sizeof(value) / sizeof(uint8_t)); } esp_err_t kp18058_set_standby_mode(bool enable_standby) @@ -169,7 +169,7 @@ esp_err_t kp18058_set_standby_mode(bool enable_standby) addr = BASE_ADDR | BIT_ALL_CHANNEL | BIT_NEXT_BYTE4; } - return _write(addr, value, sizeof(value)); + return _write(addr, value, sizeof(value) / sizeof(uint8_t)); } esp_err_t kp18058_set_shutdown(void) @@ -364,41 +364,44 @@ esp_err_t kp18058_init(driver_kp18058_t *config, void(*hook_func)(void *)) DRIVER_CHECK(s_kp18058, "alloc fail", return ESP_ERR_NO_MEM); memset(s_kp18058->mapping_addr, INVALID_ADDR, KP18058_MAX_PIN); - // The following configuration defaults value are from the KP18058 data sheet - // Byte 1 - if (config->enable_custom_param && config->custom_param.disable_voltage_compensation) { - s_kp18058->fixed_bit[0] |= BIT_DISABLE_COMPENSATION; - } else if (config->enable_custom_param && !config->custom_param.disable_voltage_compensation) { - DRIVER_CHECK((config->custom_param.compensation != KP18058_COMPENSATION_VOLTAGE_INVALID) && (config->custom_param.slope != KP18058_SLOPE_INVALID), "Voltage compensation and slope are incorrect", goto EXIT); - s_kp18058->fixed_bit[0] |= BIT_ENABLE_COMPENSATION; - s_kp18058->fixed_bit[0] |= config->custom_param.compensation << 3; - s_kp18058->fixed_bit[0] |= config->custom_param.slope << 1; - } else { - s_kp18058->fixed_bit[0] |= BIT_ENABLE_COMPENSATION; - s_kp18058->fixed_bit[0] |= BIT_DEFAULT_COMPENSATION_VOLTAGE; - s_kp18058->fixed_bit[0] |= BIT_DEFAULT_SLOPE_LEVEL; - } + // Custom configuration + if (config->enable_custom_param) { + // Byte 1 + if (config->custom_param.enable_voltage_compensation) { + DRIVER_CHECK((config->custom_param.compensation != KP18058_COMPENSATION_VOLTAGE_INVALID) && (config->custom_param.slope != KP18058_SLOPE_INVALID), "Voltage compensation and slope are incorrect", goto EXIT); + s_kp18058->fixed_bit[0] |= BIT_ENABLE_COMPENSATION; + s_kp18058->fixed_bit[0] |= config->custom_param.compensation << 3; + s_kp18058->fixed_bit[0] |= config->custom_param.slope << 1; + } else { + s_kp18058->fixed_bit[0] |= BIT_DISABLE_COMPENSATION; + } - // Byte 2 - if (config->enable_custom_param && !config->custom_param.disable_chopping_dimming) { - DRIVER_CHECK(config->custom_param.chopping_freq != KP18058_CHOPPING_INVALID, "Chopping freq is incorrect", goto EXIT); - s_kp18058->fixed_bit[1] |= config->custom_param.chopping_freq << 6; - } else { - s_kp18058->fixed_bit[1] |= BIT_DEFAULT_CHOPPING_FREQ_1KHZ; - } - s_kp18058->fixed_bit[1] |= (config->rgb_current_multiple) << 1; + // Byte 2 + if (config->custom_param.enable_chopping_dimming) { + DRIVER_CHECK(config->custom_param.chopping_freq != KP18058_CHOPPING_INVALID, "Chopping freq is incorrect", goto EXIT); + s_kp18058->fixed_bit[1] |= config->custom_param.chopping_freq << 6; + } + + // Byte 3 + if (config->custom_param.enable_chopping_dimming) { + s_kp18058->fixed_bit[2] |= BIT_ENABLE_CHOPPING_CONTROL; + } else { + s_kp18058->fixed_bit[2] |= BIT_DISABLE_CHOPPING_CONTROL; + } + if (config->custom_param.enable_rc_filter) { + s_kp18058->fixed_bit[2] |= BIT_ENABLE_RC_FILTER; + } else { + s_kp18058->fixed_bit[2] |= BIT_DISABLE_RC_FILTER; + } - // Byte 3 - if (config->enable_custom_param && config->custom_param.disable_chopping_dimming) { - s_kp18058->fixed_bit[2] |= BIT_DISABLE_CHOPPING_CONTROL; - } else { - s_kp18058->fixed_bit[2] |= BIT_ENABLE_CHOPPING_CONTROL; - } - if (config->enable_custom_param && config->custom_param.enable_rc_filter) { - s_kp18058->fixed_bit[2] |= BIT_ENABLE_RC_FILTER; } else { - s_kp18058->fixed_bit[2] |= BIT_DISABLE_RC_FILTER; + // The following configuration defaults value are from the KP18058 datasheet + s_kp18058->fixed_bit[0] = BIT_ENABLE_COMPENSATION | BIT_DEFAULT_COMPENSATION_VOLTAGE | BIT_DEFAULT_SLOPE_LEVEL; + s_kp18058->fixed_bit[1] = BIT_DEFAULT_CHOPPING_FREQ_1KHZ | BIT_DEFAULT_OUT1_3_CURRENT; + s_kp18058->fixed_bit[2] = BIT_ENABLE_CHOPPING_CONTROL | BIT_ENABLE_RC_FILTER | BIT_DEFAULT_OUT4_5_CURRENT; } + + s_kp18058->fixed_bit[1] |= (config->rgb_current_multiple) << 1; s_kp18058->fixed_bit[2] |= (config->cw_current_multiple) << 1; if (config->iic_freq_khz > 300) { diff --git a/components/led/lightbulb_driver/drivers/kp18058/kp18058.h b/components/led/lightbulb_driver/drivers/kp18058/kp18058.h index 9e9d50413..054d54a11 100644 --- a/components/led/lightbulb_driver/drivers/kp18058/kp18058.h +++ b/components/led/lightbulb_driver/drivers/kp18058/kp18058.h @@ -71,8 +71,8 @@ typedef struct { kp18058_compensation_t compensation; kp18058_slope_t slope; kp18058_chopping_freq_t chopping_freq; - bool disable_voltage_compensation : 1; - bool disable_chopping_dimming : 1; + bool enable_voltage_compensation : 1; + bool enable_chopping_dimming : 1; // If set to false, it is analog dimming. bool enable_rc_filter : 1; } custom_param; } driver_kp18058_t; From a7d478b125173308b0123c32c71ecbcc607615a7 Mon Sep 17 00:00:00 2001 From: Shi Xin Ke Date: Wed, 22 May 2024 17:43:51 +0800 Subject: [PATCH 3/4] feat(lightbulb): Add more printing to facilitate debugging --- components/led/lightbulb_driver/CHANGELOG.md | 8 ++ .../led/lightbulb_driver/idf_component.yml | 2 +- .../led/lightbulb_driver/src/lightbulb.c | 84 +++++++++++++++++-- 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/components/led/lightbulb_driver/CHANGELOG.md b/components/led/lightbulb_driver/CHANGELOG.md index e0352a1d9..3dc25a289 100644 --- a/components/led/lightbulb_driver/CHANGELOG.md +++ b/components/led/lightbulb_driver/CHANGELOG.md @@ -1,5 +1,13 @@ # ChangeLog +## v1.2.0 - 2024-05-22 + +### Enhancements: + +* Add more printing to facilitate debugging +* Refactor the KP18058 code to facilitate configuration by referring to the datasheet +* The effect interface no longer supports actions with a period of 0ms + ## v1.1.5 - 2024-05-10 ### Improvement: diff --git a/components/led/lightbulb_driver/idf_component.yml b/components/led/lightbulb_driver/idf_component.yml index 307e4e8e4..b894c3484 100644 --- a/components/led/lightbulb_driver/idf_component.yml +++ b/components/led/lightbulb_driver/idf_component.yml @@ -1,4 +1,4 @@ -version: "1.1.5" +version: "1.2.0" description: Provide multiple dimming driver solutions to easily build lightbulb applications url: https://github.com/espressif/esp-iot-solution/tree/master/components/led/lightbulb_driver dependencies: diff --git a/components/led/lightbulb_driver/src/lightbulb.c b/components/led/lightbulb_driver/src/lightbulb.c index fca88fa70..9620e4a1c 100644 --- a/components/led/lightbulb_driver/src/lightbulb.c +++ b/components/led/lightbulb_driver/src/lightbulb.c @@ -558,14 +558,12 @@ static bool mix_table_data_check(void) return result; } -static void print_func(void *priv) +static void print_func(char *driver_details, char *driver_io) { - char *name; - - hal_get_driver_feature(QUERY_DRIVER_NAME, &name); - ESP_LOGI(TAG, "---------------------------------------------------------------------"); - ESP_LOGI(TAG, "lightbulb driver component version: %d.%d.%d", LIGHTBULB_DRIVER_VER_MAJOR, LIGHTBULB_DRIVER_VER_MINOR, LIGHTBULB_DRIVER_VER_PATCH); - ESP_LOGI(TAG, "driver name: %s", name); + ESP_LOGI(TAG, "----------------------Lightbulb Driver Component-----------------------------"); + ESP_LOGI(TAG, "version: %d.%d.%d", LIGHTBULB_DRIVER_VER_MAJOR, LIGHTBULB_DRIVER_VER_MINOR, LIGHTBULB_DRIVER_VER_PATCH); + ESP_LOGI(TAG, "%s", driver_details); + ESP_LOGI(TAG, "%s", driver_io); ESP_LOGI(TAG, "low power control: %s", s_lb_obj->cap.enable_lowpower ? "enable" : "disable"); ESP_LOGI(TAG, "status storage: %s", s_lb_obj->cap.enable_status_storage ? "enable" : "disable"); ESP_LOGI(TAG, "status storage delay %d ms", s_lb_obj->cap.enable_status_storage == true ? s_lb_obj->cap.storage_delay_ms : 0); @@ -621,41 +619,111 @@ esp_err_t lightbulb_init(lightbulb_config_t *config) // hal configuration void *driver_conf = NULL; + char driver_details[224] = {0}; + char driver_io[32] = {0}; #ifdef CONFIG_ENABLE_PWM_DRIVER if (config->type == DRIVER_ESP_PWM) { driver_conf = (void *) & (config->driver_conf.pwm); + bool invert_level = 0; +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)) + invert_level = config->driver_conf.pwm.invert_level; +#endif + sprintf(driver_details, "Pwm Freq: %d Hz, Phase Delay Flag: %d, Invert Level: %d", config->driver_conf.pwm.freq_hz, config->driver_conf.pwm.phase_delay.flag, invert_level); } #endif #ifdef CONFIG_ENABLE_SM2135EH_DRIVER if (config->type == DRIVER_SM2135EH) { driver_conf = (void *) & (config->driver_conf.sm2135eh); + sprintf(driver_details, "SM2135EH IIC Freq: %d Khz, Queue: %d, SCL: %d, SDA: %d, RGB Current: %d, WY Current: %d", + config->driver_conf.sm2135eh.freq_khz, + config->driver_conf.sm2135eh.enable_iic_queue, + config->driver_conf.sm2135eh.iic_clk, + config->driver_conf.sm2135eh.iic_sda, + config->driver_conf.sm2135eh.rgb_current, + config->driver_conf.sm2135eh.wy_current); } #endif #ifdef CONFIG_ENABLE_BP57x8D_DRIVER if (config->type == DRIVER_BP57x8D) { driver_conf = (void *) & (config->driver_conf.bp57x8d); + sprintf(driver_details, "BP57x8D IIC Freq: %d Khz, Queue: %d, SCL: %d, SDA: %d, Current List:[%d %d %d %d %d]", + config->driver_conf.bp57x8d.freq_khz, + config->driver_conf.bp57x8d.enable_iic_queue, + config->driver_conf.bp57x8d.iic_clk, + config->driver_conf.bp57x8d.iic_sda, + config->driver_conf.bp57x8d.current[0], + config->driver_conf.bp57x8d.current[1], + config->driver_conf.bp57x8d.current[2], + config->driver_conf.bp57x8d.current[3], + config->driver_conf.bp57x8d.current[4]); } #endif #ifdef CONFIG_ENABLE_BP1658CJ_DRIVER if (config->type == DRIVER_BP1658CJ) { driver_conf = (void *) & (config->driver_conf.bp1658cj); + sprintf(driver_details, "BP1658CJ IIC Freq: %d Khz, Queue: %d, SCL: %d, SDA: %d, RGB Current: %d, CW Current: %d", + config->driver_conf.bp1658cj.freq_khz, + config->driver_conf.bp1658cj.enable_iic_queue, + config->driver_conf.bp1658cj.iic_clk, + config->driver_conf.bp1658cj.iic_sda, + config->driver_conf.bp1658cj.rgb_current, + config->driver_conf.bp1658cj.cw_current); } #endif #ifdef CONFIG_ENABLE_KP18058_DRIVER if (config->type == DRIVER_KP18058) { driver_conf = (void *) & (config->driver_conf.kp18058); + sprintf(driver_details, "KP18058 IIC Freq: %d Khz, Queue: %d, SCL: %d, SDA: %d, RGB Current Multiple: %d, CW Current Multiple: %d, Enable Custom Param: %d", + config->driver_conf.kp18058.iic_freq_khz, + config->driver_conf.kp18058.enable_iic_queue, + config->driver_conf.kp18058.iic_clk, + config->driver_conf.kp18058.iic_sda, + config->driver_conf.kp18058.rgb_current_multiple, + config->driver_conf.kp18058.cw_current_multiple, + config->driver_conf.kp18058.enable_custom_param); + if (config->driver_conf.kp18058.enable_custom_param) { + int offset = strlen(driver_details); + sprintf(&driver_details[offset], "\r\n\t\t\tCompensation: %d, Slope, %d, Chopping Freq: %d, Enable Compensation: %d, Enable Chopping Dimming: %d, Enable RC Filter: %d", + config->driver_conf.kp18058.custom_param.compensation, + config->driver_conf.kp18058.custom_param.slope, + config->driver_conf.kp18058.custom_param.chopping_freq, + config->driver_conf.kp18058.custom_param.enable_voltage_compensation, + config->driver_conf.kp18058.custom_param.enable_chopping_dimming, + config->driver_conf.kp18058.custom_param.enable_rc_filter); + } } #endif #ifdef CONFIG_ENABLE_SM2x35EGH_DRIVER if (config->type == DRIVER_SM2x35EGH) { driver_conf = (void *) & (config->driver_conf.sm2x35egh); + sprintf(driver_details, "SM2x35EGH IIC Freq: %d Khz, Queue: %d, SCL: %d, SDA: %d, RGB Current: %d, CW Current: %d", + config->driver_conf.sm2x35egh.freq_khz, + config->driver_conf.sm2x35egh.enable_iic_queue, + config->driver_conf.sm2x35egh.iic_clk, + config->driver_conf.sm2x35egh.iic_sda, + config->driver_conf.sm2x35egh.rgb_current, + config->driver_conf.sm2x35egh.cw_current); } #endif #ifdef CONFIG_ENABLE_WS2812_DRIVER if (config->type == DRIVER_WS2812) { driver_conf = (void *) & (config->driver_conf.ws2812); + sprintf(driver_details, "WS2812 Led Num: %d", config->driver_conf.ws2812.led_num); + sprintf(driver_io, "IO List:[%d]", config->driver_conf.ws2812.ctrl_io); } #endif + + if (config->type == DRIVER_ESP_PWM) { + sprintf(driver_io, "IO List:[%d %d %d %d %d]", config->io_conf.pwm_io.red, config->io_conf.pwm_io.green, config->io_conf.pwm_io.blue, config->io_conf.pwm_io.cold_cct, config->io_conf.pwm_io.warm_brightness); + } else if (config->type >= DRIVER_SM2135E && config->type < DRIVER_WS2812) { + sprintf(driver_io, "IO List:[%d %d %d %d %d]", config->io_conf.iic_io.red, config->io_conf.iic_io.green, config->io_conf.iic_io.blue, config->io_conf.iic_io.cold_white, config->io_conf.iic_io.warm_yellow); + } else if (config->type == DRIVER_WS2812) { + // Nothing + } else { + ESP_LOGW(TAG, "The driver has not been updated to the component"); + abort(); + } + // Config check if (config->type != DRIVER_ESP_PWM && config->type != DRIVER_WS2812) { if (config->capability.enable_hardware_cct == true) { @@ -862,7 +930,7 @@ esp_err_t lightbulb_init(lightbulb_config_t *config) } } - print_func(config); + print_func(driver_details, driver_io); return ESP_OK; From 6f413141655784cddf4c9e7656aaa2b00835ef03 Mon Sep 17 00:00:00 2001 From: Shi Xin Ke Date: Mon, 27 May 2024 11:30:48 +0800 Subject: [PATCH 4/4] feat(lightbulb): Update the threshold for triggering HAL forced stop when lower layer transmission fails to 6. After the update, HAL forced stop fade will only be triggered if all 5 channels fail --- components/led/lightbulb_driver/src/hal_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/led/lightbulb_driver/src/hal_driver.c b/components/led/lightbulb_driver/src/hal_driver.c index a817aba2a..98d044e3a 100644 --- a/components/led/lightbulb_driver/src/hal_driver.c +++ b/components/led/lightbulb_driver/src/hal_driver.c @@ -53,7 +53,7 @@ static void gpio_reverse(int gpio_num) #define MAX_TABLE_SIZE (256) // Maximum size for linear and gamma correction tables. #define DEFAULT_CURVE_COE (1.0) // Default coefficient for gamma correction curve. #define HAL_OUT_MAX_CHANNEL (5) // Maximum number of output channels in the Hardware Abstraction Layer (HAL). -#define ERROR_COUNT_THRESHOLD (1) // Threshold for errors in the lower interface. +#define ERROR_COUNT_THRESHOLD (6) // Threshold for errors in the lower interface. typedef esp_err_t (*x_init_t)(void *config, void(*hook_func)(void *)); typedef esp_err_t (*x_regist_channel_t)(int channel, int value);