#ifndef DISPLAY_H #define DISPLAY_H #include #include #include #include #include #include #include #include "misc/lv_types.h" #include "misc/lv_area.h" #include "display/lv_display.h" #include "widgets/label/lv_label.h" #include "panel_device.h" #define I2C_BUS_PORT 0 #define LVGL_TICK_PERIOD_MS 5 #define LVGL_TASK_STACK_SIZE (4 * 1024) #define LVGL_TASK_PRIORITY 2 static const char *TAG = "lcd-panel"; struct I2C { I2C(); ~I2C() = default; i2c_master_bus_handle_t i2c_bus_; private: i2c_master_bus_config_t bus_config_; }; struct ScopedLock { explicit ScopedLock() { _lock_acquire(&lock_); } ~ScopedLock() { _lock_release(&lock_); } // LVGL library is not thread-safe, this example calls LVGL APIs from tasks. // We must use a mutex to protect it. static _lock_t lock_; }; class Panel { public: explicit Panel(i2c_master_bus_handle_t i2c); explicit Panel(const I2C &i2c) : Panel(i2c.i2c_bus_) { } ~Panel() = default; [[nodiscard]] inline const esp_lcd_panel_t *get() const { return panel_; } [[nodiscard]] inline esp_lcd_panel_t *get() { return panel_; } [[nodiscard]] inline const esp_lcd_panel_t * operator*() const { return get(); } [[nodiscard]] inline esp_lcd_panel_t *operator*() { return get(); } esp_lcd_panel_io_handle_t io_handle_; esp_lcd_panel_handle_t panel_; private: esp_lcd_panel_dev_config_t panel_config_; esp_lcd_panel_io_i2c_config_t io_config_; }; class Display { public: explicit Display(const I2C &i2c); ~Display() = default; [[nodiscard]] inline const lv_display_t *get() const { return display_; } [[nodiscard]] inline lv_display_t *get() { return display_; } [[nodiscard]] inline const lv_display_t *operator*() const { return get(); } [[nodiscard]] inline lv_display_t *operator*() { return get(); } void set_text(const char *text, const char *name, lv_label_long_mode_t long_mode = LV_LABEL_LONG_SCROLL_CIRCULAR, lv_align_t align = LV_ALIGN_TOP_MID); static bool lvgl_flush_ready(esp_lcd_panel_io_handle_t panel, esp_lcd_panel_io_event_data_t *data, void *user_ctx); static void lvgl_flush_cb(lv_display_t *display, const lv_area_t *area, uint8_t *px_map); static void lvgl_increase_tick(void *arg); [[noreturn]] static void lvgl_port_task(void *arg); private: Panel panel_; lv_display_t *display_; void *buf_; std::unordered_map objects_; }; #endif // DISPLAY_H