backlight.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "backlight.h"
  2. #include "settings.h"
  3. #include <esp_log.h>
  4. #include <driver/ledc.h>
  5. #define TAG "Backlight"
  6. Backlight::Backlight() {
  7. // 创建背光渐变定时器
  8. const esp_timer_create_args_t timer_args = {
  9. .callback = [](void* arg) {
  10. auto self = static_cast<Backlight*>(arg);
  11. self->OnTransitionTimer();
  12. },
  13. .arg = this,
  14. .dispatch_method = ESP_TIMER_TASK,
  15. .name = "backlight_timer",
  16. .skip_unhandled_events = true,
  17. };
  18. ESP_ERROR_CHECK(esp_timer_create(&timer_args, &transition_timer_));
  19. }
  20. Backlight::~Backlight() {
  21. if (transition_timer_ != nullptr) {
  22. esp_timer_stop(transition_timer_);
  23. esp_timer_delete(transition_timer_);
  24. }
  25. }
  26. void Backlight::RestoreBrightness() {
  27. // Load brightness from settings
  28. Settings settings("display");
  29. int saved_brightness = settings.GetInt("brightness", 75);
  30. // 检查亮度值是否为0或过小,设置默认值
  31. if (saved_brightness <= 0) {
  32. ESP_LOGW(TAG, "Brightness value (%d) is too small, setting to default (10)", saved_brightness);
  33. saved_brightness = 10; // 设置一个较低的默认值
  34. }
  35. SetBrightness(saved_brightness);
  36. }
  37. void Backlight::SetBrightness(uint8_t brightness, bool permanent) {
  38. if (brightness > 100) {
  39. brightness = 100;
  40. }
  41. if (brightness_ == brightness) {
  42. return;
  43. }
  44. if (permanent) {
  45. Settings settings("display", true);
  46. settings.SetInt("brightness", brightness);
  47. }
  48. target_brightness_ = brightness;
  49. step_ = (target_brightness_ > brightness_) ? 1 : -1;
  50. if (transition_timer_ != nullptr) {
  51. // 启动定时器,每 5ms 更新一次
  52. esp_timer_start_periodic(transition_timer_, 5 * 1000);
  53. }
  54. ESP_LOGI(TAG, "Set brightness to %d", brightness);
  55. }
  56. void Backlight::OnTransitionTimer() {
  57. if (brightness_ == target_brightness_) {
  58. esp_timer_stop(transition_timer_);
  59. return;
  60. }
  61. brightness_ += step_;
  62. SetBrightnessImpl(brightness_);
  63. if (brightness_ == target_brightness_) {
  64. esp_timer_stop(transition_timer_);
  65. }
  66. }
  67. PwmBacklight::PwmBacklight(gpio_num_t pin, bool output_invert, uint32_t freq_hz) : Backlight() {
  68. const ledc_timer_config_t backlight_timer = {
  69. .speed_mode = LEDC_LOW_SPEED_MODE,
  70. .duty_resolution = LEDC_TIMER_10_BIT,
  71. .timer_num = LEDC_TIMER_0,
  72. .freq_hz = freq_hz, //背光pwm频率需要高一点,防止电感啸叫
  73. .clk_cfg = LEDC_AUTO_CLK,
  74. .deconfigure = false
  75. };
  76. ESP_ERROR_CHECK(ledc_timer_config(&backlight_timer));
  77. // Setup LEDC peripheral for PWM backlight control
  78. const ledc_channel_config_t backlight_channel = {
  79. .gpio_num = pin,
  80. .speed_mode = LEDC_LOW_SPEED_MODE,
  81. .channel = LEDC_CHANNEL_0,
  82. .intr_type = LEDC_INTR_DISABLE,
  83. .timer_sel = LEDC_TIMER_0,
  84. .duty = 0,
  85. .hpoint = 0,
  86. .flags = {
  87. .output_invert = output_invert,
  88. }
  89. };
  90. ESP_ERROR_CHECK(ledc_channel_config(&backlight_channel));
  91. }
  92. PwmBacklight::~PwmBacklight() {
  93. ledc_stop(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0);
  94. }
  95. void PwmBacklight::SetBrightnessImpl(uint8_t brightness) {
  96. // LEDC resolution set to 10bits, thus: 100% = 1023
  97. uint32_t duty_cycle = (1023 * brightness) / 100;
  98. ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty_cycle);
  99. ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
  100. }