#include "light_driver.h" #include #include "driver/ledc.h" #include "esp_log.h" #include "esp_err.h" #include static const char* TAG = "light_driver"; static const uint8_t light_gpio = 15; static const uint16_t light_pwm_freq = 20000; static const ledc_channel_t light_ledc_channel = LEDC_CHANNEL_0; static const ledc_mode_t light_ledc_mode = LEDC_LOW_SPEED_MODE; static const ledc_timer_bit_t light_pwm_resolution = LEDC_TIMER_10_BIT; static const uint32_t light_max_brightness = (1 << light_pwm_resolution) - 1; static const uint32_t light_max_level = 254; // zigbee light level, goes from 0 to 254 static bool light_init_done = false; static uint8_t light_current_level = 0; esp_err_t light_driver_set_level(const uint8_t level, const uint16_t transition_ms) { if (!light_init_done) { ESP_LOGW(TAG, "light driver not ready!"); return ESP_FAIL; } light_current_level = level; double brightness = (double)light_current_level / (double)light_max_level; if (brightness > 1) brightness = 1; if (brightness < 0) brightness = 0; const uint32_t duty = (uint32_t)(light_max_brightness * brightness * brightness); // brightness^2 for fast gamma correction ESP_ERROR_CHECK(ledc_set_fade_with_time(light_ledc_mode, light_ledc_channel, duty, transition_ms)); ESP_ERROR_CHECK(ledc_fade_start(light_ledc_mode, light_ledc_channel, LEDC_FADE_NO_WAIT)); return ESP_OK; } esp_err_t light_driver_set_power(const bool power, const uint16_t transition_ms) { return light_driver_set_level(power ? light_current_level : 0, transition_ms); } esp_err_t light_driver_init(const bool default_state) { const ledc_timer_config_t ledc_timer = { .speed_mode = light_ledc_mode, .duty_resolution = light_pwm_resolution, .timer_num = LEDC_TIMER_2, .freq_hz = light_pwm_freq, .clk_cfg = LEDC_AUTO_CLK }; const ledc_channel_config_t ledc_channel = { .speed_mode = ledc_timer.speed_mode, .channel = light_ledc_channel, .timer_sel = ledc_timer.timer_num, .intr_type = LEDC_INTR_DISABLE, .gpio_num = light_gpio, .duty = 0, // Set duty to 0% .hpoint = 0 }; ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); ESP_ERROR_CHECK(ledc_fade_func_install(0)); ESP_LOGI(TAG, "light driver inited, f=%d Hz", light_pwm_freq); light_init_done = true; light_driver_set_power(default_state, 100); return ESP_OK; }