I’m using a ESP32-S3 with a ST7701 display.
Its my first time working with these devices so bare with me
I’m currenly modifying the demo file that came with the device so there’s alot of code here that I didn’t write nor understand.
The flush cb:
void flushDisplay(lv_display_t *disp, const lv_area_t *area, uint8_t *color_p) {
LCD_addWindow(area->x1, area->y1, area->x2, area->y2, color_p);
lv_display_flush_ready(disp);
}
Display_ST7701.h
#pragma once
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_rgb.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "freertos/task.h"
#include "TCA9554PWR.h"
#include "LVGL_Driver.h"
#include "Touch_CST820.h"
#define LCD_CLK_PIN 2
#define LCD_MOSI_PIN 1
#define LCD_Backlight_PIN 6
// Backlight
#define PWM_Channel 1 // PWM Channel
#define Frequency 20000 // PWM frequencyconst
#define Resolution 10 // PWM resolution ratio MAX:13
#define Dutyfactor 500 // PWM Dutyfactor
#define ESP_PANEL_LCD_WIDTH (480)
#define ESP_PANEL_LCD_HEIGHT (480)
#define ESP_PANEL_LCD_COLOR_BITS (16)
#define ESP_PANEL_LCD_RGB_PIXEL_BITS (16) // 24 | 16
#define ESP_PANEL_LCD_RGB_DATA_WIDTH (16)
#define ESP_PANEL_LCD_RGB_TIMING_FREQ_HZ (16 * 1000 * 1000)
#define ESP_PANEL_LCD_RGB_TIMING_HPW (8)
#define ESP_PANEL_LCD_RGB_TIMING_HBP (10)
#define ESP_PANEL_LCD_RGB_TIMING_HFP (50)
#define ESP_PANEL_LCD_RGB_TIMING_VPW (3)
#define ESP_PANEL_LCD_RGB_TIMING_VBP (8)
#define ESP_PANEL_LCD_RGB_TIMING_VFP (8)
#define ESP_PANEL_LCD_RGB_FRAME_BUF_NUM (2) // 1/2/3
#define ESP_PANEL_LCD_RGB_BOUNCE_BUF_SIZE (ESP_PANEL_LCD_WIDTH * 10) // Bounce buffer size in bytes. This function is used to avoid screen drift.
// To enable the bounce buffer, set it to a non-zero value. Typically set to `ESP_PANEL_LCD_WIDTH * 10`
// The size of the Bounce Buffer must satisfy `width_of_lcd * height_of_lcd = size_of_buffer * N`,
// where N is an even number.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// Please update the following configuration according to your board spec ////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define ESP_PANEL_LCD_PIN_NUM_RGB_HSYNC (38)
#define ESP_PANEL_LCD_PIN_NUM_RGB_VSYNC (39)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DE (40)
#define ESP_PANEL_LCD_PIN_NUM_RGB_PCLK (41)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA0 (5)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA1 (45)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA2 (48)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA3 (47)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA4 (21)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA5 (14)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA6 (13)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA7 (12)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA8 (11)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA9 (10)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA10 (9)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA11 (46)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA12 (3)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA13 (8)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA14 (18)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DATA15 (17)
#define ESP_PANEL_LCD_PIN_NUM_RGB_DISP (-1)
#define ESP_PANEL_LCD_BK_LIGHT_ON_LEVEL (1)
#define ESP_PANEL_LCD_BK_LIGHT_OFF_LEVEL !ESP_PANEL_LCD_BK_LIGHT_ON_LEVEL
#define EXAMPLE_ENABLE_PRINT_LCD_FPS (1)
extern esp_lcd_panel_handle_t panel_handle;
bool example_on_vsync_event(esp_lcd_panel_handle_t panel, const esp_lcd_rgb_panel_event_data_t *event_data, void *user_data);
void ST7701_Init();
void LCD_Init();
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint8_t* color);
#define MIN_BRIGHTNESS 10
#define MAX_BRIGHTNESS 100
#define BREATH_STEP 1
extern int backlight;
void initBacklight();
void setBrightness(uint8_t Light);
void breathingEffect();
void initBrightnessAnimations();
Display_ST7701.cpp
#include "Display_ST7701.h"
spi_device_handle_t SPI_handle = NULL;
esp_lcd_panel_handle_t panel_handle = NULL;
void ST7701_WriteCommand(uint8_t cmd)
{
spi_transaction_t spi_tran = {
.cmd = 0,
.addr = cmd,
.length = 0,
.rxlength = 0,
};
spi_device_transmit(SPI_handle, &spi_tran);
}
void ST7701_WriteData(uint8_t data)
{
spi_transaction_t spi_tran = {
.cmd = 1,
.addr = data,
.length = 0,
.rxlength = 0,
};
spi_device_transmit(SPI_handle, &spi_tran);
}
void ST7701_CS_EN(){
Set_EXIO(EXIO_PIN3,Low);
vTaskDelay(pdMS_TO_TICKS(10));
}
void ST7701_CS_Dis(){
Set_EXIO(EXIO_PIN3,High);
vTaskDelay(pdMS_TO_TICKS(10));
}
void ST7701_Reset(){
Set_EXIO(EXIO_PIN1,Low);
vTaskDelay(pdMS_TO_TICKS(10));
Set_EXIO(EXIO_PIN1,High);
vTaskDelay(pdMS_TO_TICKS(50));
}
void ST7701_Init()
{
spi_bus_config_t buscfg = {
.mosi_io_num = LCD_MOSI_PIN,
.miso_io_num = -1,
.sclk_io_num = LCD_CLK_PIN,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 64, // ESP32 S3 max size is 64Kbytes
};
spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
spi_device_interface_config_t devcfg = {
.command_bits = 1,
.address_bits = 8,
.mode = SPI_MODE0,
.clock_speed_hz = 40000000,
.spics_io_num = -1,
.queue_size = 1, // Not using queues
};
spi_bus_add_device(SPI2_HOST, &devcfg, &SPI_handle);
ST7701_CS_EN();
ST7701_WriteCommand(0xFF);
ST7701_WriteData(0x77);
ST7701_WriteData(0x01);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x10);
ST7701_WriteCommand(0xC0);
ST7701_WriteData(0x3B);//Scan line
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xC1);
ST7701_WriteData(0x0B); //VBP
ST7701_WriteData(0x02);
ST7701_WriteCommand(0xC2);
ST7701_WriteData(0x07);
ST7701_WriteData(0x02);
ST7701_WriteCommand(0xCC);
ST7701_WriteData(0x10);
ST7701_WriteCommand(0xCD);//RGB format
ST7701_WriteData(0x08);
ST7701_WriteCommand(0xB0); // IPS
ST7701_WriteData(0x00); // 255
ST7701_WriteData(0x11); // 251
ST7701_WriteData(0x16); // 247 down
ST7701_WriteData(0x0e); // 239
ST7701_WriteData(0x11); // 231
ST7701_WriteData(0x06); // 203
ST7701_WriteData(0x05); // 175
ST7701_WriteData(0x09); // 147
ST7701_WriteData(0x08); // 108
ST7701_WriteData(0x21); // 80
ST7701_WriteData(0x06); // 52
ST7701_WriteData(0x13); // 24
ST7701_WriteData(0x10); // 16
ST7701_WriteData(0x29); // 8 down
ST7701_WriteData(0x31); // 4
ST7701_WriteData(0x18); // 0
ST7701_WriteCommand(0xB1);// IPS
ST7701_WriteData(0x00);// 255
ST7701_WriteData(0x11);// 251
ST7701_WriteData(0x16);// 247 down
ST7701_WriteData(0x0e);// 239
ST7701_WriteData(0x11);// 231
ST7701_WriteData(0x07);// 203
ST7701_WriteData(0x05);// 175
ST7701_WriteData(0x09);// 147
ST7701_WriteData(0x09);// 108
ST7701_WriteData(0x21);// 80
ST7701_WriteData(0x05);// 52
ST7701_WriteData(0x13);// 24
ST7701_WriteData(0x11);// 16
ST7701_WriteData(0x2a);// 8 down
ST7701_WriteData(0x31);// 4
ST7701_WriteData(0x18);// 0
ST7701_WriteCommand(0xFF);
ST7701_WriteData(0x77);
ST7701_WriteData(0x01);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x11);
ST7701_WriteCommand(0xB0); //VOP 3.5375+ *x 0.0125
ST7701_WriteData(0x6d); //5D
ST7701_WriteCommand(0xB1); //VCOM amplitude setting
ST7701_WriteData(0x37); //
ST7701_WriteCommand(0xB2); //VGH Voltage setting
ST7701_WriteData(0x81); //12V
ST7701_WriteCommand(0xB3);
ST7701_WriteData(0x80);
ST7701_WriteCommand(0xB5); //VGL Voltage setting
ST7701_WriteData(0x43); //-8.3V
ST7701_WriteCommand(0xB7);
ST7701_WriteData(0x85);
ST7701_WriteCommand(0xB8);
ST7701_WriteData(0x20);
ST7701_WriteCommand(0xC1);
ST7701_WriteData(0x78);
ST7701_WriteCommand(0xC2);
ST7701_WriteData(0x78);
ST7701_WriteCommand(0xD0);
ST7701_WriteData(0x88);
ST7701_WriteCommand(0xE0);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x02);
ST7701_WriteCommand(0xE1);
ST7701_WriteData(0x03);
ST7701_WriteData(0xA0);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x04);
ST7701_WriteData(0xA0);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x20);
ST7701_WriteData(0x20);
ST7701_WriteCommand(0xE2);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xE3);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x11);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xE4);
ST7701_WriteData(0x22);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xE5);
ST7701_WriteData(0x05);
ST7701_WriteData(0xEC);
ST7701_WriteData(0xA0);
ST7701_WriteData(0xA0);
ST7701_WriteData(0x07);
ST7701_WriteData(0xEE);
ST7701_WriteData(0xA0);
ST7701_WriteData(0xA0);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xE6);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x11);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xE7);
ST7701_WriteData(0x22);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xE8);
ST7701_WriteData(0x06);
ST7701_WriteData(0xED);
ST7701_WriteData(0xA0);
ST7701_WriteData(0xA0);
ST7701_WriteData(0x08);
ST7701_WriteData(0xEF);
ST7701_WriteData(0xA0);
ST7701_WriteData(0xA0);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xEB);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x40);
ST7701_WriteData(0x40);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0xED);
ST7701_WriteData(0xFF);
ST7701_WriteData(0xFF);
ST7701_WriteData(0xFF);
ST7701_WriteData(0xBA);
ST7701_WriteData(0x0A);
ST7701_WriteData(0xBF);
ST7701_WriteData(0x45);
ST7701_WriteData(0xFF);
ST7701_WriteData(0xFF);
ST7701_WriteData(0x54);
ST7701_WriteData(0xFB);
ST7701_WriteData(0xA0);
ST7701_WriteData(0xAB);
ST7701_WriteData(0xFF);
ST7701_WriteData(0xFF);
ST7701_WriteData(0xFF);
ST7701_WriteCommand(0xEF);
ST7701_WriteData(0x10);
ST7701_WriteData(0x0D);
ST7701_WriteData(0x04);
ST7701_WriteData(0x08);
ST7701_WriteData(0x3F);
ST7701_WriteData(0x1F);
ST7701_WriteCommand(0xFF);
ST7701_WriteData(0x77);
ST7701_WriteData(0x01);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x13);
ST7701_WriteCommand(0xEF);
ST7701_WriteData(0x08);
ST7701_WriteCommand(0xFF);
ST7701_WriteData(0x77);
ST7701_WriteData(0x01);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0x36);
ST7701_WriteData(0x00);
ST7701_WriteCommand(0x3A);
ST7701_WriteData(0x66);
ST7701_WriteCommand(0x11);
vTaskDelay(pdMS_TO_TICKS(480));
ST7701_WriteCommand(0x20);
vTaskDelay(pdMS_TO_TICKS(120));
ST7701_WriteCommand(0x29);
ST7701_CS_Dis();
// RGB
esp_lcd_rgb_panel_config_t rgb_config = {
.clk_src = LCD_CLK_SRC_DEFAULT,
.timings = {
.pclk_hz = ESP_PANEL_LCD_RGB_TIMING_FREQ_HZ,
.h_res = ESP_PANEL_LCD_HEIGHT,
.v_res = ESP_PANEL_LCD_WIDTH,
.hsync_pulse_width = ESP_PANEL_LCD_RGB_TIMING_HPW,
.hsync_back_porch = ESP_PANEL_LCD_RGB_TIMING_HBP,
.hsync_front_porch = ESP_PANEL_LCD_RGB_TIMING_HFP,
.vsync_pulse_width = ESP_PANEL_LCD_RGB_TIMING_VPW,
.vsync_back_porch = ESP_PANEL_LCD_RGB_TIMING_VBP,
.vsync_front_porch = ESP_PANEL_LCD_RGB_TIMING_VFP,
.flags = {
.hsync_idle_low = 0, /*!< The hsync signal is low in IDLE state */
.vsync_idle_low = 0, /*!< The vsync signal is low in IDLE state */
.de_idle_high = 0, /*!< The de signal is high in IDLE state */
.pclk_active_neg = false,
.pclk_idle_high = 0, /*!< The PCLK stays at high level in IDLE phase */
},
},
.data_width = ESP_PANEL_LCD_RGB_DATA_WIDTH,
.bits_per_pixel = ESP_PANEL_LCD_RGB_PIXEL_BITS,
.num_fbs = ESP_PANEL_LCD_RGB_FRAME_BUF_NUM,
.bounce_buffer_size_px = 10 * ESP_PANEL_LCD_HEIGHT,
.psram_trans_align = 64,
.hsync_gpio_num = ESP_PANEL_LCD_PIN_NUM_RGB_HSYNC,
.vsync_gpio_num = ESP_PANEL_LCD_PIN_NUM_RGB_VSYNC,
.de_gpio_num = ESP_PANEL_LCD_PIN_NUM_RGB_DE,
.pclk_gpio_num = ESP_PANEL_LCD_PIN_NUM_RGB_PCLK,
.disp_gpio_num = ESP_PANEL_LCD_PIN_NUM_RGB_DISP,
.data_gpio_nums = {
ESP_PANEL_LCD_PIN_NUM_RGB_DATA0,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA1,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA2,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA3,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA4,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA5,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA6,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA7,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA8,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA9,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA10,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA11,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA12,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA13,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA14,
ESP_PANEL_LCD_PIN_NUM_RGB_DATA15,
},
.flags = {
.disp_active_low = 0,
.refresh_on_demand = 0,
.fb_in_psram = true,
.double_fb = true,
.no_fb = 0,
.bb_invalidate_cache = 0,
},
};
esp_lcd_new_rgb_panel(&rgb_config, &panel_handle);
esp_lcd_panel_reset(panel_handle);
esp_lcd_panel_init(panel_handle);
}
void LCD_Init() {
ST7701_Reset();
ST7701_Init();
Touch_Init();
}
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint8_t* color) {
Xend = Xend + 1; // esp_lcd_panel_draw_bitmap: x_end End index on x-axis (x_end not included)
Yend = Yend + 1; // esp_lcd_panel_draw_bitmap: y_end End index on y-axis (y_end not included)
if (Xend >= ESP_PANEL_LCD_WIDTH)
Xend = ESP_PANEL_LCD_WIDTH;
if (Yend >= ESP_PANEL_LCD_HEIGHT)
Yend = ESP_PANEL_LCD_HEIGHT;
esp_lcd_panel_draw_bitmap(panel_handle, Xstart, Ystart, Xend, Yend, color); // x_end End index on x-axis (x_end not included)
}
void initBacklight() {
ledcAttach(LCD_Backlight_PIN, Frequency, Resolution);
ledcWrite(LCD_Backlight_PIN, Dutyfactor);
}
void setBrightness(uint8_t brightness) {
if(brightness > 100 || brightness < 0)
printf("Brightness must be between 0 to 100\n");
else{
uint32_t backlight = brightness*10;
ledcWrite(LCD_Backlight_PIN, backlight);
}
}