2025-02-15 10:11:49 -05:00
|
|
|
#ifndef PANEL_DEVICE_H
|
|
|
|
#define PANEL_DEVICE_H
|
|
|
|
|
|
|
|
#include <esp_lcd_panel_dev.h>
|
|
|
|
#include <esp_lcd_panel_ops.h>
|
2025-02-15 17:12:06 -05:00
|
|
|
#include <esp_lcd_panel_io.h>
|
|
|
|
#include <esp_log.h>
|
2025-02-15 18:26:26 -05:00
|
|
|
|
|
|
|
#include <display/lv_display.h>
|
2025-02-15 10:11:49 -05:00
|
|
|
|
2025-02-15 17:44:58 -05:00
|
|
|
#include "i2c.h"
|
2025-02-15 10:11:49 -05:00
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
// LVGL reserves 2x4 bytes in the buffer to be used as a palette.
|
|
|
|
// This additional space must be added to the IPanelDevice::buf_size_.
|
2025-02-15 17:44:58 -05:00
|
|
|
#define LVGL_PALETTE_SIZE 8
|
2025-02-15 10:11:49 -05:00
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/**
|
|
|
|
* Encapsulates vendor specific ESP LCD pabel initialization logic.
|
|
|
|
* This pure virtual interface can be inherited from for using new LCD devices.
|
|
|
|
* See the SSD1306 example for implementing a PanelDevice for NT35510 or ST7789.
|
|
|
|
*
|
|
|
|
* At this time only I2C is supported.
|
|
|
|
* Classes that inherit from this interface should likely be marked final.
|
|
|
|
*/
|
2025-02-15 17:12:06 -05:00
|
|
|
class IPanelDevice {
|
|
|
|
public:
|
2025-02-16 14:31:50 -05:00
|
|
|
/**
|
|
|
|
* Construct an IPanelDevice.
|
|
|
|
*
|
|
|
|
* @param i2c I2C object. Eventually this will mature to IProtocol or similar.
|
|
|
|
* @param config I2C configuration for this device.
|
|
|
|
* @param height Height of the device screen in pixels.
|
|
|
|
* @param width Width of the device screen in pixels.
|
|
|
|
*/
|
2025-02-15 18:16:25 -05:00
|
|
|
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) { }
|
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/**
|
|
|
|
* Construct an IPanelDevice.
|
|
|
|
*
|
|
|
|
* @param i2c I2C object. Eventually this will mature to IProtocol or similar.
|
|
|
|
* @param config I2C configuration for this device.
|
|
|
|
* @param height Height of the device screen in pixels.
|
|
|
|
* @param width Width of the device screen in pixels.
|
|
|
|
* @param draw_buf_size Size of the draw buffer for this device.
|
|
|
|
*/
|
2025-02-15 18:16:25 -05:00
|
|
|
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),
|
2025-02-15 18:26:26 -05:00
|
|
|
esp_io_config_(io_config) { }
|
2025-02-15 10:11:49 -05:00
|
|
|
|
2025-02-15 17:12:06 -05:00
|
|
|
virtual ~IPanelDevice() = default;
|
2025-02-15 10:11:49 -05:00
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/**
|
|
|
|
* Create an LVGL display using the width and height of this device.
|
|
|
|
*
|
|
|
|
* @return Handle to the created LVGL display.
|
|
|
|
*/
|
2025-02-15 17:12:06 -05:00
|
|
|
[[nodiscard]] lv_display_t *create_display() const
|
2025-02-15 10:11:49 -05:00
|
|
|
{
|
2025-02-15 17:12:06 -05:00
|
|
|
auto display = lv_display_create(width_, height_);
|
|
|
|
assert(display);
|
|
|
|
return display;
|
2025-02-15 10:11:49 -05:00
|
|
|
}
|
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/**
|
|
|
|
* Create an ESP LCD panel IO handle.
|
|
|
|
*
|
|
|
|
* @return The created ESP LCD panel IO handle.
|
|
|
|
*/
|
2025-02-15 18:26:26 -05:00
|
|
|
[[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(
|
2025-02-16 14:31:50 -05:00
|
|
|
esp_lcd_new_panel_io_i2c(I2C::get(), &esp_io_config_, &handle));
|
2025-02-15 18:26:26 -05:00
|
|
|
return handle;
|
|
|
|
}
|
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/**
|
|
|
|
* Create and initialize an ESP panel handle.
|
|
|
|
* IPanelDevice implementors must initialize the panel within init_panel.
|
|
|
|
*
|
|
|
|
* @param config ESP LCD panel configuration.
|
|
|
|
* @param io ESP LCD panel IO handle.
|
|
|
|
* @param [out] panel ESP LCD panel handle output pointer location.
|
|
|
|
*/
|
2025-02-15 17:12:06 -05:00
|
|
|
void create_panel(esp_lcd_panel_dev_config_t &config,
|
|
|
|
esp_lcd_panel_io_handle_t io,
|
|
|
|
esp_lcd_panel_handle_t &panel)
|
2025-02-15 10:11:49 -05:00
|
|
|
{
|
2025-02-15 17:12:06 -05:00
|
|
|
// 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");
|
2025-02-16 14:31:50 -05:00
|
|
|
// Call pure virtual method responsible for initializing the panel handle.
|
2025-02-15 17:12:06 -05:00
|
|
|
init_panel(config, io, panel);
|
2025-02-16 14:31:50 -05:00
|
|
|
|
2025-02-15 10:11:49 -05:00
|
|
|
}
|
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/**
|
|
|
|
* Retrieve the device specific vendor configuration structure.
|
|
|
|
*
|
|
|
|
* @return Address of vendor configuration structure.
|
|
|
|
* @sa SSD1306::vendor_config
|
|
|
|
*/
|
2025-02-15 18:26:26 -05:00
|
|
|
virtual void *vendor_config() = 0;
|
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/// Width of the device screen in pixels.
|
2025-02-15 17:12:06 -05:00
|
|
|
int32_t width_;
|
2025-02-15 18:26:26 -05:00
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/// Height of the device screen in pixels.
|
2025-02-15 17:12:06 -05:00
|
|
|
int32_t height_;
|
2025-02-15 18:26:26 -05:00
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/// RST GPIO pin number.
|
2025-02-15 18:16:25 -05:00
|
|
|
int rst_num_;
|
2025-02-15 10:11:49 -05:00
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/// LVGL draw buffer size for the device.
|
2025-02-15 17:12:06 -05:00
|
|
|
size_t lv_buf_size_;
|
2025-02-15 10:11:49 -05:00
|
|
|
|
2025-02-16 14:31:50 -05:00
|
|
|
/// ESP LCD panel IO configuration.
|
2025-02-15 18:26:26 -05:00
|
|
|
esp_lcd_panel_io_i2c_config_t esp_io_config_;
|
2025-02-15 10:11:49 -05:00
|
|
|
|
2025-02-15 17:12:06 -05:00
|
|
|
private:
|
2025-02-16 14:31:50 -05:00
|
|
|
/**
|
|
|
|
* Initializes the ESP panel using vendor specific APIs and configurations.
|
|
|
|
* This method should implement any setup logic specific to the device.
|
|
|
|
*
|
|
|
|
* @param config ESP LCD panel configuration.
|
|
|
|
* @param io ESP LCD panel IO handle.
|
|
|
|
* @param [out] panel ESP LCD panel handle output pointer location.
|
|
|
|
*/
|
2025-02-15 17:12:06 -05:00
|
|
|
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;
|
2025-02-16 14:40:53 -05:00
|
|
|
|
|
|
|
/// Tag used for ESP logging.
|
|
|
|
const char * TAG = "IPanelDevice";
|
2025-02-15 10:11:49 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // PANEL_DEVICE_H
|