#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(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(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; }