You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.4 KiB

3 weeks ago
#include "backlight.h"
#include "settings.h"
#include <esp_log.h>
#include <driver/ledc.h>
#define TAG "Backlight"
Backlight::Backlight() {
// 创建背光渐变定时器
const esp_timer_create_args_t timer_args = {
.callback = [](void* arg) {
auto self = static_cast<Backlight*>(arg);
self->OnTransitionTimer();
},
.arg = this,
.dispatch_method = ESP_TIMER_TASK,
.name = "backlight_timer",
.skip_unhandled_events = true,
};
ESP_ERROR_CHECK(esp_timer_create(&timer_args, &transition_timer_));
}
Backlight::~Backlight() {
if (transition_timer_ != nullptr) {
esp_timer_stop(transition_timer_);
esp_timer_delete(transition_timer_);
}
}
void Backlight::RestoreBrightness() {
// Load brightness from settings
Settings settings("display");
int saved_brightness = settings.GetInt("brightness", 75);
// 检查亮度值是否为0或过小设置默认值
if (saved_brightness <= 0) {
ESP_LOGW(TAG, "Brightness value (%d) is too small, setting to default (10)", saved_brightness);
saved_brightness = 10; // 设置一个较低的默认值
}
SetBrightness(saved_brightness);
}
void Backlight::SetBrightness(uint8_t brightness, bool permanent) {
if (brightness > 100) {
brightness = 100;
}
if (brightness_ == brightness) {
return;
}
if (permanent) {
Settings settings("display", true);
settings.SetInt("brightness", brightness);
}
target_brightness_ = brightness;
step_ = (target_brightness_ > brightness_) ? 1 : -1;
if (transition_timer_ != nullptr) {
// 启动定时器,每 5ms 更新一次
esp_timer_start_periodic(transition_timer_, 5 * 1000);
}
ESP_LOGI(TAG, "Set brightness to %d", brightness);
}
void Backlight::OnTransitionTimer() {
if (brightness_ == target_brightness_) {
esp_timer_stop(transition_timer_);
return;
}
brightness_ += step_;
SetBrightnessImpl(brightness_);
if (brightness_ == target_brightness_) {
esp_timer_stop(transition_timer_);
}
}
PwmBacklight::PwmBacklight(gpio_num_t pin, bool output_invert) : Backlight() {
const ledc_timer_config_t backlight_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_10_BIT,
.timer_num = LEDC_TIMER_0,
.freq_hz = 25000, //背光pwm频率需要高一点防止电感啸叫
.clk_cfg = LEDC_AUTO_CLK,
.deconfigure = false
};
ESP_ERROR_CHECK(ledc_timer_config(&backlight_timer));
// Setup LEDC peripheral for PWM backlight control
const ledc_channel_config_t backlight_channel = {
.gpio_num = pin,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LEDC_CHANNEL_0,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = LEDC_TIMER_0,
.duty = 0,
.hpoint = 0,
.flags = {
.output_invert = output_invert,
}
};
ESP_ERROR_CHECK(ledc_channel_config(&backlight_channel));
}
PwmBacklight::~PwmBacklight() {
ledc_stop(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0);
}
void PwmBacklight::SetBrightnessImpl(uint8_t brightness) {
// LEDC resolution set to 10bits, thus: 100% = 1023
uint32_t duty_cycle = (1023 * brightness) / 100;
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty_cycle);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
}