Skip to content

Commit

Permalink
Merge pull request espressif#185 from Lzw655/feature/add_esp_lcd_gc9503
Browse files Browse the repository at this point in the history
lcd: add gc9503 lcd driver
  • Loading branch information
tore-espressif authored Jun 29, 2023
2 parents 7d9b522 + 43d5781 commit fa9dd75
Show file tree
Hide file tree
Showing 11 changed files with 501 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/upload_component.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
esp32_azure_iot_kit;esp32_s2_kaluga_kit;esp_wrover_kit;esp-box;esp32_s3_usb_otg;esp32_s3_eye;esp32_s3_lcd_ev_board;esp32_s3_korvo_2;esp-box-lite;esp32_lyrat;
components/bh1750;components/ds18b20;components/es8311;components/es7210;components/fbm320;components/hts221;components/mag3110;components/mpu6050;components/ssd1306;components/esp_lvgl_port;
components/lcd_touch/esp_lcd_touch;components/lcd_touch/esp_lcd_touch_ft5x06;components/lcd_touch/esp_lcd_touch_gt911;components/lcd_touch/esp_lcd_touch_tt21100;components/lcd_touch/esp_lcd_touch_gt1151;components/lcd_touch/esp_lcd_touch_cst816s;
components/lcd/esp_lcd_gc9a01;components/lcd/esp_lcd_ili9341;components/lcd/esp_lcd_ra8875;components/lcd_touch/esp_lcd_touch_stmpe610;components/lcd/esp_lcd_sh1107;components/lcd/esp_lcd_st7796;
components/lcd/esp_lcd_gc9a01;components/lcd/esp_lcd_ili9341;components/lcd/esp_lcd_ra8875;components/lcd_touch/esp_lcd_touch_stmpe610;components/lcd/esp_lcd_sh1107;components/lcd/esp_lcd_st7796;components/lcd/esp_lcd_gc9503;
components/io_expander/esp_io_expander;components/io_expander/esp_io_expander_tca9554;components/io_expander/esp_io_expander_tca95xx_16bit;components/io_expander/esp_io_expander_ht8574;
namespace: "espressif"
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
2 changes: 2 additions & 0 deletions LCD.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ The list of available LCD displays and links to LCD driver component and touch d
| <img src="docu/pics/ssd1306.jpg" width="150"> | 128x32 0,91" OLED | SSD1306 | [IDF](https://github.com/espressif/esp-idf/tree/master/components/esp_lcd) | - | - | |
| <img src="docu/pics/ssd1963.jpg" width="150"> | Parallel | SSD1963 | **N/A** | - | - | |
| <img src="docu/pics/st7796.jpg" width="150"> | Parallel/SPI | ST7796 | [Component Manager](https://components.espressif.com/component/espressif/esp_lcd_st7796) | - | - | |
| <img src="docu/pics/esp32-s3-lcd-ev-board_480x480.png" width="150"> | [ESP32-S3-LCD-EV-Board](https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32s3/esp32-s3-lcd-ev-board/user_guide.html) | GC9503 | [Component Manager](https://components.espressif.com/component/espressif/esp_lcd_gc9503) | FT5X06 | [Component Manager](https://components.espressif.com/component/espressif/esp_lcd_touch_ft5x06) | |
| <img src="docu/pics/esp32-s3-lcd-ev-board_800x480.png" width="150"> | [ESP32-S3-LCD-EV-Board-2](https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32s3/esp32-s3-lcd-ev-board/user_guide.html) | ST7262E43 | **N/A** | GT1151 | [Component Manager](https://components.espressif.com/component/espressif/esp_lcd_touch_gt1151) | |
9 changes: 9 additions & 0 deletions components/lcd/esp_lcd_gc9503/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
idf_component_register(
SRCS
"esp_lcd_gc9503.c"
INCLUDE_DIRS
"include"
PRIV_REQUIRES
"driver"
REQUIRES
"esp_lcd")
81 changes: 81 additions & 0 deletions components/lcd/esp_lcd_gc9503/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# ESP LCD GC9503

[![Component Registry](https://components.espressif.com/components/espressif/esp_lcd_gc9503/badge.svg)](https://components.espressif.com/components/espressif/esp_lcd_gc9503)

Implementation of the GC9503 LCD controller with esp_lcd component.

| LCD controller | Communication interface | Component name | Link to datasheet |
| :------------: | :---------------------: | :------------: | :--------------------------------------------------------: |
| GC9503 | 3-wire SPI + RGB | esp_lcd_gc9503 | [WIKI](https://github.com/espressif/esp-dev-kits/blob/master/docs/_static/esp32-s3-lcd-ev-board/datasheets/3.95_480x480_SmartDisplay/GC9503NP_DataSheet_V1.7.pdf) |

## Add to project

Packages from this repository are uploaded to [Espressif's component service](https://components.espressif.com/).
You can add them to your project via `idf.py add-dependancy`, e.g.

```
idf.py add-dependency esp_lcd_gc9503==1.0.0
```

Alternatively, you can create `idf_component.yml`. More is in [Espressif's documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html).

## Example use

Create 3-wire SPI panel IO using [esp_lcd_panel_io_additions](https://components.espressif.com/components/espressif/esp_lcd_panel_io_additions) component.

```
spi_line_config_t line_config = {
.cs_io_type = IO_TYPE_EXPANDER,
.cs_expander_pin = BSP_LCD_SPI_CS,
.scl_io_type = IO_TYPE_EXPANDER,
.scl_expander_pin = BSP_LCD_SPI_SCK,
.sda_io_type = IO_TYPE_EXPANDER,
.sda_expander_pin = BSP_LCD_SPI_SDO,
.io_expander = expander_handle,
};
esp_lcd_panel_io_3wire_spi_config_t io_config = GC9503_PANEL_IO_3WIRE_SPI_CONFIG(line_config);
esp_lcd_panel_io_handle_t io_handle = NULL;
ESP_ERROR_CHECK(esp_lcd_new_panel_io_3wire_spi(&io_config, &io_handle));
```

Initialize GC9503 and create RGB panel.

```
esp_lcd_rgb_panel_config_t panel_conf = {
.clk_src = LCD_CLK_SRC_PLL160M,
.psram_trans_align = 64,
.data_width = 16,
.de_gpio_num = BSP_LCD_DE,
.pclk_gpio_num = BSP_LCD_PCLK,
.vsync_gpio_num = BSP_LCD_VSYNC,
.hsync_gpio_num = BSP_LCD_HSYNC,
.data_gpio_nums = {
BSP_LCD_DATA0,
BSP_LCD_DATA1,
BSP_LCD_DATA2,
BSP_LCD_DATA3,
BSP_LCD_DATA4,
BSP_LCD_DATA5,
BSP_LCD_DATA6,
BSP_LCD_DATA7,
BSP_LCD_DATA8,
BSP_LCD_DATA9,
BSP_LCD_DATA10,
BSP_LCD_DATA11,
BSP_LCD_DATA12,
BSP_LCD_DATA13,
BSP_LCD_DATA14,
BSP_LCD_DATA15,
},
.timings = GC9503_480_480_PANEL_60HZ_RGB_TIMING(),
.flags.fb_in_psram = 1,
};
esp_lcd_panel_handle_t panel_handle = NULL;
ESP_ERROR_CHECK(esp_lcd_new_panel_gc9503(io_handle, &panel_conf, &panel_handle));
```

Delete panel IO if it is no longer needed.

```
ESP_ERROR_CHECK(esp_lcd_panel_io_del(io_handle));
```
118 changes: 118 additions & 0 deletions components/lcd/esp_lcd_gc9503/esp_lcd_gc9503.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_check.h"
#include "esp_lcd_panel_commands.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_rgb.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_log.h"

static const char *TAG = "gc9503";

/**
* @brief LCD configuration data structure type
*
*/
typedef struct {
uint8_t cmd; // LCD command
uint8_t data[52]; // LCD data
uint8_t data_bytes; // Length of data in above data array; 0xFF = end of cmds.
} lcd_init_cmd_t;

// *INDENT-OFF*
const static lcd_init_cmd_t vendor_specific_init[] = {
{0xf0, {0x55, 0xaa, 0x52, 0x08, 0x00}, 5},
{0xf6, {0x5a, 0x87}, 2},
{0xc1, {0x3f}, 1},
{0xc2, {0x0e}, 1},
{0xc6, {0xf8}, 1},
{0xc9, {0x10}, 1},
{0xcd, {0x25}, 1},
{0xf8, {0x8a}, 1},
{0xac, {0x45}, 1},
{0xa0, {0xdd}, 1},
{0xa7, {0x47}, 1},
{0xfa, {0x00, 0x00, 0x00, 0x04}, 4},
{0x86, {0x99, 0xa3, 0xa3, 0x51}, 4},
{0xa3, {0xee}, 1},
{0xfd, {0x3c, 0x3c, 0x00}, 3},
{0x71, {0x48}, 1},
{0x72, {0x48}, 1},
{0x73, {0x00, 0x44}, 2},
{0x97, {0xee}, 1},
{0x83, {0x93}, 1},
{0x9a, {0x72}, 1},
{0x9b, {0x5a}, 1},
{0x82, {0x2c, 0x2c}, 2},
{0xb1, {0x10}, 1},
{0x6d, {0x00, 0x1f, 0x19, 0x1a, 0x10, 0x0e, 0x0c, 0x0a, 0x02, 0x07, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x08, 0x01, 0x09, 0x0b, 0x0d, 0x0f, 0x1a, 0x19, 0x1f, 0x00}, 32},
{0x64, {0x38, 0x05, 0x01, 0xdb, 0x03, 0x03, 0x38, 0x04, 0x01, 0xdc, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a}, 16},
{0x65, {0x38, 0x03, 0x01, 0xdd, 0x03, 0x03, 0x38, 0x02, 0x01, 0xde, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a}, 16},
{0x66, {0x38, 0x01, 0x01, 0xdf, 0x03, 0x03, 0x38, 0x00, 0x01, 0xe0, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a}, 16},
{0x67, {0x30, 0x01, 0x01, 0xe1, 0x03, 0x03, 0x30, 0x02, 0x01, 0xe2, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a}, 16},
{0x68, {0x00, 0x08, 0x15, 0x08, 0x15, 0x7a, 0x7a, 0x08, 0x15, 0x08, 0x15, 0x7a, 0x7a}, 13},
{0x60, {0x38, 0x08, 0x7a, 0x7a, 0x38, 0x09, 0x7a, 0x7a}, 8},
{0x63, {0x31, 0xe4, 0x7a, 0x7a, 0x31, 0xe5, 0x7a, 0x7a}, 8},
{0x69, {0x04, 0x22, 0x14, 0x22, 0x14, 0x22, 0x08}, 7},
{0x6b, {0x07}, 1},
{0x7a, {0x08, 0x13}, 2},
{0x7b, {0x08, 0x13}, 2},
{0xd1, {0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18, 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47, 0x00,
0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68, 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6, 0x02, 0xee,
0x03, 0x48, 0x03, 0xa0, 0x03, 0xba, 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea, 0x03, 0xfa, 0x03,
0xff}, 52},
{0xd2, {0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18, 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47, 0x00,
0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68, 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6, 0x02, 0xee,
0x03, 0x48, 0x03, 0xa0, 0x03, 0xba, 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea, 0x03, 0xfa, 0x03,
0xff}, 52},
{0xd3, {0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18, 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47, 0x00,
0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68, 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6, 0x02, 0xee,
0x03, 0x48, 0x03, 0xa0, 0x03, 0xba, 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea, 0x03, 0xfa, 0x03,
0xff}, 52},
{0xd4, {0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18, 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47, 0x00,
0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68, 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6, 0x02, 0xee,
0x03, 0x48, 0x03, 0xa0, 0x03, 0xba, 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea, 0x03, 0xfa, 0x03,
0xff}, 52},
{0xd5, {0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18, 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47, 0x00,
0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68, 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6, 0x02, 0xee,
0x03, 0x48, 0x03, 0xa0, 0x03, 0xba, 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea, 0x03, 0xfa, 0x03,
0xff}, 52},
{0xd6, {0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18, 0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47, 0x00,
0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68, 0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6, 0x02, 0xee,
0x03, 0x48, 0x03, 0xa0, 0x03, 0xba, 0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea, 0x03, 0xfa, 0x03,
0xff}, 52},
{0x3a, {0x66}, 1},
{0x11, {0x00}, 0},
{0x00, {0x00}, 0xff},
};
// *INDENT-OFF*

esp_err_t esp_lcd_new_panel_gc9503(esp_lcd_panel_io_handle_t io_handle, const esp_lcd_rgb_panel_config_t *rgb_config, esp_lcd_panel_handle_t *ret_panel)
{
ESP_RETURN_ON_FALSE(io_handle && rgb_config && ret_panel, ESP_ERR_INVALID_ARG, TAG, "Invalid arguments");

// Initialize LCD
// Vendor specific initialization, it can be different between manufacturers
// Should consult the LCD supplier for initialization sequence code
int cmd = 0;
while (vendor_specific_init[cmd].data_bytes != 0xff) {
esp_lcd_panel_io_tx_param(io_handle, vendor_specific_init[cmd].cmd, vendor_specific_init[cmd].data, vendor_specific_init[cmd].data_bytes);
cmd++;
}
vTaskDelay(pdMS_TO_TICKS(120));
esp_lcd_panel_io_tx_param(io_handle, LCD_CMD_DISPON, NULL, 0);
vTaskDelay(pdMS_TO_TICKS(20));

// Create RGB panel
ESP_RETURN_ON_ERROR(esp_lcd_new_rgb_panel(rgb_config, ret_panel), TAG, "Failed to create RGB panel");

return ESP_OK;
}
7 changes: 7 additions & 0 deletions components/lcd/esp_lcd_gc9503/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: "1.0.0"
targets:
- esp32s3
description: ESP LCD GC9503
url: https://github.com/espressif/esp-bsp/tree/master/components/lcd/esp_lcd_gc9503
dependencies:
idf: ">=4.4"
77 changes: 77 additions & 0 deletions components/lcd/esp_lcd_gc9503/include/esp_lcd_gc9503.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ESP LCD: GC9503
*/

#pragma once

#include "esp_lcd_types.h"
#include "esp_lcd_panel_rgb.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Create LCD panel for GC9503.
*
* @note This function first initialize GC9503 with vendor specific initialization, then calls `esp_lcd_new_rgb_panel()` to create a RGB LCD panel.
* @note Vendor specific initialization can be different between manufacturers, should consult the LCD supplier for initialization sequence code.
*
* @param[in] io_handle LCD panel IO handle
* @param[in] rgb_config Pointer to RGB panel timing configuration structure
* @param[out] ret_panel Returned LCD panel handle
* @return
* - ESP_OK: Success, otherwise returns ESP_ERR_xxx
*/
esp_err_t esp_lcd_new_panel_gc9503(esp_lcd_panel_io_handle_t io_handle, const esp_lcd_rgb_panel_config_t *rgb_config, esp_lcd_panel_handle_t *ret_panel);

/**
* @brief 3-wire SPI panel IO configuration structure
*
*/
#define GC9503_PANEL_IO_3WIRE_SPI_CONFIG(line_cfg) \
{ \
.line_config = line_cfg, \
.expect_clk_speed = PANEL_IO_3WIRE_SPI_CLK_MAX, \
.spi_mode = 0, \
.lcd_cmd_bytes = 1, \
.lcd_param_bytes = 1, \
.flags = { \
.use_dc_bit = true, \
.dc_zero_on_data = false, \
.lsb_first = false, \
.cs_high_active = false, \
.del_keep_cs_inactive = true, \
}, \
}

/**
* @brief RGB timing structure
*
* @note frame_rate = pclk_hz / (h_res + hsync_pulse_width + hsync_back_porch + hsync_front_porch)
* / (v_res + vsync_pulse_width + vsync_back_porch + vsync_front_porch)
*
*/
#define GC9503_480_480_PANEL_60HZ_RGB_TIMING() \
{ \
.pclk_hz = 16 * 1000 * 1000, \
.h_res = 480, \
.v_res = 480, \
.hsync_pulse_width = 10, \
.hsync_back_porch = 10, \
.hsync_front_porch = 20, \
.vsync_pulse_width = 10, \
.vsync_back_porch = 10, \
.vsync_front_porch = 10, \
.flags.pclk_active_neg = false, \
}

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit fa9dd75

Please sign in to comment.