diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a957e104..670f0630 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -161,6 +161,11 @@ set(LVGL_SRC libs/lvgl/src/lv_objx/lv_mbox.c libs/lvgl/src/lv_objx/lv_mbox.h + libs/lvgl/src/lv_objx/lv_bar.c + libs/lvgl/src/lv_objx/lv_bar.h + libs/lvgl/src/lv_objx/lv_slider.h + libs/lvgl/src/lv_objx/lv_slider.c + ) list(APPEND IMAGE_FILES @@ -207,7 +212,7 @@ list(APPEND SOURCE_FILES DisplayApp/Screens/Modal.cpp DisplayApp/Screens/BatteryIcon.cpp DisplayApp/Screens/BleIcon.cpp - + DisplayApp/Screens/Brightness.cpp main.cpp drivers/St7789.cpp drivers/SpiMaster.cpp @@ -217,6 +222,7 @@ list(APPEND SOURCE_FILES Components/Battery/BatteryController.cpp Components/Ble/BleController.cpp Components/DateTime/DateTimeController.cpp + Components/Brightness/BrightnessController.cpp drivers/Cst816s.cpp FreeRTOS/port.c FreeRTOS/port_cmsis_systick.c @@ -245,6 +251,7 @@ set(INCLUDE_FILES DisplayApp/Screens/Modal.h DisplayApp/Screens/BatteryIcon.h DisplayApp/Screens/BleIcon.cpp + DisplayApp/Screens/Brightness.h # DisplayApp/Screens/Tab.h drivers/St7789.h drivers/SpiMaster.h @@ -254,6 +261,7 @@ set(INCLUDE_FILES Components/Battery/BatteryController.h Components/Ble/BleController.h Components/DateTime/DateTimeController.h + Components/Brightness/BrightnessController.h drivers/Cst816s.h FreeRTOS/portmacro.h FreeRTOS/portmacro_cmsis.h diff --git a/src/Components/Brightness/BrightnessController.cpp b/src/Components/Brightness/BrightnessController.cpp new file mode 100644 index 00000000..c8825d68 --- /dev/null +++ b/src/Components/Brightness/BrightnessController.cpp @@ -0,0 +1,70 @@ +#include +#include "BrightnessController.h" + +using namespace Pinetime::Controllers; + + +void BrightnessController::Init() { + nrf_gpio_cfg_output(pinLcdBacklight1); + nrf_gpio_cfg_output(pinLcdBacklight2); + nrf_gpio_cfg_output(pinLcdBacklight3); + Set(level); +} + +void BrightnessController::Set(BrightnessController::Levels level) { + this->level = level; + switch(level) { + default: + case Levels::High: + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_clear(pinLcdBacklight2); + nrf_gpio_pin_clear(pinLcdBacklight3); + break; + case Levels::Medium: + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_clear(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); + break; + case Levels::Low: + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_set(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); + break; + case Levels::Off: + nrf_gpio_pin_set(pinLcdBacklight1); + nrf_gpio_pin_set(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); + break; + } +} + +void BrightnessController::Lower() { + switch(level) { + case Levels::High: Set(Levels::Medium); break; + case Levels::Medium: Set(Levels::Low); break; + case Levels::Low: Set(Levels::Off); break; + default: break; + } +} + +void BrightnessController::Higher() { + switch(level) { + case Levels::Off: Set(Levels::Low); break; + case Levels::Low: Set(Levels::Medium); break; + case Levels::Medium: Set(Levels::High); break; + default: break; + } +} + +BrightnessController::Levels BrightnessController::Level() const { + return level; +} + +void BrightnessController::Backup() { + backupLevel = level; +} + +void BrightnessController::Restore() { + Set(backupLevel); +} + diff --git a/src/Components/Brightness/BrightnessController.h b/src/Components/Brightness/BrightnessController.h new file mode 100644 index 00000000..b8354ec0 --- /dev/null +++ b/src/Components/Brightness/BrightnessController.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace Pinetime { + namespace Controllers { + class BrightnessController { + public: + enum class Levels {Off, Low, Medium, High}; + void Init(); + + void Set(Levels level); + Levels Level() const; + void Lower(); + void Higher(); + + void Backup(); + void Restore(); + + private: + static constexpr uint8_t pinLcdBacklight1 = 14; + static constexpr uint8_t pinLcdBacklight2 = 22; + static constexpr uint8_t pinLcdBacklight3 = 23; + Levels level = Levels::High; + Levels backupLevel = Levels::High; + }; + } +} diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 7464175e..3f58e4b3 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "../SystemTask/SystemTask.h" using namespace Pinetime::Applications; @@ -57,12 +58,7 @@ void DisplayApp::Process(void *instance) { } void DisplayApp::InitHw() { - nrf_gpio_cfg_output(pinLcdBacklight1); - nrf_gpio_cfg_output(pinLcdBacklight2); - nrf_gpio_cfg_output(pinLcdBacklight3); - nrf_gpio_pin_clear(pinLcdBacklight1); - nrf_gpio_pin_clear(pinLcdBacklight2); - nrf_gpio_pin_clear(pinLcdBacklight3); + brightnessController.Init(); } uint32_t acc = 0; @@ -85,11 +81,11 @@ void DisplayApp::Refresh() { if (xQueueReceive(msgQueue, &msg, queueTimeout)) { switch (msg) { case Messages::GoToSleep: - nrf_gpio_pin_set(pinLcdBacklight3); - vTaskDelay(100); - nrf_gpio_pin_set(pinLcdBacklight2); - vTaskDelay(100); - nrf_gpio_pin_set(pinLcdBacklight1); + brightnessController.Backup(); + while(brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { + brightnessController.Lower(); + vTaskDelay(100); + } lcd.DisplayOff(); lcd.Sleep(); touchPanel.Sleep(); @@ -100,9 +96,7 @@ void DisplayApp::Refresh() { touchPanel.Wakeup(); lcd.DisplayOn(); - nrf_gpio_pin_clear(pinLcdBacklight3); - nrf_gpio_pin_clear(pinLcdBacklight2); - nrf_gpio_pin_clear(pinLcdBacklight1); + brightnessController.Restore(); state = States::Running; break; case Messages::UpdateDateTime: @@ -174,6 +168,7 @@ void DisplayApp::RunningState() { case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break; case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break; + case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break; } nextApp = Apps::None; } diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index eaad1baa..ccbca4c3 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include "Fonts/lcdfont14.h" @@ -37,7 +38,7 @@ namespace Pinetime { void Start(); void PushMessage(Messages msg); - enum class Apps {None, Launcher, Clock, Test, Meter, Gauge}; + enum class Apps {None, Launcher, Clock, Test, Meter, Gauge, Brightness}; void StartApp(Apps app); private: @@ -64,15 +65,13 @@ namespace Pinetime { TouchEvents OnTouchEvent(); std::unique_ptr currentScreen; - static constexpr uint8_t pinLcdBacklight1 = 14; - static constexpr uint8_t pinLcdBacklight2 = 22; - static constexpr uint8_t pinLcdBacklight3 = 23; bool isClock = true; Pinetime::System::SystemTask& systemTask; Apps nextApp = Apps::None; bool onClockApp = false; // TODO find a better way to know that we should handle gestures and button differently for the Clock app. + Controllers::BrightnessController brightnessController; }; } } diff --git a/src/DisplayApp/Screens/Brightness.cpp b/src/DisplayApp/Screens/Brightness.cpp new file mode 100644 index 00000000..a87a62a8 --- /dev/null +++ b/src/DisplayApp/Screens/Brightness.cpp @@ -0,0 +1,72 @@ +#include +#include "Brightness.h" + +using namespace Pinetime::Applications::Screens; + +void slider_event_cb(lv_obj_t * slider, lv_event_t event) { + if(event == LV_EVENT_VALUE_CHANGED) { + auto* brightnessSlider = static_cast(slider->user_data); + brightnessSlider->OnValueChanged(); + } +} + +Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::BrightnessController& brightness) : Screen(app), brightness{brightness} { + slider = lv_slider_create(lv_scr_act(), NULL); + lv_obj_set_user_data(slider, this); + lv_obj_set_width(slider, LV_DPI * 2); + lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_event_cb(slider, slider_event_cb); + lv_slider_set_range(slider, 0, 2); + lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF); + + slider_label = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(slider_label, LevelToString(brightness.Level())); + lv_obj_set_auto_realign(slider_label, true); + lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); +} + +Brightness::~Brightness() { + lv_obj_clean(lv_scr_act()); +} + +bool Brightness::Refresh() { + return running; +} + +bool Brightness::OnButtonPushed() { + running = false; + return true; +} + +const char *Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) { + switch(level) { + case Pinetime::Controllers::BrightnessController::Levels::Off: return "Off"; + case Pinetime::Controllers::BrightnessController::Levels::Low: return "Low"; + case Pinetime::Controllers::BrightnessController::Levels::Medium: return "Medium"; + case Pinetime::Controllers::BrightnessController::Levels::High: return "High"; + default : return "???"; + } +} + +void Brightness::OnValueChanged() { + SetValue(lv_slider_get_value(slider)); +} + +void Brightness::SetValue(uint8_t value) { + switch(value) { + case 0: brightness.Set(Controllers::BrightnessController::Levels::Low); break; + case 1: brightness.Set(Controllers::BrightnessController::Levels::Medium); break; + case 2: brightness.Set(Controllers::BrightnessController::Levels::High); break; + } + lv_label_set_text(slider_label, LevelToString(brightness.Level())); +} + +uint8_t Brightness::LevelToInt(Pinetime::Controllers::BrightnessController::Levels level) { + switch(level) { + case Pinetime::Controllers::BrightnessController::Levels::Off: return 0; + case Pinetime::Controllers::BrightnessController::Levels::Low: return 0; + case Pinetime::Controllers::BrightnessController::Levels::Medium: return 1; + case Pinetime::Controllers::BrightnessController::Levels::High: return 2; + default : return 0; + } +} diff --git a/src/DisplayApp/Screens/Brightness.h b/src/DisplayApp/Screens/Brightness.h new file mode 100644 index 00000000..31861f8a --- /dev/null +++ b/src/DisplayApp/Screens/Brightness.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include "Screen.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Brightness : public Screen { + public: + Brightness(DisplayApp* app, Controllers::BrightnessController& brightness); + ~Brightness() override; + bool Refresh() override; + bool OnButtonPushed() override; + + void OnValueChanged(); + private: + bool running = true; + Controllers::BrightnessController& brightness; + + lv_obj_t * slider_label; + lv_obj_t * slider; + + const char* LevelToString(Controllers::BrightnessController::Levels level); + uint8_t LevelToInt(Controllers::BrightnessController::Levels level); + void SetValue(uint8_t value); + }; + } + } +} \ No newline at end of file diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index 004c8d31..5dc1fce4 100644 --- a/src/DisplayApp/Screens/Tile.cpp +++ b/src/DisplayApp/Screens/Tile.cpp @@ -16,7 +16,7 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { screen->OnObjectEvent(obj, event, eventData); } -static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "Soft\nversion", "App2", "App3", ""}; +static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "Soft\nversion", "App2", "Brightness", ""}; Tile::Tile(DisplayApp* app) : Screen(app) { modal.reset(new Modal(app)); @@ -126,8 +126,10 @@ void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { modal->Show(); break; case 4: - case 5: tile->StartTestApp(); + break; + case 5: + tile->StartBrightnessApp(); break; } @@ -151,6 +153,11 @@ void Tile::StartTestApp() { running = false; } +void Tile::StartBrightnessApp() { + app->StartApp(DisplayApp::Apps::Brightness); + running = false; +} + void Tile::StartMeterApp() { app->StartApp(DisplayApp::Apps::Meter); running = false; diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h index eb253435..cfd9b01f 100644 --- a/src/DisplayApp/Screens/Tile.h +++ b/src/DisplayApp/Screens/Tile.h @@ -58,6 +58,7 @@ namespace Pinetime { bool running = true; std::unique_ptr modal; + void StartBrightnessApp(); }; } }