@@ -0,0 +1,76 @@
|
||||
set(srcs
|
||||
"hw_init.c"
|
||||
"input/touch_init.c"
|
||||
"input/touch_rotation_helper.c"
|
||||
"input/knob_init.c"
|
||||
"helpers/lcd_orientation_helper.c"
|
||||
)
|
||||
|
||||
if(CONFIG_EXAMPLE_LCD_INTERFACE_MIPI_DSI)
|
||||
list(APPEND srcs "lcd/lcd_init_mipi_dsi.c")
|
||||
elseif(CONFIG_EXAMPLE_LCD_INTERFACE_QSPI)
|
||||
list(APPEND srcs "lcd/lcd_init_qspi.c")
|
||||
elseif(CONFIG_EXAMPLE_LCD_INTERFACE_RGB)
|
||||
list(APPEND srcs "lcd/lcd_init_rgb.c")
|
||||
elseif(CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM)
|
||||
list(APPEND srcs "lcd/lcd_init_spi_with_psram.c")
|
||||
elseif(CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITHOUT_PSRAM)
|
||||
list(APPEND srcs "lcd/lcd_init_spi_without_psram.c")
|
||||
else()
|
||||
list(APPEND srcs "lcd/lcd_init_spi_with_psram.c")
|
||||
endif()
|
||||
|
||||
set(include_dirs "." "lcd" "input" "helpers")
|
||||
|
||||
set(component_requires driver;esp_lcd;esp_lvgl_adapter)
|
||||
|
||||
if(CONFIG_EXAMPLE_LCD_INTERFACE_MIPI_DSI)
|
||||
list(APPEND component_requires esp_lcd_ek79007)
|
||||
list(APPEND component_requires espressif__esp_lcd_touch_gt911)
|
||||
endif()
|
||||
|
||||
if(CONFIG_EXAMPLE_LCD_INTERFACE_QSPI)
|
||||
list(APPEND component_requires esp_lcd_st77916)
|
||||
list(APPEND component_requires espressif__esp_lcd_touch_cst816s)
|
||||
endif()
|
||||
|
||||
if(CONFIG_EXAMPLE_LCD_INTERFACE_RGB)
|
||||
list(APPEND component_requires espressif__esp_lcd_touch_gt1151)
|
||||
endif()
|
||||
|
||||
if(CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM)
|
||||
list(APPEND component_requires espressif__esp_lcd_ili9341)
|
||||
list(APPEND component_requires espressif__esp_lcd_touch_gt911)
|
||||
endif()
|
||||
|
||||
if(CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITHOUT_PSRAM)
|
||||
list(APPEND component_requires espressif__esp_lcd_gc9a01)
|
||||
if("espressif__knob" IN_LIST build_components)
|
||||
list(APPEND component_requires espressif__knob)
|
||||
elseif("knob" IN_LIST build_components)
|
||||
list(APPEND component_requires knob)
|
||||
endif()
|
||||
if("espressif__button" IN_LIST build_components)
|
||||
list(APPEND component_requires espressif__button)
|
||||
elseif("button" IN_LIST build_components)
|
||||
list(APPEND component_requires button)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
idf_component_register(
|
||||
SRCS ${srcs}
|
||||
INCLUDE_DIRS ${include_dirs}
|
||||
REQUIRES ${component_requires}
|
||||
)
|
||||
|
||||
if(CONFIG_EXAMPLE_LCD_INTERFACE_MIPI_DSI)
|
||||
message(STATUS "hw_init: MIPI DSI + Touch")
|
||||
elseif(CONFIG_EXAMPLE_LCD_INTERFACE_QSPI)
|
||||
message(STATUS "hw_init: QSPI + Touch")
|
||||
elseif(CONFIG_EXAMPLE_LCD_INTERFACE_RGB)
|
||||
message(STATUS "hw_init: RGB + Touch")
|
||||
elseif(CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM)
|
||||
message(STATUS "hw_init: SPI (PSRAM) + Touch")
|
||||
elseif(CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITHOUT_PSRAM)
|
||||
message(STATUS "hw_init: SPI (No PSRAM) + Encoder")
|
||||
endif()
|
||||
@@ -0,0 +1,79 @@
|
||||
menu "Hardware Configuration"
|
||||
|
||||
choice EXAMPLE_LCD_INTERFACE
|
||||
prompt "LCD Interface Type"
|
||||
default EXAMPLE_LCD_INTERFACE_MIPI_DSI if IDF_TARGET_ESP32P4
|
||||
default EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM if IDF_TARGET_ESP32S3
|
||||
default EXAMPLE_LCD_INTERFACE_SPI_WITHOUT_PSRAM if IDF_TARGET_ESP32C3
|
||||
default EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM
|
||||
help
|
||||
Select the LCD interface type for your display.
|
||||
Resolution and input device will be set automatically based on the interface.
|
||||
|
||||
config EXAMPLE_LCD_INTERFACE_MIPI_DSI
|
||||
bool "MIPI DSI Interface (1024x600, Touch)"
|
||||
depends on IDF_TARGET_ESP32P4
|
||||
help
|
||||
MIPI DSI interface for high-resolution displays.
|
||||
Resolution: 1024x600
|
||||
Input: Touch panel
|
||||
Only available on ESP32-P4.
|
||||
|
||||
config EXAMPLE_LCD_INTERFACE_QSPI
|
||||
bool "QSPI Interface (360x360, Touch)"
|
||||
depends on !IDF_TARGET_ESP32C3
|
||||
help
|
||||
QSPI (Quad SPI) interface for medium-resolution displays.
|
||||
Resolution: 360x360
|
||||
Input: Touch panel
|
||||
Requires PSRAM. Not available on ESP32-C3.
|
||||
|
||||
config EXAMPLE_LCD_INTERFACE_RGB
|
||||
bool "RGB Interface (800x480, Touch)"
|
||||
depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4
|
||||
help
|
||||
RGB parallel interface for medium to high-resolution displays.
|
||||
Resolution: 800x480
|
||||
Input: Touch panel
|
||||
Requires PSRAM. Available on ESP32-S3 and ESP32-P4.
|
||||
|
||||
config EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM
|
||||
bool "SPI Interface with PSRAM (320x240, Touch)"
|
||||
depends on !IDF_TARGET_ESP32C3
|
||||
help
|
||||
Standard SPI interface with PSRAM support.
|
||||
Resolution: 320x240
|
||||
Input: Touch panel
|
||||
Not available on ESP32-C3.
|
||||
|
||||
config EXAMPLE_LCD_INTERFACE_SPI_WITHOUT_PSRAM
|
||||
bool "SPI Interface without PSRAM (240x240, Encoder)"
|
||||
help
|
||||
Standard SPI interface without PSRAM.
|
||||
Resolution: 240x240
|
||||
Input: Encoder/Knob
|
||||
Suitable for resource-constrained chips.
|
||||
endchoice
|
||||
|
||||
choice EXAMPLE_DISPLAY_ROTATION
|
||||
prompt "Display Rotation"
|
||||
default EXAMPLE_DISPLAY_ROTATION_0
|
||||
help
|
||||
Select the rotation applied to both the LCD panel and the touch controller
|
||||
so that LVGL coordinates match the screen orientation.
|
||||
|
||||
config EXAMPLE_DISPLAY_ROTATION_0
|
||||
bool "Rotate 0 degrees"
|
||||
|
||||
config EXAMPLE_DISPLAY_ROTATION_90
|
||||
bool "Rotate 90 degrees clockwise"
|
||||
|
||||
config EXAMPLE_DISPLAY_ROTATION_180
|
||||
bool "Rotate 180 degrees"
|
||||
|
||||
config EXAMPLE_DISPLAY_ROTATION_270
|
||||
bool "Rotate 270 degrees clockwise"
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "lcd_orientation_helper.h"
|
||||
|
||||
typedef struct {
|
||||
int m00;
|
||||
int m01;
|
||||
int m10;
|
||||
int m11;
|
||||
} lcd_orientation_matrix_t;
|
||||
|
||||
static lcd_orientation_matrix_t matrix_from_flags(bool swap_xy, bool mirror_x, bool mirror_y)
|
||||
{
|
||||
int axis_x_x = 1;
|
||||
int axis_x_y = 0;
|
||||
int axis_y_x = 0;
|
||||
int axis_y_y = 1;
|
||||
|
||||
if (swap_xy) {
|
||||
int tmp_x = axis_x_x;
|
||||
int tmp_y = axis_x_y;
|
||||
axis_x_x = axis_y_x;
|
||||
axis_x_y = axis_y_y;
|
||||
axis_y_x = tmp_x;
|
||||
axis_y_y = tmp_y;
|
||||
}
|
||||
|
||||
if (mirror_x) {
|
||||
axis_x_x = -axis_x_x;
|
||||
axis_x_y = -axis_x_y;
|
||||
}
|
||||
if (mirror_y) {
|
||||
axis_y_x = -axis_y_x;
|
||||
axis_y_y = -axis_y_y;
|
||||
}
|
||||
|
||||
lcd_orientation_matrix_t matrix = {
|
||||
.m00 = axis_x_x,
|
||||
.m01 = axis_y_x,
|
||||
.m10 = axis_x_y,
|
||||
.m11 = axis_y_y,
|
||||
};
|
||||
return matrix;
|
||||
}
|
||||
|
||||
static lcd_orientation_matrix_t matrix_multiply(lcd_orientation_matrix_t lhs, lcd_orientation_matrix_t rhs)
|
||||
{
|
||||
lcd_orientation_matrix_t result = {
|
||||
.m00 = lhs.m00 * rhs.m00 + lhs.m01 * rhs.m10,
|
||||
.m01 = lhs.m00 * rhs.m01 + lhs.m01 * rhs.m11,
|
||||
.m10 = lhs.m10 * rhs.m00 + lhs.m11 * rhs.m10,
|
||||
.m11 = lhs.m10 * rhs.m01 + lhs.m11 * rhs.m11,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
static lcd_orientation_matrix_t matrix_from_rotation(esp_lv_adapter_rotation_t rotation)
|
||||
{
|
||||
switch (rotation) {
|
||||
case ESP_LV_ADAPTER_ROTATE_90:
|
||||
return matrix_from_flags(true, true, false);
|
||||
case ESP_LV_ADAPTER_ROTATE_180:
|
||||
return matrix_from_flags(false, true, true);
|
||||
case ESP_LV_ADAPTER_ROTATE_270:
|
||||
return matrix_from_flags(true, false, true);
|
||||
case ESP_LV_ADAPTER_ROTATE_0:
|
||||
default:
|
||||
return matrix_from_flags(false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_get_orientation_flags(bool base_swap_xy, bool base_mirror_x, bool base_mirror_y,
|
||||
esp_lv_adapter_rotation_t rotation,
|
||||
bool *swap_xy, bool *mirror_x, bool *mirror_y)
|
||||
{
|
||||
lcd_orientation_matrix_t base = matrix_from_flags(base_swap_xy, base_mirror_x, base_mirror_y);
|
||||
lcd_orientation_matrix_t rotation_matrix = matrix_from_rotation(rotation);
|
||||
lcd_orientation_matrix_t desired = matrix_multiply(rotation_matrix, base);
|
||||
|
||||
for (int test_swap = 0; test_swap <= 1; ++test_swap) {
|
||||
for (int test_mirror_x = 0; test_mirror_x <= 1; ++test_mirror_x) {
|
||||
for (int test_mirror_y = 0; test_mirror_y <= 1; ++test_mirror_y) {
|
||||
lcd_orientation_matrix_t candidate = matrix_from_flags(test_swap, test_mirror_x, test_mirror_y);
|
||||
if (candidate.m00 == desired.m00 &&
|
||||
candidate.m01 == desired.m01 &&
|
||||
candidate.m10 == desired.m10 &&
|
||||
candidate.m11 == desired.m11) {
|
||||
if (swap_xy) {
|
||||
*swap_xy = (bool)test_swap;
|
||||
}
|
||||
if (mirror_x) {
|
||||
*mirror_x = (bool)test_mirror_x;
|
||||
}
|
||||
if (mirror_y) {
|
||||
*mirror_y = (bool)test_mirror_y;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (swap_xy) {
|
||||
*swap_xy = base_swap_xy;
|
||||
}
|
||||
if (mirror_x) {
|
||||
*mirror_x = base_mirror_x;
|
||||
}
|
||||
if (mirror_y) {
|
||||
*mirror_y = base_mirror_y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_lv_adapter_display.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void lcd_get_orientation_flags(bool base_swap_xy, bool base_mirror_x, bool base_mirror_y,
|
||||
esp_lv_adapter_rotation_t rotation,
|
||||
bool *swap_xy, bool *mirror_x, bool *mirror_y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hw_init.h"
|
||||
#if !CONFIG_EXAMPLE_LCD_INTERFACE_MIPI_DSI && \
|
||||
!CONFIG_EXAMPLE_LCD_INTERFACE_QSPI && \
|
||||
!CONFIG_EXAMPLE_LCD_INTERFACE_RGB && \
|
||||
!CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM && \
|
||||
!CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITHOUT_PSRAM
|
||||
#error "No LCD interface selected! Please select one in menuconfig."
|
||||
#endif
|
||||
|
||||
#if !HW_USE_TOUCH && !HW_USE_ENCODER
|
||||
#error "No input device configured!"
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lcd_panel_io.h"
|
||||
#include "esp_lv_adapter_display.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_LCD_INTERFACE_MIPI_DSI
|
||||
#define HW_LCD_H_RES 1024
|
||||
#define HW_LCD_V_RES 600
|
||||
#define HW_USE_TOUCH 1
|
||||
#define HW_USE_ENCODER 0
|
||||
#elif CONFIG_EXAMPLE_LCD_INTERFACE_QSPI
|
||||
#define HW_LCD_H_RES 360
|
||||
#define HW_LCD_V_RES 360
|
||||
#define HW_USE_TOUCH 0
|
||||
#define HW_USE_ENCODER 1
|
||||
#elif CONFIG_EXAMPLE_LCD_INTERFACE_RGB
|
||||
#define HW_LCD_H_RES 800
|
||||
#define HW_LCD_V_RES 480
|
||||
#define HW_USE_TOUCH 1
|
||||
#define HW_USE_ENCODER 0
|
||||
#elif CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM
|
||||
#define HW_LCD_H_RES 320
|
||||
#define HW_LCD_V_RES 240
|
||||
#define HW_USE_TOUCH 1
|
||||
#define HW_USE_ENCODER 0
|
||||
#elif CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITHOUT_PSRAM
|
||||
#define HW_LCD_H_RES 240
|
||||
#define HW_LCD_V_RES 240
|
||||
#define HW_USE_TOUCH 0
|
||||
#define HW_USE_ENCODER 1
|
||||
#else
|
||||
#define HW_LCD_H_RES 320
|
||||
#define HW_LCD_V_RES 240
|
||||
#define HW_USE_TOUCH 1
|
||||
#define HW_USE_ENCODER 0
|
||||
#endif
|
||||
|
||||
esp_err_t hw_lcd_init(esp_lcd_panel_handle_t *panel_handle,
|
||||
esp_lcd_panel_io_handle_t *io_handle,
|
||||
esp_lv_adapter_tear_avoid_mode_t tear_avoid_mode,
|
||||
esp_lv_adapter_rotation_t rotation);
|
||||
|
||||
#if HW_USE_TOUCH
|
||||
#include "esp_lcd_touch.h"
|
||||
|
||||
esp_err_t hw_touch_init(esp_lcd_touch_handle_t *touch_handle,
|
||||
esp_lv_adapter_rotation_t rotation);
|
||||
|
||||
#endif
|
||||
|
||||
#if HW_USE_ENCODER
|
||||
#include "iot_knob.h"
|
||||
#include "iot_button.h"
|
||||
|
||||
const knob_config_t *hw_knob_get_config(void);
|
||||
button_handle_t hw_knob_get_button(void);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
version: "1.0.0"
|
||||
|
||||
dependencies:
|
||||
idf:
|
||||
version: ">=5.5.0"
|
||||
|
||||
esp_lvgl_adapter:
|
||||
version: "==0.1.0-beta.1"
|
||||
|
||||
esp_lcd_ek79007:
|
||||
version: "*"
|
||||
rules:
|
||||
- if: "target == esp32p4"
|
||||
|
||||
esp_lcd_st77916:
|
||||
version: "*"
|
||||
|
||||
esp_lcd_ili9341:
|
||||
version: "^2"
|
||||
|
||||
esp_lcd_gc9a01:
|
||||
version: "^2"
|
||||
|
||||
espressif/esp_lcd_touch_gt911:
|
||||
version: "^1"
|
||||
|
||||
espressif/esp_lcd_touch_gt1151:
|
||||
version: "^1"
|
||||
|
||||
espressif/esp_lcd_touch_cst816s:
|
||||
version: "^1"
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hw_init.h"
|
||||
|
||||
#if HW_USE_ENCODER
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_log.h"
|
||||
#include "iot_knob.h"
|
||||
#include "iot_button.h"
|
||||
#include "button_gpio.h"
|
||||
|
||||
#define HW_ENCODER_A (GPIO_NUM_10)
|
||||
#define HW_ENCODER_B (GPIO_NUM_6)
|
||||
#define HW_ENCODER_ENTER (GPIO_NUM_9)
|
||||
|
||||
static const char *TAG = "hw_knob_init";
|
||||
|
||||
static const knob_config_t hw_knob_encoder_config = {
|
||||
.default_direction = 0,
|
||||
.gpio_encoder_a = HW_ENCODER_A,
|
||||
.gpio_encoder_b = HW_ENCODER_B,
|
||||
.enable_power_save = false,
|
||||
};
|
||||
|
||||
static button_handle_t s_encoder_button_handle = NULL;
|
||||
|
||||
const knob_config_t *hw_knob_get_config(void)
|
||||
{
|
||||
return &hw_knob_encoder_config;
|
||||
}
|
||||
|
||||
button_handle_t hw_knob_get_button(void)
|
||||
{
|
||||
if (s_encoder_button_handle == NULL) {
|
||||
ESP_LOGI(TAG, "Initializing encoder button on GPIO %d", HW_ENCODER_ENTER);
|
||||
|
||||
const button_config_t btn_cfg = {
|
||||
.long_press_time = 0,
|
||||
.short_press_time = 0,
|
||||
};
|
||||
|
||||
const button_gpio_config_t btn_gpio_cfg = {
|
||||
.gpio_num = HW_ENCODER_ENTER,
|
||||
.active_level = 0,
|
||||
.enable_power_save = false,
|
||||
.disable_pull = false,
|
||||
};
|
||||
|
||||
esp_err_t ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &s_encoder_button_handle);
|
||||
if (ret != ESP_OK || s_encoder_button_handle == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create encoder button: %d", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Encoder button initialized successfully");
|
||||
}
|
||||
|
||||
return s_encoder_button_handle;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "driver/i2c_master.h"
|
||||
#include <stdbool.h>
|
||||
#include "esp_log.h"
|
||||
#include "hw_init.h"
|
||||
#include "input/touch_rotation_helper.h"
|
||||
|
||||
#if HW_USE_TOUCH
|
||||
|
||||
#if CONFIG_EXAMPLE_LCD_INTERFACE_RGB
|
||||
#include "esp_lcd_touch_gt1151.h"
|
||||
#define HW_LCD_TOUCH_RST (GPIO_NUM_NC)
|
||||
#define HW_LCD_TOUCH_INT (GPIO_NUM_NC)
|
||||
#define HW_I2C_SDA (GPIO_NUM_47)
|
||||
#define HW_I2C_SCL (GPIO_NUM_48)
|
||||
#define TOUCH_CONTROLLER_NAME "GT1151"
|
||||
#define TOUCH_ROTATION_TYPE TOUCH_ROTATION_STANDARD
|
||||
#define TOUCH_CONTROLLER_TYPE_GT1151 1
|
||||
|
||||
#elif CONFIG_EXAMPLE_LCD_INTERFACE_MIPI_DSI
|
||||
#include "esp_lcd_touch_gt911.h"
|
||||
#define HW_LCD_TOUCH_RST (GPIO_NUM_NC)
|
||||
#define HW_LCD_TOUCH_INT (GPIO_NUM_NC)
|
||||
#define HW_I2C_SDA (GPIO_NUM_7)
|
||||
#define HW_I2C_SCL (GPIO_NUM_8)
|
||||
#define TOUCH_CONTROLLER_NAME "GT911"
|
||||
#define TOUCH_ROTATION_TYPE TOUCH_ROTATION_MIPI_DSI
|
||||
#define TOUCH_CONTROLLER_TYPE_GT911 1
|
||||
|
||||
#elif CONFIG_EXAMPLE_LCD_INTERFACE_QSPI
|
||||
#include "esp_lcd_touch_cst816s.h"
|
||||
#define HW_LCD_TOUCH_RST (GPIO_NUM_NC)
|
||||
#define HW_LCD_TOUCH_INT (GPIO_NUM_10)
|
||||
#define HW_I2C_SDA (GPIO_NUM_2)
|
||||
#define HW_I2C_SCL (GPIO_NUM_1)
|
||||
#define TOUCH_CONTROLLER_NAME "CST816S"
|
||||
#define TOUCH_ROTATION_TYPE TOUCH_ROTATION_STANDARD
|
||||
#define TOUCH_CONTROLLER_TYPE_CST816S 1
|
||||
|
||||
#elif CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM
|
||||
#include "esp_lcd_touch_gt911.h"
|
||||
#define HW_LCD_TOUCH_RST (GPIO_NUM_NC)
|
||||
#define HW_LCD_TOUCH_INT (GPIO_NUM_3)
|
||||
#define HW_I2C_SDA (GPIO_NUM_8)
|
||||
#define HW_I2C_SCL (GPIO_NUM_18)
|
||||
#define TOUCH_CONTROLLER_NAME "GT911"
|
||||
#define TOUCH_ROTATION_TYPE TOUCH_ROTATION_STANDARD
|
||||
#define TOUCH_CONTROLLER_TYPE_GT911 1
|
||||
|
||||
#else
|
||||
#include "esp_lcd_touch_gt911.h"
|
||||
#define HW_LCD_TOUCH_RST (GPIO_NUM_NC)
|
||||
#define HW_LCD_TOUCH_INT (GPIO_NUM_NC)
|
||||
#define HW_I2C_SDA (GPIO_NUM_7)
|
||||
#define HW_I2C_SCL (GPIO_NUM_8)
|
||||
#define TOUCH_CONTROLLER_NAME "GT911"
|
||||
#define TOUCH_ROTATION_TYPE TOUCH_ROTATION_STANDARD
|
||||
#define TOUCH_CONTROLLER_TYPE_GT911 1
|
||||
#endif
|
||||
|
||||
#define HW_I2C_NUM (I2C_NUM_0)
|
||||
#define HW_I2C_CLK_SPEED_HZ (400000)
|
||||
|
||||
static const char *TAG = "hw_touch_init";
|
||||
static i2c_master_bus_handle_t s_touch_i2c_bus = NULL;
|
||||
|
||||
static esp_err_t hw_touch_i2c_init(void)
|
||||
{
|
||||
if (s_touch_i2c_bus) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
i2c_master_bus_config_t i2c_bus_conf = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.sda_io_num = HW_I2C_SDA,
|
||||
.scl_io_num = HW_I2C_SCL,
|
||||
.i2c_port = HW_I2C_NUM,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_conf, &s_touch_i2c_bus));
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t hw_touch_init(esp_lcd_touch_handle_t *ret_touch, esp_lv_adapter_rotation_t rotation)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initializing touch controller (%s)", TOUCH_CONTROLLER_NAME);
|
||||
|
||||
ESP_ERROR_CHECK(hw_touch_i2c_init());
|
||||
|
||||
bool swap_xy = false;
|
||||
bool mirror_x = false;
|
||||
bool mirror_y = false;
|
||||
touch_get_rotation_flags(TOUCH_ROTATION_TYPE, rotation, &swap_xy, &mirror_x, &mirror_y);
|
||||
|
||||
const esp_lcd_touch_config_t tp_cfg = {
|
||||
.x_max = HW_LCD_H_RES,
|
||||
.y_max = HW_LCD_V_RES,
|
||||
.rst_gpio_num = HW_LCD_TOUCH_RST,
|
||||
.int_gpio_num = HW_LCD_TOUCH_INT,
|
||||
.levels = {
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags = {
|
||||
.swap_xy = swap_xy,
|
||||
.mirror_x = mirror_x,
|
||||
.mirror_y = mirror_y,
|
||||
},
|
||||
};
|
||||
|
||||
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
|
||||
|
||||
/* Initialize touch controller based on type */
|
||||
#if defined(TOUCH_CONTROLLER_TYPE_GT1151)
|
||||
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT1151_CONFIG();
|
||||
tp_io_config.scl_speed_hz = HW_I2C_CLK_SPEED_HZ;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(s_touch_i2c_bus, &tp_io_config, &tp_io_handle));
|
||||
return esp_lcd_touch_new_i2c_gt1151(tp_io_handle, &tp_cfg, ret_touch);
|
||||
|
||||
#elif defined(TOUCH_CONTROLLER_TYPE_CST816S)
|
||||
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG();
|
||||
tp_io_config.scl_speed_hz = HW_I2C_CLK_SPEED_HZ;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(s_touch_i2c_bus, &tp_io_config, &tp_io_handle));
|
||||
return esp_lcd_touch_new_i2c_cst816s(tp_io_handle, &tp_cfg, ret_touch);
|
||||
|
||||
#elif defined(TOUCH_CONTROLLER_TYPE_GT911)
|
||||
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
|
||||
tp_io_config.scl_speed_hz = HW_I2C_CLK_SPEED_HZ;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(s_touch_i2c_bus, &tp_io_config, &tp_io_handle));
|
||||
return esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, ret_touch);
|
||||
|
||||
#else
|
||||
#error "No touch controller type defined"
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "touch_rotation_helper.h"
|
||||
|
||||
void touch_get_rotation_flags(touch_rotation_type_t type, esp_lv_adapter_rotation_t rotation,
|
||||
bool *swap_xy, bool *mirror_x, bool *mirror_y)
|
||||
{
|
||||
bool swap = false;
|
||||
bool x_mirror, y_mirror;
|
||||
|
||||
if (type == TOUCH_ROTATION_MIPI_DSI) {
|
||||
x_mirror = true;
|
||||
y_mirror = true;
|
||||
switch (rotation) {
|
||||
case ESP_LV_ADAPTER_ROTATE_90:
|
||||
swap = true;
|
||||
x_mirror = false;
|
||||
y_mirror = true;
|
||||
break;
|
||||
case ESP_LV_ADAPTER_ROTATE_180:
|
||||
swap = false;
|
||||
x_mirror = false;
|
||||
y_mirror = false;
|
||||
break;
|
||||
case ESP_LV_ADAPTER_ROTATE_270:
|
||||
swap = true;
|
||||
x_mirror = true;
|
||||
y_mirror = false;
|
||||
break;
|
||||
case ESP_LV_ADAPTER_ROTATE_0:
|
||||
default:
|
||||
swap = false;
|
||||
x_mirror = true;
|
||||
y_mirror = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
x_mirror = false;
|
||||
y_mirror = false;
|
||||
switch (rotation) {
|
||||
case ESP_LV_ADAPTER_ROTATE_90:
|
||||
swap = true;
|
||||
x_mirror = true;
|
||||
y_mirror = false;
|
||||
break;
|
||||
case ESP_LV_ADAPTER_ROTATE_180:
|
||||
swap = false;
|
||||
x_mirror = true;
|
||||
y_mirror = true;
|
||||
break;
|
||||
case ESP_LV_ADAPTER_ROTATE_270:
|
||||
swap = true;
|
||||
x_mirror = false;
|
||||
y_mirror = true;
|
||||
break;
|
||||
case ESP_LV_ADAPTER_ROTATE_0:
|
||||
default:
|
||||
swap = false;
|
||||
x_mirror = false;
|
||||
y_mirror = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (swap_xy) {
|
||||
*swap_xy = swap;
|
||||
}
|
||||
if (mirror_x) {
|
||||
*mirror_x = x_mirror;
|
||||
}
|
||||
if (mirror_y) {
|
||||
*mirror_y = y_mirror;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_lv_adapter_display.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
TOUCH_ROTATION_STANDARD,
|
||||
TOUCH_ROTATION_MIPI_DSI,
|
||||
} touch_rotation_type_t;
|
||||
|
||||
void touch_get_rotation_flags(touch_rotation_type_t type, esp_lv_adapter_rotation_t rotation,
|
||||
bool *swap_xy, bool *mirror_x, bool *mirror_y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "hw_init.h"
|
||||
|
||||
#if CONFIG_EXAMPLE_LCD_INTERFACE_MIPI_DSI
|
||||
|
||||
#include "esp_ldo_regulator.h"
|
||||
#include "esp_lcd_mipi_dsi.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lcd_ek79007.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
static const char *TAG = "hw_lcd_init";
|
||||
|
||||
#define HW_LDO_MIPI_CHAN (3)
|
||||
#define HW_LDO_MIPI_VOLTAGE_MV (2500)
|
||||
#define HW_LCD_BIT_PER_PIXEL (16)
|
||||
#define HW_MIPI_DPI_PX_FORMAT (LCD_COLOR_PIXEL_FORMAT_RGB565)
|
||||
#define HW_PIN_NUM_LCD_RST (27)
|
||||
|
||||
static esp_lcd_dsi_bus_handle_t s_mipi_dsi_bus;
|
||||
static esp_lcd_panel_io_handle_t s_mipi_dbi_io;
|
||||
static esp_lcd_panel_handle_t s_panel_handle;
|
||||
|
||||
static void lcd_ldo_power_on(void)
|
||||
{
|
||||
esp_ldo_channel_handle_t ldo_mipi_phy = NULL;
|
||||
esp_ldo_channel_config_t ldo_mipi_phy_config = {
|
||||
.chan_id = HW_LDO_MIPI_CHAN,
|
||||
.voltage_mv = HW_LDO_MIPI_VOLTAGE_MV,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy));
|
||||
}
|
||||
|
||||
esp_err_t hw_lcd_init(esp_lcd_panel_handle_t *panel_handle, esp_lcd_panel_io_handle_t *io_handle, esp_lv_adapter_tear_avoid_mode_t tear_avoid_mode, esp_lv_adapter_rotation_t rotation)
|
||||
{
|
||||
lcd_ldo_power_on();
|
||||
|
||||
ESP_LOGD(TAG, "Install LCD driver");
|
||||
esp_lcd_dsi_bus_config_t bus_config = EK79007_PANEL_BUS_DSI_2CH_CONFIG();
|
||||
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &s_mipi_dsi_bus));
|
||||
|
||||
ESP_LOGI(TAG, "Install panel IO");
|
||||
esp_lcd_dbi_io_config_t dbi_config = EK79007_PANEL_IO_DBI_CONFIG();
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(s_mipi_dsi_bus, &dbi_config, &s_mipi_dbi_io));
|
||||
|
||||
ESP_LOGI(TAG, "Install LCD driver of ek79007");
|
||||
esp_lcd_dpi_panel_config_t dpi_config = EK79007_1024_600_PANEL_60HZ_CONFIG(HW_MIPI_DPI_PX_FORMAT);
|
||||
dpi_config.num_fbs = esp_lv_adapter_get_required_frame_buffer_count(tear_avoid_mode, rotation);
|
||||
ek79007_vendor_config_t vendor_config = {
|
||||
.mipi_config = {
|
||||
.dsi_bus = s_mipi_dsi_bus,
|
||||
.dpi_config = &dpi_config,
|
||||
},
|
||||
};
|
||||
const esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = HW_PIN_NUM_LCD_RST,
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
||||
.bits_per_pixel = HW_LCD_BIT_PER_PIXEL,
|
||||
.vendor_config = &vendor_config,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_ek79007(s_mipi_dbi_io, &panel_config, &s_panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_reset(s_panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_init(s_panel_handle));
|
||||
|
||||
*panel_handle = s_panel_handle;
|
||||
if (io_handle) {
|
||||
*io_handle = s_mipi_dbi_io;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_lcd_st77916.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "hw_init.h"
|
||||
#include "helpers/lcd_orientation_helper.h"
|
||||
|
||||
#if CONFIG_EXAMPLE_LCD_INTERFACE_QSPI
|
||||
|
||||
static const char *TAG = "hw_lcd_init";
|
||||
|
||||
#define HW_PIN_NUM_BK_LIGHT (GPIO_NUM_44)
|
||||
#define HW_LCD_BK_LIGHT_ON_LEVEL (1)
|
||||
#define HW_LCD_BASE_SWAP_XY (false)
|
||||
#define HW_LCD_BASE_MIRROR_X (false)
|
||||
#define HW_LCD_BASE_MIRROR_Y (false)
|
||||
|
||||
#define HW_LCD_DATA3 (GPIO_NUM_12)
|
||||
#define HW_LCD_DATA2 (GPIO_NUM_11)
|
||||
#define HW_LCD_DATA1 (GPIO_NUM_13)
|
||||
#define HW_LCD_DATA0 (GPIO_NUM_46)
|
||||
#define HW_LCD_PCLK (GPIO_NUM_18)
|
||||
#define HW_LCD_CS (GPIO_NUM_14)
|
||||
#define HW_LCD_DC (GPIO_NUM_45)
|
||||
#define HW_LCD_RST (GPIO_NUM_47)
|
||||
#define HW_LCD_POWER_OFF (GPIO_NUM_9)
|
||||
|
||||
#define HW_LCD_PIXEL_CLOCK_HZ (80 * 1000 * 1000)
|
||||
#define HW_LCD_COLOR_SPACE (LCD_RGB_ELEMENT_ORDER_RGB)
|
||||
#define HW_LCD_BITS_PER_PIXEL (16)
|
||||
#define HW_LCD_CMD_BITS (32)
|
||||
#define HW_LCD_PARAM_BITS (8)
|
||||
#define HW_LCD_MAX_TRANSFER_SZ (HW_LCD_H_RES * HW_LCD_V_RES * 2)
|
||||
|
||||
static esp_lcd_panel_io_handle_t s_panel_io_handle;
|
||||
static esp_lcd_panel_handle_t s_panel_handle;
|
||||
|
||||
static const st77916_lcd_init_cmd_t st77916_qspi_init[] = {
|
||||
{0xF0, (uint8_t []){0x28}, 1, 0},
|
||||
{0xF2, (uint8_t []){0x28}, 1, 0},
|
||||
{0x73, (uint8_t []){0xF0}, 1, 0},
|
||||
{0x7C, (uint8_t []){0xD1}, 1, 0},
|
||||
{0x83, (uint8_t []){0xE0}, 1, 0},
|
||||
{0x84, (uint8_t []){0x61}, 1, 0},
|
||||
{0xF2, (uint8_t []){0x82}, 1, 0},
|
||||
{0xF0, (uint8_t []){0x00}, 1, 0},
|
||||
{0xF0, (uint8_t []){0x01}, 1, 0},
|
||||
{0xF1, (uint8_t []){0x01}, 1, 0},
|
||||
{0xB0, (uint8_t []){0x56}, 1, 0},
|
||||
{0xB1, (uint8_t []){0x4D}, 1, 0},
|
||||
{0xB2, (uint8_t []){0x24}, 1, 0},
|
||||
{0xB4, (uint8_t []){0x87}, 1, 0},
|
||||
{0xB5, (uint8_t []){0x44}, 1, 0},
|
||||
{0xB6, (uint8_t []){0x8B}, 1, 0},
|
||||
{0xB7, (uint8_t []){0x40}, 1, 0},
|
||||
{0xB8, (uint8_t []){0x86}, 1, 0},
|
||||
{0xBA, (uint8_t []){0x00}, 1, 0},
|
||||
{0xBB, (uint8_t []){0x08}, 1, 0},
|
||||
{0xBC, (uint8_t []){0x08}, 1, 0},
|
||||
{0xBD, (uint8_t []){0x00}, 1, 0},
|
||||
{0xC0, (uint8_t []){0x80}, 1, 0},
|
||||
{0xC1, (uint8_t []){0x10}, 1, 0},
|
||||
{0xC2, (uint8_t []){0x37}, 1, 0},
|
||||
{0xC3, (uint8_t []){0x80}, 1, 0},
|
||||
{0xC4, (uint8_t []){0x10}, 1, 0},
|
||||
{0xC5, (uint8_t []){0x37}, 1, 0},
|
||||
{0xC6, (uint8_t []){0xA9}, 1, 0},
|
||||
{0xC7, (uint8_t []){0x41}, 1, 0},
|
||||
{0xC8, (uint8_t []){0x01}, 1, 0},
|
||||
{0xC9, (uint8_t []){0xA9}, 1, 0},
|
||||
{0xCA, (uint8_t []){0x41}, 1, 0},
|
||||
{0xCB, (uint8_t []){0x01}, 1, 0},
|
||||
{0xD0, (uint8_t []){0x91}, 1, 0},
|
||||
{0xD1, (uint8_t []){0x68}, 1, 0},
|
||||
{0xD2, (uint8_t []){0x68}, 1, 0},
|
||||
{0xF5, (uint8_t []){0x00, 0xA5}, 2, 0},
|
||||
{0xDD, (uint8_t []){0x4F}, 1, 0},
|
||||
{0xDE, (uint8_t []){0x4F}, 1, 0},
|
||||
{0xF1, (uint8_t []){0x10}, 1, 0},
|
||||
{0xF0, (uint8_t []){0x00}, 1, 0},
|
||||
{0xF0, (uint8_t []){0x02}, 1, 0},
|
||||
{0xE0, (uint8_t []){0xF0, 0x0A, 0x10, 0x09, 0x09, 0x36, 0x35, 0x33, 0x4A, 0x29, 0x15, 0x15, 0x2E, 0x34}, 14, 0},
|
||||
{0xE1, (uint8_t []){0xF0, 0x0A, 0x0F, 0x08, 0x08, 0x05, 0x34, 0x33, 0x4A, 0x39, 0x15, 0x15, 0x2D, 0x33}, 14, 0},
|
||||
{0xF0, (uint8_t []){0x10}, 1, 0},
|
||||
{0xF3, (uint8_t []){0x10}, 1, 0},
|
||||
{0xE0, (uint8_t []){0x07}, 1, 0},
|
||||
{0xE1, (uint8_t []){0x00}, 1, 0},
|
||||
{0xE2, (uint8_t []){0x00}, 1, 0},
|
||||
{0xE3, (uint8_t []){0x00}, 1, 0},
|
||||
{0xE4, (uint8_t []){0xE0}, 1, 0},
|
||||
{0xE5, (uint8_t []){0x06}, 1, 0},
|
||||
{0xE6, (uint8_t []){0x21}, 1, 0},
|
||||
{0xE7, (uint8_t []){0x01}, 1, 0},
|
||||
{0xE8, (uint8_t []){0x05}, 1, 0},
|
||||
{0xE9, (uint8_t []){0x02}, 1, 0},
|
||||
{0xEA, (uint8_t []){0xDA}, 1, 0},
|
||||
{0xEB, (uint8_t []){0x00}, 1, 0},
|
||||
{0xEC, (uint8_t []){0x00}, 1, 0},
|
||||
{0xED, (uint8_t []){0x0F}, 1, 0},
|
||||
{0xEE, (uint8_t []){0x00}, 1, 0},
|
||||
{0xEF, (uint8_t []){0x00}, 1, 0},
|
||||
{0xF8, (uint8_t []){0x00}, 1, 0},
|
||||
{0xF9, (uint8_t []){0x00}, 1, 0},
|
||||
{0xFA, (uint8_t []){0x00}, 1, 0},
|
||||
{0xFB, (uint8_t []){0x00}, 1, 0},
|
||||
{0xFC, (uint8_t []){0x00}, 1, 0},
|
||||
{0xFD, (uint8_t []){0x00}, 1, 0},
|
||||
{0xFE, (uint8_t []){0x00}, 1, 0},
|
||||
{0xFF, (uint8_t []){0x00}, 1, 0},
|
||||
{0x60, (uint8_t []){0x40}, 1, 0},
|
||||
{0x61, (uint8_t []){0x04}, 1, 0},
|
||||
{0x62, (uint8_t []){0x00}, 1, 0},
|
||||
{0x63, (uint8_t []){0x42}, 1, 0},
|
||||
{0x64, (uint8_t []){0xD9}, 1, 0},
|
||||
{0x65, (uint8_t []){0x00}, 1, 0},
|
||||
{0x66, (uint8_t []){0x00}, 1, 0},
|
||||
{0x67, (uint8_t []){0x00}, 1, 0},
|
||||
{0x68, (uint8_t []){0x00}, 1, 0},
|
||||
{0x69, (uint8_t []){0x00}, 1, 0},
|
||||
{0x6A, (uint8_t []){0x00}, 1, 0},
|
||||
{0x6B, (uint8_t []){0x00}, 1, 0},
|
||||
{0x70, (uint8_t []){0x40}, 1, 0},
|
||||
{0x71, (uint8_t []){0x03}, 1, 0},
|
||||
{0x72, (uint8_t []){0x00}, 1, 0},
|
||||
{0x73, (uint8_t []){0x42}, 1, 0},
|
||||
{0x74, (uint8_t []){0xD8}, 1, 0},
|
||||
{0x75, (uint8_t []){0x00}, 1, 0},
|
||||
{0x76, (uint8_t []){0x00}, 1, 0},
|
||||
{0x77, (uint8_t []){0x00}, 1, 0},
|
||||
{0x78, (uint8_t []){0x00}, 1, 0},
|
||||
{0x79, (uint8_t []){0x00}, 1, 0},
|
||||
{0x7A, (uint8_t []){0x00}, 1, 0},
|
||||
{0x7B, (uint8_t []){0x00}, 1, 0},
|
||||
{0x80, (uint8_t []){0x48}, 1, 0},
|
||||
{0x81, (uint8_t []){0x00}, 1, 0},
|
||||
{0x82, (uint8_t []){0x06}, 1, 0},
|
||||
{0x83, (uint8_t []){0x02}, 1, 0},
|
||||
{0x84, (uint8_t []){0xD6}, 1, 0},
|
||||
{0x85, (uint8_t []){0x04}, 1, 0},
|
||||
{0x86, (uint8_t []){0x00}, 1, 0},
|
||||
{0x87, (uint8_t []){0x00}, 1, 0},
|
||||
{0x88, (uint8_t []){0x48}, 1, 0},
|
||||
{0x89, (uint8_t []){0x00}, 1, 0},
|
||||
{0x8A, (uint8_t []){0x08}, 1, 0},
|
||||
{0x8B, (uint8_t []){0x02}, 1, 0},
|
||||
{0x8C, (uint8_t []){0xD8}, 1, 0},
|
||||
{0x8D, (uint8_t []){0x04}, 1, 0},
|
||||
{0x8E, (uint8_t []){0x00}, 1, 0},
|
||||
{0x8F, (uint8_t []){0x00}, 1, 0},
|
||||
{0x90, (uint8_t []){0x48}, 1, 0},
|
||||
{0x91, (uint8_t []){0x00}, 1, 0},
|
||||
{0x92, (uint8_t []){0x0A}, 1, 0},
|
||||
{0x93, (uint8_t []){0x02}, 1, 0},
|
||||
{0x94, (uint8_t []){0xDA}, 1, 0},
|
||||
{0x95, (uint8_t []){0x04}, 1, 0},
|
||||
{0x96, (uint8_t []){0x00}, 1, 0},
|
||||
{0x97, (uint8_t []){0x00}, 1, 0},
|
||||
{0x98, (uint8_t []){0x48}, 1, 0},
|
||||
{0x99, (uint8_t []){0x00}, 1, 0},
|
||||
{0x9A, (uint8_t []){0x0C}, 1, 0},
|
||||
{0x9B, (uint8_t []){0x02}, 1, 0},
|
||||
{0x9C, (uint8_t []){0xDC}, 1, 0},
|
||||
{0x9D, (uint8_t []){0x04}, 1, 0},
|
||||
{0x9E, (uint8_t []){0x00}, 1, 0},
|
||||
{0x9F, (uint8_t []){0x00}, 1, 0},
|
||||
{0xA0, (uint8_t []){0x48}, 1, 0},
|
||||
{0xA1, (uint8_t []){0x00}, 1, 0},
|
||||
{0xA2, (uint8_t []){0x05}, 1, 0},
|
||||
{0xA3, (uint8_t []){0x02}, 1, 0},
|
||||
{0xA4, (uint8_t []){0xD5}, 1, 0},
|
||||
{0xA5, (uint8_t []){0x04}, 1, 0},
|
||||
{0xA6, (uint8_t []){0x00}, 1, 0},
|
||||
{0xA7, (uint8_t []){0x00}, 1, 0},
|
||||
{0xA8, (uint8_t []){0x48}, 1, 0},
|
||||
{0xA9, (uint8_t []){0x00}, 1, 0},
|
||||
{0xAA, (uint8_t []){0x07}, 1, 0},
|
||||
{0xAB, (uint8_t []){0x02}, 1, 0},
|
||||
{0xAC, (uint8_t []){0xD7}, 1, 0},
|
||||
{0xAD, (uint8_t []){0x04}, 1, 0},
|
||||
{0xAE, (uint8_t []){0x00}, 1, 0},
|
||||
{0xAF, (uint8_t []){0x00}, 1, 0},
|
||||
{0xB0, (uint8_t []){0x48}, 1, 0},
|
||||
{0xB1, (uint8_t []){0x00}, 1, 0},
|
||||
{0xB2, (uint8_t []){0x09}, 1, 0},
|
||||
{0xB3, (uint8_t []){0x02}, 1, 0},
|
||||
{0xB4, (uint8_t []){0xD9}, 1, 0},
|
||||
{0xB5, (uint8_t []){0x04}, 1, 0},
|
||||
{0xB6, (uint8_t []){0x00}, 1, 0},
|
||||
{0xB7, (uint8_t []){0x00}, 1, 0},
|
||||
{0xB8, (uint8_t []){0x48}, 1, 0},
|
||||
{0xB9, (uint8_t []){0x00}, 1, 0},
|
||||
{0xBA, (uint8_t []){0x0B}, 1, 0},
|
||||
{0xBB, (uint8_t []){0x02}, 1, 0},
|
||||
{0xBC, (uint8_t []){0xDB}, 1, 0},
|
||||
{0xBD, (uint8_t []){0x04}, 1, 0},
|
||||
{0xBE, (uint8_t []){0x00}, 1, 0},
|
||||
{0xBF, (uint8_t []){0x00}, 1, 0},
|
||||
{0xC0, (uint8_t []){0x10}, 1, 0},
|
||||
{0xC1, (uint8_t []){0x47}, 1, 0},
|
||||
{0xC2, (uint8_t []){0x56}, 1, 0},
|
||||
{0xC3, (uint8_t []){0x65}, 1, 0},
|
||||
{0xC4, (uint8_t []){0x74}, 1, 0},
|
||||
{0xC5, (uint8_t []){0x88}, 1, 0},
|
||||
{0xC6, (uint8_t []){0x99}, 1, 0},
|
||||
{0xC7, (uint8_t []){0x01}, 1, 0},
|
||||
{0xC8, (uint8_t []){0xBB}, 1, 0},
|
||||
{0xC9, (uint8_t []){0xAA}, 1, 0},
|
||||
{0xD0, (uint8_t []){0x10}, 1, 0},
|
||||
{0xD1, (uint8_t []){0x47}, 1, 0},
|
||||
{0xD2, (uint8_t []){0x56}, 1, 0},
|
||||
{0xD3, (uint8_t []){0x65}, 1, 0},
|
||||
{0xD4, (uint8_t []){0x74}, 1, 0},
|
||||
{0xD5, (uint8_t []){0x88}, 1, 0},
|
||||
{0xD6, (uint8_t []){0x99}, 1, 0},
|
||||
{0xD7, (uint8_t []){0x01}, 1, 0},
|
||||
{0xD8, (uint8_t []){0xBB}, 1, 0},
|
||||
{0xD9, (uint8_t []){0xAA}, 1, 0},
|
||||
{0xF3, (uint8_t []){0x01}, 1, 0},
|
||||
{0xF0, (uint8_t []){0x00}, 1, 0},
|
||||
{0x21, (uint8_t []){}, 0, 0},
|
||||
{0x11, (uint8_t []){}, 0, 0},
|
||||
{0x00, (uint8_t []){}, 0, 120},
|
||||
};
|
||||
|
||||
esp_err_t hw_lcd_init(esp_lcd_panel_handle_t *panel_handle, esp_lcd_panel_io_handle_t *io_handle, esp_lv_adapter_tear_avoid_mode_t tear_avoid_mode, esp_lv_adapter_rotation_t rotation)
|
||||
{
|
||||
ESP_LOGD(TAG, "Initialize QSPI bus");
|
||||
const spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = HW_LCD_PCLK,
|
||||
.data0_io_num = HW_LCD_DATA0,
|
||||
.data1_io_num = HW_LCD_DATA1,
|
||||
.data2_io_num = HW_LCD_DATA2,
|
||||
.data3_io_num = HW_LCD_DATA3,
|
||||
.max_transfer_sz = HW_LCD_MAX_TRANSFER_SZ,
|
||||
.flags = SPICOMMON_BUSFLAG_QUAD,
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
ESP_LOGD(TAG, "Install panel IO");
|
||||
esp_lcd_panel_io_spi_config_t io_config = {
|
||||
.dc_gpio_num = HW_LCD_DC,
|
||||
.cs_gpio_num = HW_LCD_CS,
|
||||
.pclk_hz = HW_LCD_PIXEL_CLOCK_HZ,
|
||||
.lcd_cmd_bits = HW_LCD_CMD_BITS,
|
||||
.lcd_param_bits = HW_LCD_PARAM_BITS,
|
||||
.spi_mode = 0,
|
||||
.trans_queue_depth = 1,
|
||||
.flags = {
|
||||
.quad_mode = 1,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)SPI2_HOST, &io_config, &s_panel_io_handle));
|
||||
|
||||
ESP_LOGD(TAG, "Power on LCD");
|
||||
gpio_config_t power_gpio_config = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = 1ULL << HW_LCD_POWER_OFF
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_config(&power_gpio_config));
|
||||
gpio_set_level(HW_LCD_POWER_OFF, 0);
|
||||
|
||||
ESP_LOGD(TAG, "Install LCD driver");
|
||||
const st77916_vendor_config_t vendor_config = {
|
||||
.init_cmds = st77916_qspi_init,
|
||||
.init_cmds_size = sizeof(st77916_qspi_init) / sizeof(st77916_lcd_init_cmd_t),
|
||||
.flags = {
|
||||
.use_qspi_interface = 1,
|
||||
},
|
||||
};
|
||||
esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = HW_LCD_RST,
|
||||
.rgb_ele_order = HW_LCD_COLOR_SPACE,
|
||||
.bits_per_pixel = HW_LCD_BITS_PER_PIXEL,
|
||||
.vendor_config = (void *) &vendor_config,
|
||||
.flags = {
|
||||
.reset_active_high = true,
|
||||
},
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "Install st77916 panel driver");
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_st77916(s_panel_io_handle, (const esp_lcd_panel_dev_config_t *)&panel_config, &s_panel_handle));
|
||||
|
||||
esp_lcd_panel_reset(s_panel_handle);
|
||||
esp_lcd_panel_init(s_panel_handle);
|
||||
|
||||
bool swap_xy = false;
|
||||
bool mirror_x = false;
|
||||
bool mirror_y = false;
|
||||
lcd_get_orientation_flags(HW_LCD_BASE_SWAP_XY, HW_LCD_BASE_MIRROR_X, HW_LCD_BASE_MIRROR_Y,
|
||||
rotation, &swap_xy, &mirror_x, &mirror_y);
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(s_panel_handle, swap_xy));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_mirror(s_panel_handle, mirror_x, mirror_y));
|
||||
esp_lcd_panel_disp_on_off(s_panel_handle, true);
|
||||
|
||||
*io_handle = s_panel_io_handle;
|
||||
*panel_handle = s_panel_handle;
|
||||
|
||||
gpio_config_t bk_gpio_config = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = 1ULL << HW_PIN_NUM_BK_LIGHT
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
|
||||
ESP_LOGI(TAG, "Turning on LCD backlight");
|
||||
gpio_set_level(HW_PIN_NUM_BK_LIGHT, HW_LCD_BK_LIGHT_ON_LEVEL);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "hw_init.h"
|
||||
|
||||
#if CONFIG_EXAMPLE_LCD_INTERFACE_RGB
|
||||
|
||||
#include "esp_lcd_panel_rgb.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
static const char *TAG = "hw_lcd_init";
|
||||
|
||||
#define HW_LCD_PIXEL_CLOCK_HZ (18 * 1000 * 1000)
|
||||
#define HW_LCD_HSYNC (40)
|
||||
#define HW_LCD_HBP (40)
|
||||
#define HW_LCD_HFP (48)
|
||||
#define HW_LCD_VSYNC (23)
|
||||
#define HW_LCD_VBP (32)
|
||||
#define HW_LCD_VFP (13)
|
||||
|
||||
#define HW_LCD_RGB_VSYNC (GPIO_NUM_3)
|
||||
#define HW_LCD_RGB_HSYNC (GPIO_NUM_46)
|
||||
#define HW_LCD_RGB_DE (GPIO_NUM_17)
|
||||
#define HW_LCD_RGB_PCLK (GPIO_NUM_9)
|
||||
#define HW_LCD_RGB_DISP (GPIO_NUM_NC)
|
||||
#define HW_LCD_RGB_DATA0 (GPIO_NUM_10)
|
||||
#define HW_LCD_RGB_DATA1 (GPIO_NUM_11)
|
||||
#define HW_LCD_RGB_DATA2 (GPIO_NUM_12)
|
||||
#define HW_LCD_RGB_DATA3 (GPIO_NUM_13)
|
||||
#define HW_LCD_RGB_DATA4 (GPIO_NUM_14)
|
||||
#define HW_LCD_RGB_DATA5 (GPIO_NUM_21)
|
||||
#define HW_LCD_RGB_DATA6 (GPIO_NUM_8)
|
||||
#define HW_LCD_RGB_DATA7 (GPIO_NUM_18)
|
||||
#define HW_LCD_RGB_DATA8 (GPIO_NUM_45)
|
||||
#define HW_LCD_RGB_DATA9 (GPIO_NUM_38)
|
||||
#define HW_LCD_RGB_DATA10 (GPIO_NUM_39)
|
||||
#define HW_LCD_RGB_DATA11 (GPIO_NUM_40)
|
||||
#define HW_LCD_RGB_DATA12 (GPIO_NUM_41)
|
||||
#define HW_LCD_RGB_DATA13 (GPIO_NUM_42)
|
||||
#define HW_LCD_RGB_DATA14 (GPIO_NUM_2)
|
||||
#define HW_LCD_RGB_DATA15 (GPIO_NUM_1)
|
||||
|
||||
#define HW_LCD_DATA_WIDTH (16)
|
||||
#define HW_LCD_BIT_PER_PIXEL (16)
|
||||
#define HW_LCD_BOUNCE_BUFFER_HEIGHT (20)
|
||||
|
||||
static esp_lcd_panel_handle_t s_panel_handle;
|
||||
|
||||
esp_err_t hw_lcd_init(esp_lcd_panel_handle_t *panel_handle, esp_lcd_panel_io_handle_t *io_handle, esp_lv_adapter_tear_avoid_mode_t tear_avoid_mode, esp_lv_adapter_rotation_t rotation)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initialize RGB panel");
|
||||
esp_lcd_rgb_panel_config_t panel_conf = {
|
||||
.clk_src = LCD_CLK_SRC_DEFAULT,
|
||||
.dma_burst_size = 64,
|
||||
.data_width = HW_LCD_DATA_WIDTH,
|
||||
.bits_per_pixel = HW_LCD_BIT_PER_PIXEL,
|
||||
.de_gpio_num = HW_LCD_RGB_DE,
|
||||
.pclk_gpio_num = HW_LCD_RGB_PCLK,
|
||||
.vsync_gpio_num = HW_LCD_RGB_VSYNC,
|
||||
.hsync_gpio_num = HW_LCD_RGB_HSYNC,
|
||||
.disp_gpio_num = HW_LCD_RGB_DISP,
|
||||
.data_gpio_nums = {
|
||||
HW_LCD_RGB_DATA0,
|
||||
HW_LCD_RGB_DATA1,
|
||||
HW_LCD_RGB_DATA2,
|
||||
HW_LCD_RGB_DATA3,
|
||||
HW_LCD_RGB_DATA4,
|
||||
HW_LCD_RGB_DATA5,
|
||||
HW_LCD_RGB_DATA6,
|
||||
HW_LCD_RGB_DATA7,
|
||||
HW_LCD_RGB_DATA8,
|
||||
HW_LCD_RGB_DATA9,
|
||||
HW_LCD_RGB_DATA10,
|
||||
HW_LCD_RGB_DATA11,
|
||||
HW_LCD_RGB_DATA12,
|
||||
HW_LCD_RGB_DATA13,
|
||||
HW_LCD_RGB_DATA14,
|
||||
HW_LCD_RGB_DATA15,
|
||||
},
|
||||
.timings = {
|
||||
.pclk_hz = HW_LCD_PIXEL_CLOCK_HZ,
|
||||
.h_res = HW_LCD_H_RES,
|
||||
.v_res = HW_LCD_V_RES,
|
||||
.hsync_back_porch = HW_LCD_HBP,
|
||||
.hsync_front_porch = HW_LCD_HFP,
|
||||
.hsync_pulse_width = HW_LCD_HSYNC,
|
||||
.vsync_back_porch = HW_LCD_VBP,
|
||||
.vsync_front_porch = HW_LCD_VFP,
|
||||
.vsync_pulse_width = HW_LCD_VSYNC,
|
||||
.flags = {
|
||||
.pclk_active_neg = true,
|
||||
},
|
||||
},
|
||||
.flags.fb_in_psram = 1,
|
||||
.num_fbs = esp_lv_adapter_get_required_frame_buffer_count(tear_avoid_mode, rotation),
|
||||
.bounce_buffer_size_px = HW_LCD_H_RES * HW_LCD_BOUNCE_BUFFER_HEIGHT,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_conf, &s_panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_reset(s_panel_handle));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_init(s_panel_handle));
|
||||
|
||||
*panel_handle = s_panel_handle;
|
||||
if (io_handle) {
|
||||
*io_handle = NULL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_lcd_ili9341.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "hw_init.h"
|
||||
#include "helpers/lcd_orientation_helper.h"
|
||||
|
||||
#if CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITH_PSRAM
|
||||
|
||||
static const char *TAG = "hw_lcd_init";
|
||||
|
||||
#define HW_PIN_NUM_BK_LIGHT (GPIO_NUM_47)
|
||||
#define HW_LCD_BK_LIGHT_ON_LEVEL (1)
|
||||
#define HW_LCD_BASE_SWAP_XY (false)
|
||||
#define HW_LCD_BASE_MIRROR_X (true)
|
||||
#define HW_LCD_BASE_MIRROR_Y (true)
|
||||
|
||||
#define HW_LCD_DATA0 (GPIO_NUM_6)
|
||||
#define HW_LCD_PCLK (GPIO_NUM_7)
|
||||
#define HW_LCD_CS (GPIO_NUM_5)
|
||||
#define HW_LCD_DC (GPIO_NUM_4)
|
||||
#define HW_LCD_RST (GPIO_NUM_48)
|
||||
|
||||
#define HW_LCD_PIXEL_CLOCK_HZ (40 * 1000 * 1000)
|
||||
#define HW_LCD_COLOR_SPACE (LCD_RGB_ELEMENT_ORDER_RGB)
|
||||
#define HW_LCD_BITS_PER_PIXEL (16)
|
||||
#define HW_LCD_CMD_BITS (8)
|
||||
#define HW_LCD_PARAM_BITS (8)
|
||||
#define HW_LCD_MAX_TRANSFER_SZ (HW_LCD_H_RES * HW_LCD_V_RES * 2)
|
||||
|
||||
static esp_lcd_panel_io_handle_t s_panel_io_handle;
|
||||
static esp_lcd_panel_handle_t s_panel_handle;
|
||||
|
||||
static const ili9341_lcd_init_cmd_t vendor_specific_init_default[] = {
|
||||
{0xC8, (uint8_t []){0xFF, 0x93, 0x42}, 3, 0},
|
||||
{0xC0, (uint8_t []){0x0E, 0x0E}, 2, 0},
|
||||
{0xC5, (uint8_t []){0xD0}, 1, 0},
|
||||
{0xC1, (uint8_t []){0x02}, 1, 0},
|
||||
{0xB4, (uint8_t []){0x02}, 1, 0},
|
||||
{0xE0, (uint8_t []){0x00, 0x03, 0x08, 0x06, 0x13, 0x09, 0x39, 0x39, 0x48, 0x02, 0x0a, 0x08, 0x17, 0x17, 0x0F}, 15, 0},
|
||||
{0xE1, (uint8_t []){0x00, 0x28, 0x29, 0x01, 0x0d, 0x03, 0x3f, 0x33, 0x52, 0x04, 0x0f, 0x0e, 0x37, 0x38, 0x0F}, 15, 0},
|
||||
{0xB1, (uint8_t []){00, 0x1B}, 2, 0},
|
||||
{0x36, (uint8_t []){0x08}, 1, 0},
|
||||
{0x3A, (uint8_t []){0x55}, 1, 0},
|
||||
{0xB7, (uint8_t []){0x06}, 1, 0},
|
||||
{0x11, (uint8_t []){0}, 0x80, 0},
|
||||
{0x29, (uint8_t []){0}, 0x80, 0},
|
||||
{0, (uint8_t []){0}, 0xff, 0},
|
||||
};
|
||||
|
||||
esp_err_t hw_lcd_init(esp_lcd_panel_handle_t *panel_handle, esp_lcd_panel_io_handle_t *io_handle, esp_lv_adapter_tear_avoid_mode_t tear_avoid_mode, esp_lv_adapter_rotation_t rotation)
|
||||
{
|
||||
ESP_LOGD(TAG, "Initialize SPI bus");
|
||||
const spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = HW_LCD_PCLK,
|
||||
.mosi_io_num = HW_LCD_DATA0,
|
||||
.miso_io_num = GPIO_NUM_NC,
|
||||
.quadwp_io_num = GPIO_NUM_NC,
|
||||
.quadhd_io_num = GPIO_NUM_NC,
|
||||
.max_transfer_sz = HW_LCD_MAX_TRANSFER_SZ,
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
ESP_LOGD(TAG, "Install panel IO");
|
||||
esp_lcd_panel_io_spi_config_t io_config = {
|
||||
.dc_gpio_num = HW_LCD_DC,
|
||||
.cs_gpio_num = HW_LCD_CS,
|
||||
.pclk_hz = HW_LCD_PIXEL_CLOCK_HZ,
|
||||
.lcd_cmd_bits = HW_LCD_CMD_BITS,
|
||||
.lcd_param_bits = HW_LCD_PARAM_BITS,
|
||||
.spi_mode = 0,
|
||||
.trans_queue_depth = 1,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)SPI2_HOST, &io_config, &s_panel_io_handle));
|
||||
|
||||
ESP_LOGD(TAG, "Install LCD driver");
|
||||
const ili9341_vendor_config_t vendor_config = {
|
||||
.init_cmds = vendor_specific_init_default,
|
||||
.init_cmds_size = sizeof(vendor_specific_init_default) / sizeof(vendor_specific_init_default[0]),
|
||||
};
|
||||
esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = HW_LCD_RST,
|
||||
.flags.reset_active_high = true,
|
||||
.rgb_ele_order = HW_LCD_COLOR_SPACE,
|
||||
.bits_per_pixel = HW_LCD_BITS_PER_PIXEL,
|
||||
.vendor_config = (void *) &vendor_config,
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "Install ili9341 panel driver");
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9341(s_panel_io_handle, (const esp_lcd_panel_dev_config_t *)&panel_config, &s_panel_handle));
|
||||
|
||||
esp_lcd_panel_reset(s_panel_handle);
|
||||
esp_lcd_panel_init(s_panel_handle);
|
||||
|
||||
bool swap_xy = false;
|
||||
bool mirror_x = true;
|
||||
bool mirror_y = true;
|
||||
lcd_get_orientation_flags(HW_LCD_BASE_SWAP_XY, HW_LCD_BASE_MIRROR_X, HW_LCD_BASE_MIRROR_Y,
|
||||
rotation, &swap_xy, &mirror_x, &mirror_y);
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(s_panel_handle, swap_xy));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_mirror(s_panel_handle, mirror_x, mirror_y));
|
||||
esp_lcd_panel_disp_on_off(s_panel_handle, true);
|
||||
|
||||
*io_handle = s_panel_io_handle;
|
||||
*panel_handle = s_panel_handle;
|
||||
|
||||
gpio_config_t bk_gpio_config = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = 1ULL << HW_PIN_NUM_BK_LIGHT
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
|
||||
ESP_LOGI(TAG, "Turning on LCD backlight");
|
||||
gpio_set_level(HW_PIN_NUM_BK_LIGHT, HW_LCD_BK_LIGHT_ON_LEVEL);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_lcd_gc9a01.h"
|
||||
#include "hw_init.h"
|
||||
#include "helpers/lcd_orientation_helper.h"
|
||||
|
||||
#if CONFIG_EXAMPLE_LCD_INTERFACE_SPI_WITHOUT_PSRAM
|
||||
|
||||
static const char *TAG = "hw_lcd_init";
|
||||
|
||||
#define HW_LCD_BASE_SWAP_XY (false)
|
||||
#define HW_LCD_BASE_MIRROR_X (true)
|
||||
#define HW_LCD_BASE_MIRROR_Y (false)
|
||||
|
||||
#define HW_LCD_DATA0 (GPIO_NUM_0)
|
||||
#define HW_LCD_PCLK (GPIO_NUM_1)
|
||||
#define HW_LCD_CS (GPIO_NUM_7)
|
||||
#define HW_LCD_DC (GPIO_NUM_2)
|
||||
#define HW_LCD_RST (GPIO_NUM_NC)
|
||||
|
||||
#define HW_LCD_PIXEL_CLOCK_HZ (80 * 1000 * 1000)
|
||||
#define HW_LCD_COLOR_SPACE (LCD_RGB_ELEMENT_ORDER_BGR)
|
||||
#define HW_LCD_BITS_PER_PIXEL (16)
|
||||
#define HW_LCD_CMD_BITS (8)
|
||||
#define HW_LCD_PARAM_BITS (8)
|
||||
#define HW_LCD_MAX_TRANSFER_SZ (HW_LCD_H_RES * 80 * 2)
|
||||
|
||||
static esp_lcd_panel_io_handle_t s_panel_io_handle;
|
||||
static esp_lcd_panel_handle_t s_panel_handle;
|
||||
|
||||
esp_err_t hw_lcd_init(esp_lcd_panel_handle_t *panel_handle, esp_lcd_panel_io_handle_t *io_handle, esp_lv_adapter_tear_avoid_mode_t tear_avoid_mode, esp_lv_adapter_rotation_t rotation)
|
||||
{
|
||||
ESP_LOGD(TAG, "Initialize SPI bus");
|
||||
const spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = HW_LCD_PCLK,
|
||||
.mosi_io_num = HW_LCD_DATA0,
|
||||
.miso_io_num = GPIO_NUM_NC,
|
||||
.quadwp_io_num = GPIO_NUM_NC,
|
||||
.quadhd_io_num = GPIO_NUM_NC,
|
||||
.max_transfer_sz = HW_LCD_MAX_TRANSFER_SZ,
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
ESP_LOGD(TAG, "Install panel IO");
|
||||
esp_lcd_panel_io_spi_config_t io_config = {
|
||||
.dc_gpio_num = HW_LCD_DC,
|
||||
.cs_gpio_num = HW_LCD_CS,
|
||||
.pclk_hz = HW_LCD_PIXEL_CLOCK_HZ,
|
||||
.lcd_cmd_bits = HW_LCD_CMD_BITS,
|
||||
.lcd_param_bits = HW_LCD_PARAM_BITS,
|
||||
.spi_mode = 0,
|
||||
.trans_queue_depth = 10,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)SPI2_HOST, &io_config, &s_panel_io_handle));
|
||||
|
||||
ESP_LOGD(TAG, "Install LCD driver");
|
||||
esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = HW_LCD_RST,
|
||||
.rgb_ele_order = HW_LCD_COLOR_SPACE,
|
||||
.bits_per_pixel = HW_LCD_BITS_PER_PIXEL,
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "Install gc9a01 panel driver");
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_gc9a01(s_panel_io_handle, &panel_config, &s_panel_handle));
|
||||
|
||||
esp_lcd_panel_reset(s_panel_handle);
|
||||
esp_lcd_panel_init(s_panel_handle);
|
||||
|
||||
bool swap_xy = false;
|
||||
bool mirror_x = true;
|
||||
bool mirror_y = false;
|
||||
lcd_get_orientation_flags(HW_LCD_BASE_SWAP_XY, HW_LCD_BASE_MIRROR_X, HW_LCD_BASE_MIRROR_Y,
|
||||
rotation, &swap_xy, &mirror_x, &mirror_y);
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(s_panel_handle, swap_xy));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_mirror(s_panel_handle, mirror_x, mirror_y));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_invert_color(s_panel_handle, true));
|
||||
esp_lcd_panel_disp_on_off(s_panel_handle, true);
|
||||
|
||||
*io_handle = s_panel_io_handle;
|
||||
*panel_handle = s_panel_handle;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user