#ifndef PANEL_DEVICE_H #define PANEL_DEVICE_H #include #include #include #include #include #include "i2c.h" #define LVGL_PALETTE_SIZE 8 class IPanelDevice { public: explicit IPanelDevice(I2C &i2c, esp_lcd_panel_io_i2c_config_t config, int width, int height) : IPanelDevice(i2c, config, width, height, width * height / 8 + LVGL_PALETTE_SIZE) { } explicit IPanelDevice(I2C &i2c, esp_lcd_panel_io_i2c_config_t io_config, int width, int height, size_t draw_buf_size) : width_(width), height_(height), rst_num_(i2c.rst_num_), lv_buf_size_(draw_buf_size), esp_i2c_bus_(i2c.esp_i2c_bus_), esp_io_config_(io_config) { } virtual ~IPanelDevice() = default; [[nodiscard]] lv_display_t *create_display() const { auto display = lv_display_create(width_, height_); assert(display); return display; } [[nodiscard]] esp_lcd_panel_io_handle_t create_io_handle() { ESP_LOGI(TAG, "Creating panel IO handle"); esp_lcd_panel_io_handle_t handle = nullptr; ESP_ERROR_CHECK( esp_lcd_new_panel_io_i2c(esp_i2c_bus_, &esp_io_config_, &handle)); return handle; } void create_panel(esp_lcd_panel_dev_config_t &config, esp_lcd_panel_io_handle_t io, esp_lcd_panel_handle_t &panel) { // If the passed handle is already allocated, delete it. if (panel != nullptr) { ESP_LOGI(TAG, "Removing unused panel"); esp_lcd_panel_del(panel); } ESP_LOGI(TAG, "Install SSD1306 panel driver"); init_panel(config, io, panel); } virtual void *vendor_config() = 0; int32_t width_; int32_t height_; int rst_num_; // LVGL reserves 2x4 bytes in the buffer to be used as a palette. size_t lv_buf_size_; i2c_master_bus_handle_t esp_i2c_bus_; esp_lcd_panel_io_i2c_config_t esp_io_config_; private: virtual void init_panel(esp_lcd_panel_dev_config_t &config, esp_lcd_panel_io_handle_t io, esp_lcd_panel_handle_t &panel) = 0; }; #endif // PANEL_DEVICE_H