Power off drops the peripheral rail (PWR_ON low), sleeps the panel and puts the chip into deep sleep with ext1 wake armed on the encoder pins, choosing any-low or any-high from the knob's resting state so a single detent wakes it. The button (GPIO0) is not a wake source on purpose.
100 lines
3.7 KiB
C
100 lines
3.7 KiB
C
#include "display.h"
|
|
#include "board.h"
|
|
#include "sdkconfig.h"
|
|
#include "driver/spi_master.h"
|
|
#include "driver/ledc.h"
|
|
#include "esp_lcd_panel_io.h"
|
|
#include "esp_lcd_panel_vendor.h"
|
|
#include "esp_lcd_panel_ops.h"
|
|
#include "esp_lvgl_port.h"
|
|
#include "esp_log.h"
|
|
|
|
static const char *TAG = "display";
|
|
|
|
#define LCD_SPI_HOST SPI2_HOST
|
|
#define BL_TIMER LEDC_TIMER_0
|
|
#define BL_CHANNEL LEDC_CHANNEL_0
|
|
|
|
static esp_lcd_panel_handle_t panel;
|
|
|
|
static void backlight_init(void)
|
|
{
|
|
ledc_timer_config_t timer = {
|
|
.speed_mode = LEDC_LOW_SPEED_MODE, .duty_resolution = LEDC_TIMER_10_BIT,
|
|
.timer_num = BL_TIMER, .freq_hz = 5000, .clk_cfg = LEDC_AUTO_CLK,
|
|
};
|
|
ESP_ERROR_CHECK(ledc_timer_config(&timer));
|
|
ledc_channel_config_t ch = {
|
|
.gpio_num = board->lcd_bl, .speed_mode = LEDC_LOW_SPEED_MODE, .channel = BL_CHANNEL,
|
|
.timer_sel = BL_TIMER, .duty = 0, .hpoint = 0,
|
|
};
|
|
ESP_ERROR_CHECK(ledc_channel_config(&ch));
|
|
}
|
|
|
|
void display_set_backlight(uint8_t percent)
|
|
{
|
|
if (percent > 100) percent = 100;
|
|
// perceptual-ish curve so 50% doesn't look like 90%
|
|
uint32_t duty = (1023u * percent * percent) / 10000u;
|
|
ledc_set_duty(LEDC_LOW_SPEED_MODE, BL_CHANNEL, duty);
|
|
ledc_update_duty(LEDC_LOW_SPEED_MODE, BL_CHANNEL);
|
|
}
|
|
|
|
void display_init(void)
|
|
{
|
|
backlight_init();
|
|
|
|
spi_bus_config_t bus = {
|
|
.mosi_io_num = board->lcd_mosi, .miso_io_num = board->lcd_miso, .sclk_io_num = board->lcd_sclk,
|
|
.quadwp_io_num = -1, .quadhd_io_num = -1,
|
|
.max_transfer_sz = LCD_H_RES * 48 * sizeof(uint16_t),
|
|
};
|
|
ESP_ERROR_CHECK(spi_bus_initialize(LCD_SPI_HOST, &bus, SPI_DMA_CH_AUTO));
|
|
|
|
esp_lcd_panel_io_handle_t io = NULL;
|
|
esp_lcd_panel_io_spi_config_t io_cfg = {
|
|
.cs_gpio_num = board->lcd_cs, .dc_gpio_num = board->lcd_dc,
|
|
.spi_mode = 0, .pclk_hz = CONFIG_WIDGET_LCD_PCLK_MHZ * 1000 * 1000,
|
|
.trans_queue_depth = 10, .lcd_cmd_bits = 8, .lcd_param_bits = 8,
|
|
};
|
|
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_SPI_HOST, &io_cfg, &io));
|
|
|
|
esp_lcd_panel_dev_config_t panel_cfg = {
|
|
.reset_gpio_num = board->lcd_rst,
|
|
.rgb_ele_order = board->lcd_bgr ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB,
|
|
.bits_per_pixel = 16,
|
|
};
|
|
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io, &panel_cfg, &panel));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_init(panel));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel, true)); // IPS panel, TFT_INVERSION_ON
|
|
// TFT_eSPI setRotation(3) == MADCTL MV|MY; the 170 px axis sits at RAM column 35.
|
|
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel, true));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel, false, true));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_set_gap(panel, 0, 35));
|
|
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel, true));
|
|
|
|
lvgl_port_cfg_t port_cfg = ESP_LVGL_PORT_INIT_CONFIG();
|
|
port_cfg.task_stack = 10240;
|
|
port_cfg.task_affinity = 1;
|
|
ESP_ERROR_CHECK(lvgl_port_init(&port_cfg));
|
|
|
|
lvgl_port_display_cfg_t disp_cfg = {
|
|
.io_handle = io, .panel_handle = panel,
|
|
.buffer_size = LCD_H_RES * 40, .double_buffer = true,
|
|
.hres = LCD_H_RES, .vres = LCD_V_RES, .monochrome = false,
|
|
.rotation = {.swap_xy = true, .mirror_x = false, .mirror_y = true},
|
|
.color_format = LV_COLOR_FORMAT_RGB565,
|
|
.flags = {.buff_dma = true, .buff_spiram = false, .swap_bytes = true},
|
|
};
|
|
lv_display_t *disp = lvgl_port_add_disp(&disp_cfg);
|
|
if (!disp) { ESP_LOGE(TAG, "lvgl_port_add_disp failed"); abort(); }
|
|
ESP_LOGI(TAG, "ST7789 %dx%d up at %d MHz", LCD_H_RES, LCD_V_RES, CONFIG_WIDGET_LCD_PCLK_MHZ);
|
|
}
|
|
|
|
void display_off(void)
|
|
{
|
|
display_set_backlight(0);
|
|
if (panel) esp_lcd_panel_disp_on_off(panel, false);
|
|
}
|