summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-04-22 16:00:53 +1000
committerjacqueline <me@jacqueline.id.au>2024-04-22 16:00:53 +1000
commitdb9e5cce1fff82149a609939709a94ae02f349a8 (patch)
tree5dd6f5a636eb2e87bca84d7ceabbf09c893f23e1 /src
parent5b99267cb9f0344e519956096867aea5468ecf9f (diff)
downloadtangara-fw-db9e5cce1fff82149a609939709a94ae02f349a8.tar.gz
Improve handling of the display
- Blank the display when locking to prevent burn-in - Delay turning the display on until *exactly* after the first lvgl flush - Init the display in the ui task to avoid blocking the rest of boot
Diffstat (limited to 'src')
-rw-r--r--src/drivers/display.cpp28
-rw-r--r--src/drivers/include/display.hpp1
-rw-r--r--src/ui/include/ui_events.hpp7
-rw-r--r--src/ui/include/ui_fsm.hpp1
-rw-r--r--src/ui/lvgl_task.cpp1
-rw-r--r--src/ui/ui_fsm.cpp23
6 files changed, 49 insertions, 12 deletions
diff --git a/src/drivers/display.cpp b/src/drivers/display.cpp
index c16fc148..5c686811 100644
--- a/src/drivers/display.cpp
+++ b/src/drivers/display.cpp
@@ -5,6 +5,7 @@
*/
#include "display.hpp"
+#include <stdint.h>
#include <cmath>
#include <cstdint>
@@ -168,7 +169,11 @@ auto Display::Create(IGpios& expander,
}
Display::Display(IGpios& gpio, spi_device_handle_t handle)
- : gpio_(gpio), handle_(handle), display_on_(false), brightness_(0) {}
+ : gpio_(gpio),
+ handle_(handle),
+ first_flush_finished_(false),
+ display_on_(false),
+ brightness_(0) {}
Display::~Display() {
ledc_fade_func_uninstall();
@@ -176,14 +181,28 @@ Display::~Display() {
auto Display::SetDisplayOn(bool enabled) -> void {
display_on_ = enabled;
+ if (!first_flush_finished_) {
+ return;
+ }
+
+ if (display_on_) {
+ SendCommandWithData(displays::ST77XX_DISPON, nullptr, 0);
+ vTaskDelay(pdMS_TO_TICKS(100));
+ }
+
int new_duty = display_on_ ? brightness_ : 0;
SetDutyCycle(new_duty, true);
+
+ if (!display_on_) {
+ vTaskDelay(pdMS_TO_TICKS(100));
+ SendCommandWithData(displays::ST77XX_DISPOFF, nullptr, 0);
+ }
}
auto Display::SetBrightness(uint_fast8_t percent) -> void {
brightness_ =
std::pow(static_cast<double>(percent) / 100.0, 2.8) * 1024.0 + 0.5;
- if (display_on_) {
+ if (first_flush_finished_ && display_on_) {
SetDutyCycle(brightness_, false);
}
}
@@ -295,6 +314,11 @@ void Display::OnLvglFlush(lv_disp_drv_t* disp_drv,
SendCommandWithData(displays::ST77XX_RAMWR,
reinterpret_cast<uint8_t*>(color_map), size * 2);
+ if (!first_flush_finished_ && lv_disp_flush_is_last(disp_drv)) {
+ first_flush_finished_ = true;
+ SetDisplayOn(display_on_);
+ }
+
lv_disp_flush_ready(&driver_);
}
diff --git a/src/drivers/include/display.hpp b/src/drivers/include/display.hpp
index b0aa5d58..d2e18a5c 100644
--- a/src/drivers/include/display.hpp
+++ b/src/drivers/include/display.hpp
@@ -52,6 +52,7 @@ class Display {
IGpios& gpio_;
spi_device_handle_t handle_;
+ bool first_flush_finished_;
bool display_on_;
uint_fast8_t brightness_;
diff --git a/src/ui/include/ui_events.hpp b/src/ui/include/ui_events.hpp
index 81e0543a..3d794edc 100644
--- a/src/ui/include/ui_events.hpp
+++ b/src/ui/include/ui_events.hpp
@@ -8,7 +8,9 @@
#include <memory>
#include "database.hpp"
+#include "gpios.hpp"
#include "index.hpp"
+#include "nvs.hpp"
#include "screen.hpp"
#include "tinyfsm.hpp"
@@ -32,6 +34,11 @@ struct DumpLuaStack : tinyfsm::Event {};
namespace internal {
+struct InitDisplay : tinyfsm::Event {
+ drivers::IGpios& gpios;
+ drivers::NvsStorage& nvs;
+};
+
struct ReindexDatabase : tinyfsm::Event {};
struct BackPressed : tinyfsm::Event {};
diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp
index 8eafc6e0..325aea8f 100644
--- a/src/ui/include/ui_fsm.hpp
+++ b/src/ui/include/ui_fsm.hpp
@@ -70,6 +70,7 @@ class UiState : public tinyfsm::Fsm<UiState> {
void react(const system_fsm::KeyLockChanged&);
void react(const system_fsm::SamdUsbStatusChanged&);
+ void react(const internal::InitDisplay&);
void react(const internal::DismissAlerts&);
void react(const database::event::UpdateStarted&);
diff --git a/src/ui/lvgl_task.cpp b/src/ui/lvgl_task.cpp
index 4cf25c15..51da0179 100644
--- a/src/ui/lvgl_task.cpp
+++ b/src/ui/lvgl_task.cpp
@@ -84,7 +84,6 @@ auto UiTask::Main() -> void {
}
auto UiTask::input(std::shared_ptr<input::LvglInputDriver> input) -> void {
- assert(current_screen_);
input_ = input;
}
diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp
index 1305e764..ceeb194d 100644
--- a/src/ui/ui_fsm.cpp
+++ b/src/ui/ui_fsm.cpp
@@ -267,6 +267,15 @@ lua::Property UiState::sUsbMassStorageBusy{false};
auto UiState::InitBootSplash(drivers::IGpios& gpios, drivers::NvsStorage& nvs)
-> bool {
+ events::Ui().Dispatch(internal::InitDisplay{
+ .gpios = gpios,
+ .nvs = nvs,
+ });
+ sTask.reset(UiTask::Start());
+ return true;
+}
+
+void UiState::react(const internal::InitDisplay& ev) {
// Init LVGL first, since the display driver registers itself with LVGL.
lv_init();
@@ -275,19 +284,15 @@ auto UiState::InitBootSplash(drivers::IGpios& gpios, drivers::NvsStorage& nvs)
// HACK: correct the display size for our prototypes.
// nvs.DisplaySize({161, 130});
- auto actual_size = nvs.DisplaySize();
+ auto actual_size = ev.nvs.DisplaySize();
init_data.width = actual_size.first.value_or(init_data.width);
init_data.height = actual_size.second.value_or(init_data.height);
-
- sDisplay.reset(drivers::Display::Create(gpios, init_data));
- if (sDisplay == nullptr) {
- return false;
- }
+ sDisplay.reset(drivers::Display::Create(ev.gpios, init_data));
sCurrentScreen.reset(new screens::Splash());
- sTask.reset(UiTask::Start());
- sDisplay->SetDisplayOn(!gpios.IsLocked());
- return true;
+
+ // Display will only actually come on after LVGL finishes its first flush.
+ sDisplay->SetDisplayOn(!ev.gpios.IsLocked());
}
void UiState::PushScreen(std::shared_ptr<Screen> screen) {