/* * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ #include "waveshare_rgb_lcd_port.h" static const char *TAG = "example"; // VSYNC event callback function IRAM_ATTR static bool rgb_lcd_on_vsync_event(esp_lcd_panel_handle_t panel, const esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx) { return lvgl_port_notify_rgb_vsync(); } #if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 /** * @brief I2C master initialization */ static esp_err_t i2c_master_init(void) { int i2c_master_port = I2C_MASTER_NUM; i2c_config_t i2c_conf = { .mode = I2C_MODE_MASTER, .sda_io_num = I2C_MASTER_SDA_IO, .scl_io_num = I2C_MASTER_SCL_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = I2C_MASTER_FREQ_HZ, }; // Configure I2C parameters i2c_param_config(i2c_master_port, &i2c_conf); // Install I2C driver return i2c_driver_install(i2c_master_port, i2c_conf.mode, 0, 0, 0); } // GPIO initialization void gpio_init(void) { // Zero-initialize the config structure gpio_config_t io_conf = {}; // Disable interrupt io_conf.intr_type = GPIO_INTR_DISABLE; // Bit mask of the pins, use GPIO4 here io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL; // Set as input mode io_conf.mode = GPIO_MODE_OUTPUT; gpio_config(&io_conf); } // Reset the touch screen void waveshare_esp32_s3_touch_reset() { uint8_t write_buf = 0x01; i2c_master_write_to_device(I2C_MASTER_NUM, 0x24, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); // Reset the touch screen. It is recommended to reset the touch screen before using it. write_buf = 0x2C; i2c_master_write_to_device(I2C_MASTER_NUM, 0x38, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); esp_rom_delay_us(100 * 1000); gpio_set_level(GPIO_INPUT_IO_4, 0); esp_rom_delay_us(100 * 1000); write_buf = 0x2E; i2c_master_write_to_device(I2C_MASTER_NUM, 0x38, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); esp_rom_delay_us(200 * 1000); } #endif // Initialize RGB LCD esp_err_t waveshare_esp32_s3_rgb_lcd_init() { ESP_LOGI(TAG, "Install RGB LCD panel driver"); // Log the start of the RGB LCD panel driver installation esp_lcd_panel_handle_t panel_handle = NULL; // Declare a handle for the LCD panel esp_lcd_rgb_panel_config_t panel_config = { .clk_src = LCD_CLK_SRC_DEFAULT, // Set the clock source for the panel .timings = { .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ, // Pixel clock frequency .h_res = EXAMPLE_LCD_H_RES, // Horizontal resolution .v_res = EXAMPLE_LCD_V_RES, // Vertical resolution .hsync_pulse_width = 4, // Horizontal sync pulse width .hsync_back_porch = 8, // Horizontal back porch .hsync_front_porch = 8, // Horizontal front porch .vsync_pulse_width = 4, // Vertical sync pulse width .vsync_back_porch = 8, // Vertical back porch .vsync_front_porch = 8, // Vertical front porch .flags = { .pclk_active_neg = 1, // Active low pixel clock }, }, .data_width = EXAMPLE_RGB_DATA_WIDTH, // Data width for RGB .bits_per_pixel = EXAMPLE_RGB_BIT_PER_PIXEL, // Bits per pixel .num_fbs = LVGL_PORT_LCD_RGB_BUFFER_NUMS, // Number of frame buffers .bounce_buffer_size_px = EXAMPLE_RGB_BOUNCE_BUFFER_SIZE, // Bounce buffer size in pixels .sram_trans_align = 4, // SRAM transaction alignment .psram_trans_align = 64, // PSRAM transaction alignment .hsync_gpio_num = EXAMPLE_LCD_IO_RGB_HSYNC, // GPIO number for horizontal sync .vsync_gpio_num = EXAMPLE_LCD_IO_RGB_VSYNC, // GPIO number for vertical sync .de_gpio_num = EXAMPLE_LCD_IO_RGB_DE, // GPIO number for data enable .pclk_gpio_num = EXAMPLE_LCD_IO_RGB_PCLK, // GPIO number for pixel clock .disp_gpio_num = EXAMPLE_LCD_IO_RGB_DISP, // GPIO number for display .data_gpio_nums = { EXAMPLE_LCD_IO_RGB_DATA0, EXAMPLE_LCD_IO_RGB_DATA1, EXAMPLE_LCD_IO_RGB_DATA2, EXAMPLE_LCD_IO_RGB_DATA3, EXAMPLE_LCD_IO_RGB_DATA4, EXAMPLE_LCD_IO_RGB_DATA5, EXAMPLE_LCD_IO_RGB_DATA6, EXAMPLE_LCD_IO_RGB_DATA7, EXAMPLE_LCD_IO_RGB_DATA8, EXAMPLE_LCD_IO_RGB_DATA9, EXAMPLE_LCD_IO_RGB_DATA10, EXAMPLE_LCD_IO_RGB_DATA11, EXAMPLE_LCD_IO_RGB_DATA12, EXAMPLE_LCD_IO_RGB_DATA13, EXAMPLE_LCD_IO_RGB_DATA14, EXAMPLE_LCD_IO_RGB_DATA15, }, .flags = { .fb_in_psram = 1, // Use PSRAM for framebuffer }, }; // Create a new RGB panel with the specified configuration ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle)); ESP_LOGI(TAG, "Initialize RGB LCD panel"); // Log the initialization of the RGB LCD panel ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); // Initialize the LCD panel esp_lcd_touch_handle_t tp_handle = NULL; // Declare a handle for the touch panel #if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 ESP_LOGI(TAG, "Initialize I2C bus"); // Log the initialization of the I2C bus i2c_master_init(); // Initialize the I2C master ESP_LOGI(TAG, "Initialize GPIO"); // Log GPIO initialization gpio_init(); // Initialize GPIO pins ESP_LOGI(TAG, "Initialize Touch LCD"); // Log touch LCD initialization waveshare_esp32_s3_touch_reset(); // Reset the touch panel esp_lcd_panel_io_handle_t tp_io_handle = NULL; // Declare a handle for touch panel I/O const esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG(); // Configure I2C for GT911 touch controller ESP_LOGI(TAG, "Initialize I2C panel IO"); // Log I2C panel I/O initialization ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_MASTER_NUM, &tp_io_config, &tp_io_handle)); // Create new I2C panel I/O ESP_LOGI(TAG, "Initialize touch controller GT911"); // Log touch controller initialization const esp_lcd_touch_config_t tp_cfg = { .x_max = EXAMPLE_LCD_H_RES, // Set maximum X coordinate .y_max = EXAMPLE_LCD_V_RES, // Set maximum Y coordinate .rst_gpio_num = EXAMPLE_PIN_NUM_TOUCH_RST, // GPIO number for reset .int_gpio_num = EXAMPLE_PIN_NUM_TOUCH_INT, // GPIO number for interrupt .levels = { .reset = 0, // Reset level .interrupt = 0, // Interrupt level }, .flags = { .swap_xy = 0, // No swap of X and Y .mirror_x = 0, // No mirroring of X .mirror_y = 0, // No mirroring of Y }, }; ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp_handle)); // Create new I2C GT911 touch controller #endif // CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 ESP_ERROR_CHECK(lvgl_port_init(panel_handle, tp_handle)); // Initialize LVGL with the panel and touch handles // Register callbacks for RGB panel events esp_lcd_rgb_panel_event_callbacks_t cbs = { #if EXAMPLE_RGB_BOUNCE_BUFFER_SIZE > 0 .on_bounce_frame_finish = rgb_lcd_on_vsync_event, // Callback for bounce frame finish #else .on_vsync = rgb_lcd_on_vsync_event, // Callback for vertical sync #endif }; ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(panel_handle, &cbs, NULL)); // Register event callbacks return ESP_OK; // Return success } /******************************* Turn on the screen backlight **************************************/ esp_err_t wavesahre_rgb_lcd_bl_on() { //Configure CH422G to output mode uint8_t write_buf = 0x01; i2c_master_write_to_device(I2C_MASTER_NUM, 0x24, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); //Pull the backlight pin high to light the screen backlight write_buf = 0x1E; i2c_master_write_to_device(I2C_MASTER_NUM, 0x38, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); return ESP_OK; } /******************************* Turn off the screen backlight **************************************/ esp_err_t wavesahre_rgb_lcd_bl_off() { //Configure CH422G to output mode uint8_t write_buf = 0x01; i2c_master_write_to_device(I2C_MASTER_NUM, 0x24, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); //Turn off the screen backlight by pulling the backlight pin low write_buf = 0x1A; i2c_master_write_to_device(I2C_MASTER_NUM, 0x38, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); return ESP_OK; }