117 lines
3.6 KiB
C
117 lines
3.6 KiB
C
|
|
#include "esp_log.h"
|
|
#include "esp_lcd_panel_io.h"
|
|
#include "esp_lcd_panel_ops.h"
|
|
#include "esp_lcd_panel_vendor.h"
|
|
#include "esp_lcd_panel_st7789.h"
|
|
#include "driver/spi_master.h"
|
|
#include "hw_pins.h"
|
|
#include "display_manager.h"
|
|
|
|
static const char *TAG = "display";
|
|
|
|
#define LCD_HOST HW_SPI_HOST
|
|
#define LCD_PIXEL_CLOCK_HZ (16 * 1000 * 1000)
|
|
#define LCD_CMD_BITS 8
|
|
#define LCD_PARAM_BITS 8
|
|
|
|
static esp_lcd_panel_handle_t s_panel = NULL;
|
|
static lv_disp_t *s_disp = NULL;
|
|
|
|
esp_err_t display_manager_init(void)
|
|
{
|
|
if (s_disp != NULL) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
/* ponytail: native SPI bus init directly in display manager */
|
|
spi_bus_config_t buscfg = {
|
|
.sclk_io_num = HW_SPI_SCK_GPIO,
|
|
.mosi_io_num = HW_SPI_MOSI_GPIO,
|
|
.miso_io_num = HW_SPI_MISO_GPIO,
|
|
.quadwp_io_num = -1,
|
|
.quadhd_io_num = -1,
|
|
.max_transfer_sz = 240 * 80 * sizeof(uint16_t),
|
|
};
|
|
esp_err_t ret = spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO);
|
|
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
|
|
ESP_LOGE(TAG, "spi_bus_initialize failed: %s", esp_err_to_name(ret));
|
|
return ret;
|
|
}
|
|
|
|
/* 1. Initialize ST7789 panel via esp_lcd */
|
|
esp_lcd_panel_io_handle_t io = NULL;
|
|
esp_lcd_panel_io_spi_config_t io_config = {
|
|
.dc_gpio_num = HW_LCD_DC_GPIO,
|
|
.cs_gpio_num = HW_LCD_CS_GPIO,
|
|
.pclk_hz = LCD_PIXEL_CLOCK_HZ,
|
|
.lcd_cmd_bits = LCD_CMD_BITS,
|
|
.lcd_param_bits = LCD_PARAM_BITS,
|
|
.spi_mode = 0,
|
|
.trans_queue_depth = 10,
|
|
};
|
|
ret = esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io);
|
|
if (ret != ESP_OK) {
|
|
ESP_LOGE(TAG, "panel io init failed: %s", esp_err_to_name(ret));
|
|
return ret;
|
|
}
|
|
|
|
esp_lcd_panel_dev_config_t panel_config = {
|
|
.reset_gpio_num = HW_LCD_RST_GPIO,
|
|
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
|
.bits_per_pixel = 16,
|
|
};
|
|
ret = esp_lcd_new_panel_st7789(io, &panel_config, &s_panel);
|
|
if (ret != ESP_OK) {
|
|
ESP_LOGE(TAG, "st7789 panel create failed: %s", esp_err_to_name(ret));
|
|
return ret;
|
|
}
|
|
|
|
ESP_ERROR_CHECK(esp_lcd_panel_reset(s_panel));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_init(s_panel));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_invert_color(s_panel, true));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_mirror(s_panel, false, false));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(s_panel, true));
|
|
|
|
/* 2. Initialize LVGL port on Core 1 */
|
|
lvgl_port_cfg_t port_cfg = ESP_LVGL_PORT_INIT_CONFIG();
|
|
port_cfg.task_affinity = 1;
|
|
ret = lvgl_port_init(&port_cfg);
|
|
if (ret != ESP_OK) {
|
|
ESP_LOGE(TAG, "lvgl port init failed: %s", esp_err_to_name(ret));
|
|
return ret;
|
|
}
|
|
|
|
/* 20 lines buffer (240 * 20 * 2 = 9.6 KB) - lean SRAM footprint */
|
|
lvgl_port_display_cfg_t disp_cfg = {
|
|
.io_handle = io,
|
|
.panel_handle = s_panel,
|
|
.buffer_size = DISP_W * 20,
|
|
.double_buffer = false,
|
|
.hres = DISP_W,
|
|
.vres = DISP_H,
|
|
.monochrome = false,
|
|
.rotation = {
|
|
.swap_xy = false,
|
|
.mirror_x = false,
|
|
.mirror_y = false,
|
|
},
|
|
.flags = {
|
|
.buff_dma = true,
|
|
},
|
|
};
|
|
s_disp = lvgl_port_add_disp(&disp_cfg);
|
|
if (s_disp == NULL) {
|
|
ESP_LOGE(TAG, "lvgl_port_add_disp failed");
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
ESP_LOGI(TAG, "ST7789 %dx%d with LVGL ready (CS=%d DC=%d RST=%d)",
|
|
DISP_W, DISP_H, HW_LCD_CS_GPIO, HW_LCD_DC_GPIO, HW_LCD_RST_GPIO);
|
|
return ESP_OK;
|
|
}
|
|
|
|
lv_disp_t *display_get_disp(void)
|
|
{
|
|
return s_disp;
|
|
} |