Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 15 additions & 71 deletions components/display/include/display.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ template <typename Pixel> class Display : public BaseComponent {
nullptr}; /**< Optional function used to configure display with new rotation setting. */
DisplayRotation rotation{
DisplayRotation::LANDSCAPE}; /**< Default / Initial rotation of the display. */
Task::BaseConfig task_config{.name = "Display",
.stack_size_bytes = 4096,
.priority = 20,
.core_id = 0}; /**< Task configuration. */
std::chrono::duration<float> update_period{
0.01}; /**< How frequently to run the update function. */
};

/**
Expand Down Expand Up @@ -148,11 +142,9 @@ template <typename Pixel> class Display : public BaseComponent {
, height_(lvgl_conf.height)
, display_buffer_px_size_(mem_conf.pixel_buffer_size)
, vram_0_(mem_conf.vram0)
, vram_1_(mem_conf.vram1)
, update_period_(lvgl_conf.update_period) {
, vram_1_(mem_conf.vram1) {
init_backlight(lcd_config.backlight_pin, lcd_config.backlight_on_value);
init_gfx(lvgl_conf.flush_callback, lvgl_conf.rotation_callback, lvgl_conf.rotation,
lvgl_conf.task_config);
init_gfx(lvgl_conf.flush_callback, lvgl_conf.rotation_callback, lvgl_conf.rotation);
set_brightness(1.0);
}

Expand All @@ -170,12 +162,10 @@ template <typename Pixel> class Display : public BaseComponent {
: BaseComponent("Display", log_level)
, width_(lvgl_conf.width)
, height_(lvgl_conf.height)
, display_buffer_px_size_(mem_conf.pixel_buffer_size)
, update_period_(lvgl_conf.update_period) {
, display_buffer_px_size_(mem_conf.pixel_buffer_size) {
init_memory(mem_conf.double_buffered, mem_conf.allocation_flags);
init_backlight(lcd_config.backlight_pin, lcd_config.backlight_on_value);
init_gfx(lvgl_conf.flush_callback, lvgl_conf.rotation_callback, lvgl_conf.rotation,
lvgl_conf.task_config);
init_gfx(lvgl_conf.flush_callback, lvgl_conf.rotation_callback, lvgl_conf.rotation);
set_brightness(1.0);
}

Expand All @@ -196,11 +186,9 @@ template <typename Pixel> class Display : public BaseComponent {
, display_buffer_px_size_(mem_conf.pixel_buffer_size)
, vram_0_(mem_conf.vram0)
, vram_1_(mem_conf.vram1)
, update_period_(lvgl_conf.update_period)
, set_brightness_(oled_config.set_brightness_callback)
, get_brightness_(oled_config.get_brightness_callback) {
init_gfx(lvgl_conf.flush_callback, lvgl_conf.rotation_callback, lvgl_conf.rotation,
lvgl_conf.task_config);
init_gfx(lvgl_conf.flush_callback, lvgl_conf.rotation_callback, lvgl_conf.rotation);
set_brightness(1.0);
}

Expand All @@ -219,20 +207,17 @@ template <typename Pixel> class Display : public BaseComponent {
, width_(lvgl_conf.width)
, height_(lvgl_conf.height)
, display_buffer_px_size_(mem_conf.pixel_buffer_size)
, update_period_(lvgl_conf.update_period)
, set_brightness_(oled_config.set_brightness_callback)
, get_brightness_(oled_config.get_brightness_callback) {
init_memory(mem_conf.double_buffered, mem_conf.allocation_flags);
init_gfx(lvgl_conf.flush_callback, lvgl_conf.rotation_callback, lvgl_conf.rotation,
lvgl_conf.task_config);
init_gfx(lvgl_conf.flush_callback, lvgl_conf.rotation_callback, lvgl_conf.rotation);
set_brightness(1.0);
}

/**
* @brief Stops the upate task and frees the display buffer memory.
*/
~Display() {
task_->stop();
if (created_vram_) {
free(vram_0_);
free(vram_1_);
Expand Down Expand Up @@ -282,18 +267,6 @@ template <typename Pixel> class Display : public BaseComponent {
return 0.0f;
}

/**
* @brief Pause the display update task, to prevent LVGL from writing to the
* display.
*/
void pause() { paused_ = true; }

/**
* @brief Resume the display update task, to allow LVGL to write to the
* display.
*/
void resume() { paused_ = false; }

/**
* @brief Force a redraw / refresh of the display.
*
Expand Down Expand Up @@ -395,10 +368,9 @@ template <typename Pixel> class Display : public BaseComponent {
* @param flush_callback Callback used to flush color data to the display.
* @param rotation_callback function to call in the event handler on rotation change.
* @param rotation Default / initial rotation of the display.
* @param task_config Configuration for the task that runs the lvgl tick
*/
void init_gfx(const flush_fn flush_callback, const rotation_fn rotation_callback,
DisplayRotation rotation, const Task::BaseConfig &task_config) {
DisplayRotation rotation) {
// save the callbacks
if (flush_callback == nullptr) {
logger_.error("No flush callback provided, cannot initialize display!");
Expand All @@ -413,6 +385,10 @@ template <typename Pixel> class Display : public BaseComponent {

lv_init();

lv_tick_set_cb(xTaskGetTickCount);

lv_delay_set_cb(vTaskDelay_wrapper);

display_ = lv_display_create(width_, height_);
// store a pointer to this object in the display user data, so that we can
// access it in the flush callback
Expand All @@ -429,14 +405,6 @@ template <typename Pixel> class Display : public BaseComponent {

// Setting as default display, allows the use of lv_disp_get_default()
lv_display_set_default(display_);

// Now start the task for the ui management
using namespace std::placeholders;
task_ = Task::make_unique({
.callback = std::bind(&Display::update, this, _1, _2, _3),
.task_config = task_config,
});
task_->start();
}

/**
Expand Down Expand Up @@ -479,35 +447,12 @@ template <typename Pixel> class Display : public BaseComponent {
}

/**
* @brief Flush the data to the display, called within the task_.
*
* This task should always be high priority, so that it is higher than
* than the task running lv_task_handler(). For more info, see
* https://docs.lvgl.io/latest/en/html/porting/tick.html
* @brief Wrapper around vTaskDelay, to pass to LVGL.
* If not, LVGL will do random math as to delay the task instead.
* @param ms The number of milliseconds to delay.
*/
bool update(std::mutex &m, std::condition_variable &cv, bool &task_notified) {
auto now = std::chrono::high_resolution_clock::now();
static auto prev = now;
if (!paused_) {
int elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now - prev).count();
// we shouldn't stop, update the display
lv_tick_inc(elapsed_ms);
}
// update previous timestamp
prev = now;
// delay
{
using namespace std::chrono_literals;
std::unique_lock<std::mutex> lk(m);
cv.wait_for(lk, update_period_, [&task_notified] { return task_notified; });
task_notified = false;
}
// don't want to stop the task
return false;
}
static void vTaskDelay_wrapper(const uint32_t ms) { vTaskDelay(pdMS_TO_TICKS(ms)); }

std::atomic<bool> paused_{false};
std::unique_ptr<Task> task_;
size_t width_;
size_t height_;
flush_fn flush_callback_{nullptr};
Expand All @@ -518,7 +463,6 @@ template <typename Pixel> class Display : public BaseComponent {
bool created_vram_{false};
std::vector<Led::ChannelConfig> led_channel_configs_;
std::unique_ptr<Led> backlight_{nullptr};
std::chrono::duration<float> update_period_;
lv_display_t *display_;
set_brightness_fn set_brightness_{nullptr};
get_brightness_fn get_brightness_{nullptr};
Expand Down
8 changes: 1 addition & 7 deletions components/esp-box/example/main/esp_box_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,8 @@ extern "C" void app_main(void) {
}
// set the pixel buffer to be 50 lines high
static constexpr size_t pixel_buffer_size = box.lcd_width() * 50;
espp::Task::BaseConfig display_task_config = {
.name = "Display",
.stack_size_bytes = 6 * 1024,
.priority = 10,
.core_id = 0,
};
// initialize the LVGL display for the esp-box
if (!box.initialize_display(pixel_buffer_size, display_task_config)) {
if (!box.initialize_display(pixel_buffer_size)) {
logger.error("Failed to initialize display!");
return;
}
Expand Down
9 changes: 1 addition & 8 deletions components/esp-box/include/esp-box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,9 @@ class EspBox : public BaseComponent {

/// Initialize the display (lvgl display driver)
/// \param pixel_buffer_size The size of the pixel buffer
/// \param task_config The task configuration for the display task
/// \param update_period_ms The update period of the display task
/// \return true if the display was successfully initialized, false otherwise
/// \note This will also allocate two full frame buffers in the SPIRAM
bool initialize_display(size_t pixel_buffer_size,
const espp::Task::BaseConfig &task_config = {.name = "Display",
.stack_size_bytes = 4096,
.priority = 10,
.core_id = 0},
int update_period_ms = 16);
bool initialize_display(size_t pixel_buffer_size);

/// Get the width of the LCD in pixels
/// \return The width of the LCD in pixels
Expand Down
7 changes: 2 additions & 5 deletions components/esp-box/src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ bool EspBox::initialize_lcd() {
return true;
}

bool EspBox::initialize_display(size_t pixel_buffer_size, const espp::Task::BaseConfig &task_config,
int update_period_ms) {
bool EspBox::initialize_display(size_t pixel_buffer_size) {
if (!lcd_handle_) {
logger_.error(
"LCD not initialized, you must call initialize_lcd() before initialize_display()!");
Expand All @@ -104,9 +103,7 @@ bool EspBox::initialize_display(size_t pixel_buffer_size, const espp::Task::Base
.height = lcd_height_,
.flush_callback = DisplayDriver::flush,
.rotation_callback = DisplayDriver::rotate,
.rotation = rotation,
.task_config = task_config,
.update_period = 1ms * update_period_ms},
.rotation = rotation},
Display<Pixel>::LcdConfig{.backlight_pin = backlight_io,
.backlight_on_value = backlight_value},
Display<Pixel>::DynamicMemoryConfig{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,9 @@ class MatouchRotaryDisplay : public BaseComponent {

/// Initialize the display (lvgl display driver)
/// \param pixel_buffer_size The size of the pixel buffer
/// \param task_config The task configuration for the display task
/// \param update_period_ms The update period of the display task
/// \return true if the display was successfully initialized, false otherwise
/// \note This will also allocate two full frame buffers in the SPIRAM
bool initialize_display(size_t pixel_buffer_size,
const espp::Task::BaseConfig &task_config = {.name = "Display",
.stack_size_bytes = 4096,
.priority = 10,
.core_id = 0},
int update_period_ms = 16);
bool initialize_display(size_t pixel_buffer_size);

/// Get the width of the LCD in pixels
/// \return The width of the LCD in pixels
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,7 @@ bool MatouchRotaryDisplay::initialize_lcd() {
return true;
}

bool MatouchRotaryDisplay::initialize_display(size_t pixel_buffer_size,
const espp::Task::BaseConfig &task_config,
int update_period_ms) {
bool MatouchRotaryDisplay::initialize_display(size_t pixel_buffer_size) {
if (!lcd_handle_) {
logger_.error(
"LCD not initialized, you must call initialize_lcd() before initialize_display()!");
Expand All @@ -302,9 +300,7 @@ bool MatouchRotaryDisplay::initialize_display(size_t pixel_buffer_size,
.height = lcd_height_,
.flush_callback = DisplayDriver::flush,
.rotation_callback = DisplayDriver::rotate,
.rotation = rotation,
.task_config = task_config,
.update_period = 1ms * update_period_ms},
.rotation = rotation},
Display<Pixel>::LcdConfig{.backlight_pin = backlight_io,
.backlight_on_value = backlight_value},
Display<Pixel>::DynamicMemoryConfig{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,8 @@ extern "C" void app_main(void) {
}
// set the pixel buffer to be 50 lines high
static constexpr size_t pixel_buffer_size = round_display.lcd_width() * 50;
espp::Task::BaseConfig display_task_config = {
.name = "Display",
.stack_size_bytes = 6 * 1024,
.priority = 10,
.core_id = 0,
};
// initialize the LVGL display for the seeed-studio-round-display
if (!round_display.initialize_display(pixel_buffer_size, display_task_config)) {
if (!round_display.initialize_display(pixel_buffer_size)) {
logger.error("Failed to initialize display!");
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,9 @@ class SsRoundDisplay : public espp::BaseComponent {

/// Initialize the display (lvgl display driver)
/// \param pixel_buffer_size The size of the pixel buffer
/// \param task_config The task configuration for the display task
/// \param update_period_ms The update period of the display task
/// \return true if the display was successfully initialized, false otherwise
/// \note This will also allocate two full frame buffers in the SPIRAM
bool initialize_display(size_t pixel_buffer_size,
const espp::Task::BaseConfig &task_config = {.name = "Display",
.stack_size_bytes = 4096,
.priority = 10,
.core_id = 0},
int update_period_ms = 16);
bool initialize_display(size_t pixel_buffer_size);

/// Get the width of the LCD in pixels
/// \return The width of the LCD in pixels
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,7 @@ bool SsRoundDisplay::initialize_lcd() {
return true;
}

bool SsRoundDisplay::initialize_display(size_t pixel_buffer_size,
const espp::Task::BaseConfig &task_config,
int update_period_ms) {
bool SsRoundDisplay::initialize_display(size_t pixel_buffer_size) {
if (!lcd_handle_) {
logger_.error(
"LCD not initialized, you must call initialize_lcd() before initialize_display()!");
Expand All @@ -262,9 +260,7 @@ bool SsRoundDisplay::initialize_display(size_t pixel_buffer_size,
.height = lcd_height_,
.flush_callback = DisplayDriver::flush,
.rotation_callback = DisplayDriver::rotate,
.rotation = rotation,
.task_config = task_config,
.update_period = 1ms * update_period_ms},
.rotation = rotation},
Display<Pixel>::LcdConfig{.backlight_pin = pin_config_.lcd_backlight,
.backlight_on_value = backlight_value},
Display<Pixel>::DynamicMemoryConfig{
Expand Down
9 changes: 1 addition & 8 deletions components/t-deck/include/t-deck.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,16 +239,9 @@ class TDeck : public BaseComponent {

/// Initialize the display (lvgl display driver)
/// \param pixel_buffer_size The size of the pixel buffer
/// \param task_config The task configuration for the display task
/// \param update_period_ms The update period of the display task
/// \return true if the display was successfully initialized, false otherwise
/// \note This will also allocate two full frame buffers in the SPIRAM
bool initialize_display(size_t pixel_buffer_size,
const espp::Task::BaseConfig &task_config = {.name = "Display",
.stack_size_bytes = 4096,
.priority = 10,
.core_id = 0},
int update_period_ms = 16);
bool initialize_display(size_t pixel_buffer_size);

/// Get the width of the LCD in pixels
/// \return The width of the LCD in pixels
Expand Down
7 changes: 2 additions & 5 deletions components/t-deck/src/t-deck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,7 @@ bool TDeck::initialize_lcd() {
return true;
}

bool TDeck::initialize_display(size_t pixel_buffer_size, const espp::Task::BaseConfig &task_config,
int update_period_ms) {
bool TDeck::initialize_display(size_t pixel_buffer_size) {
if (!lcd_handle_) {
logger_.error(
"LCD not initialized, you must call initialize_lcd() before initialize_display()!");
Expand All @@ -331,9 +330,7 @@ bool TDeck::initialize_display(size_t pixel_buffer_size, const espp::Task::BaseC
.height = lcd_height_,
.flush_callback = DisplayDriver::flush,
.rotation_callback = DisplayDriver::rotate,
.rotation = rotation,
.task_config = task_config,
.update_period = 1ms * update_period_ms},
.rotation = rotation},
Display<Pixel>::LcdConfig{.backlight_pin = backlight_io,
.backlight_on_value = backlight_value},
Display<Pixel>::DynamicMemoryConfig{
Expand Down
9 changes: 1 addition & 8 deletions components/t-dongle-s3/include/t-dongle-s3.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,9 @@ class TDongleS3 : public BaseComponent {

/// Initialize the display (lvgl display driver)
/// \param pixel_buffer_size The size of the pixel buffer
/// \param task_config The task configuration for the display task
/// \param update_period_ms The update period of the display task
/// \return true if the display was successfully initialized, false otherwise
/// \note This will also allocate two full frame buffers in the SPIRAM
bool initialize_display(size_t pixel_buffer_size,
const espp::Task::BaseConfig &task_config = {.name = "Display",
.stack_size_bytes = 4096,
.priority = 10,
.core_id = 0},
int update_period_ms = 16);
bool initialize_display(size_t pixel_buffer_size);

/// Get the width of the LCD in pixels
/// \return The width of the LCD in pixels
Expand Down
Loading