knxdisplay/main/Display.cpp
2026-01-17 12:22:45 +01:00

102 lines
3.4 KiB
C++

#include "Display.hpp"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_mipi_dsi.h"
#include "esp_ldo_regulator.h"
#include "esp_lcd_jd9365_10_1.h"
#include "esp_lv_adapter.h"
// Display config
#define LCD_H_RES 800
#define LCD_V_RES 1280
#define LCD_BIT_PER_PIXEL 16 // RGB565 for better performance
#define LCD_RST_GPIO 27
#define LCD_BK_GPIO 26
#define LCD_BK_ON_LEVEL 1
// MIPI DSI config
#define MIPI_DSI_LANE_NUM 2
#define MIPI_DSI_PHY_LDO_CHAN 3
#define MIPI_DSI_PHY_LDO_VOLTAGE_MV 2500
Display::Display() : panel_handle(nullptr) {}
void Display::init() {
// --- Backlight Init ---
gpio_config_t bk_gpio_config = {};
bk_gpio_config.mode = GPIO_MODE_OUTPUT;
bk_gpio_config.pin_bit_mask = 1ULL << LCD_BK_GPIO;
gpio_config(&bk_gpio_config);
gpio_set_level(static_cast<gpio_num_t>(LCD_BK_GPIO), LCD_BK_ON_LEVEL);
// --- DSI PHY LDO Init ---
esp_ldo_channel_handle_t ldo_mipi = NULL;
esp_ldo_channel_config_t ldo_cfg = {};
ldo_cfg.chan_id = MIPI_DSI_PHY_LDO_CHAN;
ldo_cfg.voltage_mv = MIPI_DSI_PHY_LDO_VOLTAGE_MV;
esp_ldo_acquire_channel(&ldo_cfg, &ldo_mipi);
// --- DSI Bus Init ---
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
esp_lcd_dsi_bus_config_t bus_cfg = {};
bus_cfg.bus_id = 0;
bus_cfg.num_data_lanes = 2;
bus_cfg.phy_clk_src = static_cast<mipi_dsi_phy_pllref_clock_source_t>(0);
bus_cfg.lane_bit_rate_mbps = 1500;
esp_lcd_new_dsi_bus(&bus_cfg, &mipi_dsi_bus);
// --- DSI Panel IO Init ---
esp_lcd_panel_io_handle_t mipi_dbi_io = NULL;
esp_lcd_dbi_io_config_t io_cfg = {};
io_cfg.virtual_channel = 0;
io_cfg.lcd_cmd_bits = 8;
io_cfg.lcd_param_bits = 8;
esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &io_cfg, &mipi_dbi_io);
// --- DPI Panel Config ---
esp_lcd_dpi_panel_config_t dpi_cfg = {};
dpi_cfg.dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT;
dpi_cfg.dpi_clock_freq_mhz = 80;
dpi_cfg.virtual_channel = 0;
dpi_cfg.pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565;
dpi_cfg.video_timing.h_size = 800;
dpi_cfg.video_timing.v_size = 1280;
dpi_cfg.video_timing.hsync_back_porch = 20;
dpi_cfg.video_timing.hsync_pulse_width = 20;
dpi_cfg.video_timing.hsync_front_porch = 40;
dpi_cfg.video_timing.vsync_back_porch = 10;
dpi_cfg.video_timing.vsync_pulse_width = 4;
dpi_cfg.video_timing.vsync_front_porch = 30;
dpi_cfg.flags.use_dma2d = true;
dpi_cfg.num_fbs = esp_lv_adapter_get_required_frame_buffer_count(
ESP_LV_ADAPTER_TEAR_AVOID_MODE_DEFAULT_MIPI_DSI,
ESP_LV_ADAPTER_ROTATE_90
);
// --- Vendor Config ---
jd9365_vendor_config_t vendor_cfg = {};
vendor_cfg.flags.use_mipi_interface = 1;
vendor_cfg.mipi_config.dsi_bus = mipi_dsi_bus;
vendor_cfg.mipi_config.dpi_config = &dpi_cfg;
vendor_cfg.mipi_config.lane_num = MIPI_DSI_LANE_NUM;
// --- Panel Device Config ---
esp_lcd_panel_dev_config_t panel_cfg = {};
panel_cfg.reset_gpio_num = LCD_RST_GPIO;
panel_cfg.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB;
panel_cfg.bits_per_pixel = LCD_BIT_PER_PIXEL;
panel_cfg.vendor_config = &vendor_cfg;
esp_lcd_new_panel_jd9365(mipi_dbi_io, &panel_cfg, &this->panel_handle);
esp_lcd_panel_reset(this->panel_handle);
esp_lcd_panel_init(this->panel_handle);
esp_lcd_panel_disp_on_off(this->panel_handle, true);
}
esp_lcd_panel_handle_t Display::getPanelHandle() const {
return this->panel_handle;
}