386 lines
15 KiB
C
386 lines
15 KiB
C
|
|
|
|||
|
|
#include "esp_lcd_st7305.h"
|
|||
|
|
#include "soc/soc_caps.h"
|
|||
|
|
#include "esp_check.h"
|
|||
|
|
#include "esp_lcd_types.h"
|
|||
|
|
#include <stdlib.h>
|
|||
|
|
#include <sys/cdefs.h>
|
|||
|
|
#include "freertos/FreeRTOS.h"
|
|||
|
|
#include "freertos/task.h"
|
|||
|
|
#include "esp_lcd_panel_interface.h"
|
|||
|
|
#include "esp_lcd_panel_io.h"
|
|||
|
|
#include "esp_lcd_panel_vendor.h"
|
|||
|
|
#include "esp_lcd_panel_ops.h"
|
|||
|
|
#include "esp_lcd_panel_commands.h"
|
|||
|
|
#include "driver/gpio.h"
|
|||
|
|
#include "esp_log.h"
|
|||
|
|
#include "esp_check.h"
|
|||
|
|
// 定义面板操作函数
|
|||
|
|
|
|||
|
|
static esp_err_t panel_st7305_del(esp_lcd_panel_t *panel);
|
|||
|
|
static esp_err_t panel_st7305_reset(esp_lcd_panel_t *panel);
|
|||
|
|
static esp_err_t panel_st7305_init(esp_lcd_panel_t *panel);
|
|||
|
|
static esp_err_t panel_st7305_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data);
|
|||
|
|
static esp_err_t panel_st7305_invert_color(esp_lcd_panel_t *panel, bool invert_color_data);
|
|||
|
|
static esp_err_t panel_st7305_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool mirror_y);
|
|||
|
|
static esp_err_t panel_st7305_swap_xy(esp_lcd_panel_t *panel, bool swap_axes);
|
|||
|
|
static esp_err_t panel_st7305_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap);
|
|||
|
|
static esp_err_t panel_st7305_disp_on_off(esp_lcd_panel_t *panel, bool off);
|
|||
|
|
static inline void _swap_int(int *a, int *b) {
|
|||
|
|
int temp = *a;
|
|||
|
|
*a = *b;
|
|||
|
|
*b = temp;
|
|||
|
|
}
|
|||
|
|
const char *TAG = "st7305";
|
|||
|
|
|
|||
|
|
typedef struct {
|
|||
|
|
esp_lcd_panel_t base;
|
|||
|
|
esp_lcd_panel_io_handle_t io;
|
|||
|
|
int reset_gpio_num;
|
|||
|
|
bool reset_level;
|
|||
|
|
int x_gap;
|
|||
|
|
int y_gap;
|
|||
|
|
int width;
|
|||
|
|
int height;
|
|||
|
|
uint8_t rotation; // 当前旋转角度 (0, 1, 2, 3 对应 0°, 90°, 180°, 270°)
|
|||
|
|
|
|||
|
|
uint8_t fb_bits_per_pixel;
|
|||
|
|
uint8_t madctl_val; // save current value of LCD_CMD_MADCTL register
|
|||
|
|
uint8_t colmod_val; // save current value of LCD_CMD_COLMOD register
|
|||
|
|
const st7305_lcd_init_cmd_t *init_cmds;
|
|||
|
|
uint16_t init_cmds_size;
|
|||
|
|
} st7305_panel_t;
|
|||
|
|
|
|||
|
|
static const st7305_lcd_init_cmd_t st7305_init_cmds[] = {
|
|||
|
|
{0xD6, (uint8_t[]){0x17, 0x02}, 2, 0}, // NVM Load Control
|
|||
|
|
{0xD1, (uint8_t[]){0x01}, 1, 0}, // Booster Enable
|
|||
|
|
|
|||
|
|
{0xC0, (uint8_t[]){0x12, 0x0a}, 2, 0}, // Gate Voltage Setting
|
|||
|
|
{0xC1, (uint8_t[]){0x73, 0x3E, 0x3C, 0x3C}, 4, 0}, // VSHP Setting (4.8V)
|
|||
|
|
{0xC2, (uint8_t[]){0x00, 0x21, 0x23, 0x23}, 4, 0}, // VSLP Setting (0.98V)
|
|||
|
|
{0xC4, (uint8_t[]){0x32, 0x5C, 0x5A, 0x5A}, 4, 0}, // VSHN Setting (-3.6V)
|
|||
|
|
{0xC5, (uint8_t[]){0x32, 0x35, 0x37, 0x37}, 4, 0}, // VSLN Setting (0.22V)
|
|||
|
|
|
|||
|
|
{0xD8, (uint8_t[]){0x80, 0xE9}, 2, 0}, // OSC Setting: Enable OSC, HPM Frame Rate Max = 51Hz
|
|||
|
|
{0xB2, (uint8_t[]){0x12}, 1, 0}, // Frame Rate Control (HPM=51hz)
|
|||
|
|
|
|||
|
|
{0xB3, (uint8_t[]){0xE5, 0xF6, 0x17, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x71}, 10, 0}, // Update Period Gate EQ Control in HPM
|
|||
|
|
{0xB4, (uint8_t[]){0x05, 0x46, 0x77, 0x77, 0x77, 0x77, 0x76, 0x45}, 8, 0}, // Update Period Gate EQ Control in LPM
|
|||
|
|
|
|||
|
|
{0x62, (uint8_t[]){0x32, 0x03, 0x1F}, 3, 0}, // Gate Timing Control
|
|||
|
|
{0xB7, (uint8_t[]){0x13}, 1, 0}, // Source EQ Enable
|
|||
|
|
{0xB0, (uint8_t[]){0x32}, 1, 0}, // Gate Line Setting: 200 line (50 * 4)
|
|||
|
|
|
|||
|
|
{0x11, NULL, 0, 120}, // Sleep out (delay 120ms)
|
|||
|
|
|
|||
|
|
{0xC9, (uint8_t[]){0x00}, 1, 0}, // Source Voltage Select
|
|||
|
|
{0x36, (uint8_t[]){0x48}, 1, 0}, // Memory Data Access Control (MX=1; DO=1)
|
|||
|
|
{0x3A, (uint8_t[]){0x11}, 1, 0}, // Data Format Select
|
|||
|
|
{0xB9, (uint8_t[]){0x20}, 1, 0}, // Gamma Mode Setting
|
|||
|
|
{0xB8, (uint8_t[]){0x29}, 1, 0}, // Panel Setting
|
|||
|
|
|
|||
|
|
{0x2A, (uint8_t[]){0x16, 0x26}, 2, 0}, // Column Address Setting (0x16,0x26)
|
|||
|
|
{0x2B, (uint8_t[]){0x00, 0x63}, 2, 0}, // Row Address Setting (0x00,0x63)
|
|||
|
|
{0x35, (uint8_t[]){0x00}, 1, 0}, // TE
|
|||
|
|
|
|||
|
|
{0xD0, (uint8_t[]){0xFF}, 1, 0}, // Auto power down ON
|
|||
|
|
{0x38, NULL, 0, 0}, // HPM: High Power Mode ON
|
|||
|
|
|
|||
|
|
{0x29, NULL, 0, 0}, // Display ON
|
|||
|
|
{0x20, NULL, 0, 0}, // Display Inversion Off
|
|||
|
|
|
|||
|
|
{0xBB, (uint8_t[]){0x4F}, 1, 0}, // Enable Clear RAM, clear RAM to 0
|
|||
|
|
};
|
|||
|
|
esp_err_t esp_lcd_new_panel_st7305(const esp_lcd_panel_io_handle_t io, const esp_lcd_panel_dev_config_t *panel_dev_config,
|
|||
|
|
esp_lcd_panel_handle_t *ret_panel)
|
|||
|
|
{
|
|||
|
|
esp_err_t ret = ESP_OK;
|
|||
|
|
st7305_panel_t *st7305 = NULL;
|
|||
|
|
gpio_config_t io_conf = { 0 };
|
|||
|
|
|
|||
|
|
ESP_GOTO_ON_FALSE(io && panel_dev_config && ret_panel, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
|||
|
|
st7305 = (st7305_panel_t *)calloc(1, sizeof(st7305_panel_t));
|
|||
|
|
ESP_GOTO_ON_FALSE(st7305, ESP_ERR_NO_MEM, err, TAG, "no mem for st7305 panel");
|
|||
|
|
|
|||
|
|
if (panel_dev_config->reset_gpio_num >= 0) {
|
|||
|
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
|||
|
|
io_conf.pin_bit_mask = 1ULL << panel_dev_config->reset_gpio_num;
|
|||
|
|
ESP_GOTO_ON_ERROR(gpio_config(&io_conf), err, TAG, "configure GPIO for RST line failed");
|
|||
|
|
}
|
|||
|
|
st7305->width = ST7305_WIDTH;
|
|||
|
|
st7305->height = ST7305_HEIGHT;
|
|||
|
|
st7305->madctl_val = 0; // 初始化MADCTL值
|
|||
|
|
st7305->rotation = 0; // 初始化MADCTL值
|
|||
|
|
|
|||
|
|
st7305->io = io;
|
|||
|
|
st7305->reset_gpio_num = panel_dev_config->reset_gpio_num;
|
|||
|
|
st7305->reset_level = panel_dev_config->flags.reset_active_high;
|
|||
|
|
if (panel_dev_config->vendor_config) {
|
|||
|
|
st7305->init_cmds = ((st7305_vendor_config_t *)panel_dev_config->vendor_config)->init_cmds;
|
|||
|
|
st7305->init_cmds_size = ((st7305_vendor_config_t *)panel_dev_config->vendor_config)->init_cmds_size;
|
|||
|
|
}
|
|||
|
|
st7305->base.del = panel_st7305_del;
|
|||
|
|
st7305->base.reset = panel_st7305_reset;
|
|||
|
|
st7305->base.init = panel_st7305_init;
|
|||
|
|
st7305->base.draw_bitmap = panel_st7305_draw_bitmap;
|
|||
|
|
st7305->base.invert_color = panel_st7305_invert_color;
|
|||
|
|
st7305->base.set_gap = panel_st7305_set_gap;
|
|||
|
|
st7305->base.mirror = panel_st7305_mirror;
|
|||
|
|
st7305->base.swap_xy = panel_st7305_swap_xy;
|
|||
|
|
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
|||
|
|
st7305->base.disp_off = panel_st7305_disp_on_off;
|
|||
|
|
#else
|
|||
|
|
st7305->base.disp_on_off = panel_st7305_disp_on_off;
|
|||
|
|
#endif
|
|||
|
|
*ret_panel = &(st7305->base);
|
|||
|
|
ESP_LOGD(TAG, "new st7305 panel @%p", st7305);
|
|||
|
|
|
|||
|
|
// ESP_LOGI(TAG, "LCD panel create success, version: %d.%d.%d", ESP_LCD_ILI9341_VER_MAJOR, ESP_LCD_ILI9341_VER_MINOR,
|
|||
|
|
// ESP_LCD_ILI9341_VER_PATCH);
|
|||
|
|
|
|||
|
|
return ESP_OK;
|
|||
|
|
|
|||
|
|
err:
|
|||
|
|
if (st7305) {
|
|||
|
|
if (panel_dev_config->reset_gpio_num >= 0) {
|
|||
|
|
gpio_reset_pin(panel_dev_config->reset_gpio_num);
|
|||
|
|
}
|
|||
|
|
free(st7305);
|
|||
|
|
}
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
// Panel删除函数
|
|||
|
|
static esp_err_t panel_st7305_del(esp_lcd_panel_t *panel)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
|
|||
|
|
if (st7305->reset_gpio_num >= 0) {
|
|||
|
|
gpio_reset_pin(st7305->reset_gpio_num);
|
|||
|
|
}
|
|||
|
|
free(st7305);
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Panel复位函数
|
|||
|
|
static esp_err_t panel_st7305_reset(esp_lcd_panel_t *panel)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
|
|||
|
|
// 执行硬件复位
|
|||
|
|
if (st7305->reset_gpio_num >= 0) {
|
|||
|
|
gpio_set_level(st7305->reset_gpio_num, st7305->reset_level);
|
|||
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|||
|
|
gpio_set_level(st7305->reset_gpio_num, !st7305->reset_level);
|
|||
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Panel初始化函数
|
|||
|
|
static esp_err_t panel_st7305_init(esp_lcd_panel_t *panel)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
esp_lcd_panel_io_handle_t io = st7305->io;
|
|||
|
|
|
|||
|
|
// 发送初始化命令序列
|
|||
|
|
for (size_t i = 0; i < sizeof(st7305_init_cmds) / sizeof(st7305_lcd_init_cmd_t); i++) {
|
|||
|
|
if (st7305_init_cmds[i].data_bytes > 0) {
|
|||
|
|
esp_lcd_panel_io_tx_param(io, st7305_init_cmds[i].cmd,
|
|||
|
|
st7305_init_cmds[i].data,
|
|||
|
|
st7305_init_cmds[i].data_bytes);
|
|||
|
|
} else {
|
|||
|
|
esp_lcd_panel_io_tx_param(io, st7305_init_cmds[i].cmd, NULL, 0);
|
|||
|
|
}
|
|||
|
|
if (st7305_init_cmds[i].delay_ms > 0) {
|
|||
|
|
vTaskDelay(pdMS_TO_TICKS(st7305_init_cmds[i].delay_ms));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static esp_err_t panel_st7305_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
esp_lcd_panel_io_handle_t io = st7305->io;
|
|||
|
|
|
|||
|
|
// 创建主缓冲区和临时缓冲区(大小基于面板分辨率)
|
|||
|
|
uint16_t pages = (st7305->height) / 8;
|
|||
|
|
size_t lcd_buf_size = (size_t)st7305->width * pages;
|
|||
|
|
uint8_t *lcd_buffer = heap_caps_malloc(lcd_buf_size, MALLOC_CAP_DMA);
|
|||
|
|
uint8_t *temp_buffer = heap_caps_malloc(lcd_buf_size, MALLOC_CAP_DMA);
|
|||
|
|
if (!lcd_buffer || !temp_buffer) {
|
|||
|
|
if (lcd_buffer) free(lcd_buffer);
|
|||
|
|
if (temp_buffer) free(temp_buffer);
|
|||
|
|
return ESP_ERR_NO_MEM;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 直接复制输入数据到主缓冲区
|
|||
|
|
// memcpy(lcd_buffer, color_data, 384 * 21);
|
|||
|
|
// // memset(lcd_buffer, 0, 384 * 21);
|
|||
|
|
|
|||
|
|
// // 数据格式转换
|
|||
|
|
// uint16_t k = 0;
|
|||
|
|
// for (uint16_t i = 0; i < ST7305_WIDTH; i += 2) {
|
|||
|
|
// for (uint16_t j = 0; j < 21; j += 3) {
|
|||
|
|
// for (uint8_t y = 0; y < 3; y++) {
|
|||
|
|
// if ((j + y) < 21) {
|
|||
|
|
// uint8_t b1 = lcd_buffer[(j + y) * ST7305_WIDTH + i];
|
|||
|
|
// uint8_t b2 = lcd_buffer[(j + y) * ST7305_WIDTH + i + 1];
|
|||
|
|
|
|||
|
|
// // 第一组4位
|
|||
|
|
// uint8_t mix = ((b1 & 0x01) << 7) | ((b2 & 0x01) << 6) |
|
|||
|
|
// ((b1 & 0x02) << 4) | ((b2 & 0x02) << 3) |
|
|||
|
|
// ((b1 & 0x04) << 1) | ((b2 & 0x04)) |
|
|||
|
|
// ((b1 & 0x08) >> 2) | ((b2 & 0x08) >> 3);
|
|||
|
|
// temp_buffer[k++] = mix;
|
|||
|
|
|
|||
|
|
// // 第二组4位
|
|||
|
|
// b1 >>= 4;
|
|||
|
|
// b2 >>= 4;
|
|||
|
|
// mix = ((b1 & 0x01) << 7) | ((b2 & 0x01) << 6) |
|
|||
|
|
// ((b1 & 0x02) << 4) | ((b2 & 0x02) << 3) |
|
|||
|
|
// ((b1 & 0x04) << 1) | ((b2 & 0x04)) |
|
|||
|
|
// ((b1 & 0x08) >> 2) | ((b2 & 0x08) >> 3);
|
|||
|
|
// temp_buffer[k++] = mix;
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
memset(lcd_buffer, 0, lcd_buf_size);
|
|||
|
|
|
|||
|
|
// 判断是否需要交换XY
|
|||
|
|
bool is_xy_swapped = (st7305->madctl_val & ST7305_MADCTL_MV);
|
|||
|
|
|
|||
|
|
// 复制并转换数据到lcd_buffer
|
|||
|
|
const uint8_t *src = (const uint8_t *)color_data;
|
|||
|
|
if (!is_xy_swapped) {
|
|||
|
|
// 正常模式
|
|||
|
|
memcpy(lcd_buffer, src, lcd_buf_size);
|
|||
|
|
} else {
|
|||
|
|
// XY交换模式 - 需要重新排列数据
|
|||
|
|
for (int y = 0; y < st7305->height; y++) {
|
|||
|
|
for (int x = 0; x < st7305->width; x++) {
|
|||
|
|
// 计算源数据中的位置
|
|||
|
|
uint16_t src_byte_idx = (y >> 3) * st7305->width + x;
|
|||
|
|
uint8_t src_bit_pos = y & 0x07;
|
|||
|
|
bool pixel = src[src_byte_idx] & (1 << src_bit_pos);
|
|||
|
|
|
|||
|
|
// 计算目标位置(交换x和y)
|
|||
|
|
uint16_t dst_byte_idx = (x >> 3) * st7305->height + y;
|
|||
|
|
uint8_t dst_bit_pos = x & 0x07;
|
|||
|
|
|
|||
|
|
if (pixel) {
|
|||
|
|
lcd_buffer[dst_byte_idx] |= (1 << dst_bit_pos);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 数据格式转换
|
|||
|
|
uint16_t k = 0;
|
|||
|
|
uint16_t width = is_xy_swapped ? st7305->height : st7305->width;
|
|||
|
|
uint16_t stride = is_xy_swapped ? st7305->height : st7305->width;
|
|||
|
|
uint16_t pages_loop = is_xy_swapped ? (st7305->width) / 8 : pages;
|
|||
|
|
|
|||
|
|
for (uint16_t i = 0; i < width; i += 2) {
|
|||
|
|
for (uint16_t j = 0; j < pages_loop; j += 3) {
|
|||
|
|
for (uint8_t y = 0; y < 3; y++) {
|
|||
|
|
if ((j + y) < pages_loop) {
|
|||
|
|
uint8_t b1 = lcd_buffer[(j + y) * stride + i];
|
|||
|
|
uint8_t b2 = lcd_buffer[(j + y) * stride + i + 1];
|
|||
|
|
|
|||
|
|
// 第一组4位
|
|||
|
|
uint8_t mix = ((b1 & 0x01) << 7) | ((b2 & 0x01) << 6) |
|
|||
|
|
((b1 & 0x02) << 4) | ((b2 & 0x02) << 3) |
|
|||
|
|
((b1 & 0x04) << 1) | ((b2 & 0x04)) |
|
|||
|
|
((b1 & 0x08) >> 2) | ((b2 & 0x08) >> 3);
|
|||
|
|
temp_buffer[k++] = mix;
|
|||
|
|
|
|||
|
|
// 第二组4位
|
|||
|
|
b1 >>= 4;
|
|||
|
|
b2 >>= 4;
|
|||
|
|
mix = ((b1 & 0x01) << 7) | ((b2 & 0x01) << 6) |
|
|||
|
|
((b1 & 0x02) << 4) | ((b2 & 0x02) << 3) |
|
|||
|
|
((b1 & 0x04) << 1) | ((b2 & 0x04)) |
|
|||
|
|
((b1 & 0x08) >> 2) | ((b2 & 0x08) >> 3);
|
|||
|
|
temp_buffer[k++] = mix;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 设置显示范围和发送数据
|
|||
|
|
uint8_t caset[] = {0x16, 0x26};
|
|||
|
|
uint8_t raset[] = {0x00, 0x63};
|
|||
|
|
|
|||
|
|
esp_lcd_panel_io_tx_param(io, ST7305_CMD_CASET, caset, sizeof(caset));
|
|||
|
|
esp_lcd_panel_io_tx_param(io, ST7305_CMD_RASET, raset, sizeof(raset));
|
|||
|
|
esp_lcd_panel_io_tx_color(io, ST7305_CMD_RAMWR, temp_buffer, lcd_buf_size);
|
|||
|
|
|
|||
|
|
free(lcd_buffer);
|
|||
|
|
free(temp_buffer);
|
|||
|
|
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
// 颜色反转函数
|
|||
|
|
static esp_err_t panel_st7305_invert_color(esp_lcd_panel_t *panel, bool invert_color_data)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
esp_lcd_panel_io_tx_param(st7305->io, invert_color_data ? 0x21 : 0x20, NULL, 0);
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 镜像函数
|
|||
|
|
// 旋转接口实现
|
|||
|
|
static esp_err_t panel_st7305_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool mirror_y)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
esp_lcd_panel_io_handle_t io = st7305->io;
|
|||
|
|
if (mirror_x) {
|
|||
|
|
st7305->madctl_val |= ST7305_MADCTL_MY;
|
|||
|
|
} else {
|
|||
|
|
st7305->madctl_val &= ~ST7305_MADCTL_MY;
|
|||
|
|
}
|
|||
|
|
if (mirror_y) {
|
|||
|
|
st7305->madctl_val |= ST7305_MADCTL_MX;
|
|||
|
|
} else {
|
|||
|
|
st7305->madctl_val &= ~ST7305_MADCTL_MX;
|
|||
|
|
}
|
|||
|
|
ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, LCD_CMD_MADCTL, (uint8_t[]) {
|
|||
|
|
st7305->madctl_val
|
|||
|
|
}, 1), TAG, "send command failed");
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static esp_err_t panel_st7305_swap_xy(esp_lcd_panel_t *panel, bool swap_axes)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
esp_lcd_panel_io_handle_t io = st7305->io;
|
|||
|
|
if (swap_axes) {
|
|||
|
|
st7305->madctl_val |= ST7305_MADCTL_MV;
|
|||
|
|
} else {
|
|||
|
|
st7305->madctl_val &= ~ST7305_MADCTL_MV;
|
|||
|
|
}
|
|||
|
|
ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, LCD_CMD_MADCTL, (uint8_t[]) {
|
|||
|
|
st7305->madctl_val
|
|||
|
|
}, 1), TAG, "send command failed");
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置偏移函数
|
|||
|
|
static esp_err_t panel_st7305_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
st7305->x_gap = x_gap;
|
|||
|
|
st7305->y_gap = y_gap;
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
// 添加显示开关函数
|
|||
|
|
static esp_err_t panel_st7305_disp_on_off(esp_lcd_panel_t *panel, bool on)
|
|||
|
|
{
|
|||
|
|
st7305_panel_t *st7305 = __containerof(panel, st7305_panel_t, base);
|
|||
|
|
esp_lcd_panel_io_tx_param(st7305->io, on ? ST7305_CMD_DISPON : ST7305_CMD_DISPOFF, NULL, 0);
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|