Files
MTGcompanion/main/display_manager.c
Rasmus 8d034ed1df
All checks were successful
ESP32 Build & Release / build (push) Successful in 1m12s
change display to 8 mhz
2026-09-13 23:21:09 +02:00

137 lines
4.0 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 (8 * 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;
}
/* 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, true, true));
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 = true,
.mirror_y = true,
},
.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;
}
static bool s_sleeping = false;
esp_err_t display_set_sleep(bool sleep)
{
if (s_panel == NULL) {
return ESP_ERR_INVALID_STATE;
}
if (s_sleeping == sleep) {
return ESP_OK;
}
s_sleeping = sleep;
ESP_LOGI(TAG, "Display %s", sleep ? "sleep (off)" : "wake (on)");
return esp_lcd_panel_disp_on_off(s_panel, !sleep);
}
bool display_is_sleeping(void)
{
return s_sleeping;
}