From 367da3d2814e6275ef99767bccdee9cc5364fb38 Mon Sep 17 00:00:00 2001 From: John Crawford Date: Mon, 2 Oct 2023 18:56:44 -0600 Subject: [PATCH 1/2] feat: pwm smooth brightness tranistions --- .../brightness/BrightnessController.cpp | 72 ++++++++++++++----- .../brightness/BrightnessController.h | 7 ++ src/displayapp/DisplayApp.cpp | 5 +- 3 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 0392158cbc..5ec987fe97 100644 --- a/src/components/brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp @@ -2,39 +2,75 @@ #include #include "displayapp/screens/Symbols.h" #include "drivers/PinMap.h" + +#include "nrf_pwm.h" + using namespace Pinetime::Controllers; void BrightnessController::Init() { nrf_gpio_cfg_output(PinMap::LcdBacklightLow); nrf_gpio_cfg_output(PinMap::LcdBacklightMedium); nrf_gpio_cfg_output(PinMap::LcdBacklightHigh); + + nrf_gpio_pin_clear(PinMap::LcdBacklightLow); + nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); + nrf_gpio_pin_clear(PinMap::LcdBacklightHigh); + + static nrf_pwm_sequence_t seq; + + seq.values.p_common = pwmSequence; + seq.length = 1; + seq.repeats = 0; + seq.end_delay = 0; + + uint32_t out_pins[] = {PinMap::LcdBacklightHigh, PinMap::LcdBacklightMedium, PinMap::LcdBacklightLow, NRF_PWM_PIN_NOT_CONNECTED}; + + nrf_pwm_pins_set(NRF_PWM0, out_pins); + nrf_pwm_enable(NRF_PWM0); + // With 8 MHz and 10000 reload timer PWM frequency is 712 Hz + nrf_pwm_configure(NRF_PWM0, NRF_PWM_CLK_8MHz, NRF_PWM_MODE_UP, 10000); + nrf_pwm_loop_set(NRF_PWM0, 0); + nrf_pwm_decoder_set(NRF_PWM0, NRF_PWM_LOAD_COMMON, NRF_PWM_STEP_AUTO); + nrf_pwm_sequence_set(NRF_PWM0, 0, &seq); + nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0); + + pwmVal = 0; Set(level); -} +}; -void BrightnessController::Set(BrightnessController::Levels level) { +void BrightnessController::setPwm(uint16_t val) { + pwmSequence[0] = val; + nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0); +}; + +uint16_t BrightnessController::getPwm(BrightnessController::Levels level) { this->level = level; switch (level) { default: case Levels::High: - nrf_gpio_pin_clear(PinMap::LcdBacklightLow); - nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); - nrf_gpio_pin_clear(PinMap::LcdBacklightHigh); - break; + return 10000; case Levels::Medium: - nrf_gpio_pin_clear(PinMap::LcdBacklightLow); - nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); - nrf_gpio_pin_set(PinMap::LcdBacklightHigh); - break; + return 4000; case Levels::Low: - nrf_gpio_pin_clear(PinMap::LcdBacklightLow); - nrf_gpio_pin_set(PinMap::LcdBacklightMedium); - nrf_gpio_pin_set(PinMap::LcdBacklightHigh); - break; + return 900; case Levels::Off: - nrf_gpio_pin_set(PinMap::LcdBacklightLow); - nrf_gpio_pin_set(PinMap::LcdBacklightMedium); - nrf_gpio_pin_set(PinMap::LcdBacklightHigh); - break; + return 0; + } +} + +void BrightnessController::Set(BrightnessController::Levels level) { + this->level = level; + uint16_t target = getPwm(level); + uint16_t step = abs((pwmVal - target) / 10); + + while (target != pwmVal) { + if (target > pwmVal) { + pwmVal += step; + } else { + pwmVal -= step; + } + setPwm(pwmVal); + vTaskDelay(15); } } diff --git a/src/components/brightness/BrightnessController.h b/src/components/brightness/BrightnessController.h index 7f86759a67..56c1f88576 100644 --- a/src/components/brightness/BrightnessController.h +++ b/src/components/brightness/BrightnessController.h @@ -1,6 +1,9 @@ #pragma once #include +#include +#include +#include namespace Pinetime { namespace Controllers { @@ -20,6 +23,10 @@ namespace Pinetime { private: Levels level = Levels::High; + uint16_t pwmVal; + uint16_t getPwm(Levels level); + void setPwm(uint16_t val); + uint16_t pwmSequence[1] = {10000}; }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index cd941f16cc..6ed9a23f2e 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -221,10 +221,7 @@ void DisplayApp::Refresh() { RestoreBrightness(); break; case Messages::GoToSleep: - while (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { - brightnessController.Lower(); - vTaskDelay(100); - } + brightnessController.Set(Controllers::BrightnessController::Levels::Off); lcd.Sleep(); PushMessageToSystemTask(Pinetime::System::Messages::OnDisplayTaskSleeping); state = States::Idle; From 7d224e4f20979fc584dc1bab020eece1fe1c4232 Mon Sep 17 00:00:00 2001 From: John Crawford Date: Mon, 2 Oct 2023 21:06:17 -0600 Subject: [PATCH 2/2] feat: slightly increase transition delay --- src/components/brightness/BrightnessController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 5ec987fe97..b55ee9b7e4 100644 --- a/src/components/brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp @@ -70,7 +70,7 @@ void BrightnessController::Set(BrightnessController::Levels level) { pwmVal -= step; } setPwm(pwmVal); - vTaskDelay(15); + vTaskDelay(20); } }