From 927b1a67ced9e76fe4f3af96e005c15966647d9c Mon Sep 17 00:00:00 2001 From: AngryApostrophe Date: Fri, 7 Nov 2025 20:12:21 -0700 Subject: [PATCH 1/3] CSTxxx touch: allow build if using custom I2C address --- src/drivers/touch/port/esp_lcd_touch_cst816s.h | 18 ++++++++++++++++++ src/drivers/touch/port/esp_lcd_touch_cst820.h | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/drivers/touch/port/esp_lcd_touch_cst816s.h b/src/drivers/touch/port/esp_lcd_touch_cst816s.h index 98cba221..cdb3787a 100644 --- a/src/drivers/touch/port/esp_lcd_touch_cst816s.h +++ b/src/drivers/touch/port/esp_lcd_touch_cst816s.h @@ -56,6 +56,24 @@ esp_err_t esp_lcd_touch_new_i2c_cst816s(const esp_lcd_panel_io_handle_t io, cons } \ } +/** + * @brief Touch IO configuration structure with input address + * + * @param[in] addr I2C address of the touch panel + * + */ +#define ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG_WITH_ADDR(addr) \ + { \ + .dev_addr = addr, \ + .control_phase_bytes = 1, \ + .dc_bit_offset = 0, \ + .lcd_cmd_bits = 8, \ + .flags = \ + { \ + .disable_control_phase = 1, \ + } \ + } + #ifdef __cplusplus } #endif diff --git a/src/drivers/touch/port/esp_lcd_touch_cst820.h b/src/drivers/touch/port/esp_lcd_touch_cst820.h index cbde1d9a..1c6945bb 100644 --- a/src/drivers/touch/port/esp_lcd_touch_cst820.h +++ b/src/drivers/touch/port/esp_lcd_touch_cst820.h @@ -57,6 +57,24 @@ esp_err_t esp_lcd_touch_new_i2c_cst820(const esp_lcd_panel_io_handle_t io, const } \ } +/** + * @brief Touch IO configuration structure with input address + * + * @param[in] addr I2C address of the touch panel + * + */ +#define ESP_LCD_TOUCH_IO_I2C_CST820_CONFIG_WITH_ADDR(addr) \ + { \ + .dev_addr = addr, \ + .control_phase_bytes = 1, \ + .dc_bit_offset = 0, \ + .lcd_cmd_bits = 8, \ + .flags = \ + { \ + .disable_control_phase = 1, \ + } \ + } + #ifdef __cplusplus } #endif From f105771858aa80cf476ade2dc6174d4a93213295 Mon Sep 17 00:00:00 2001 From: AngryApostrophe Date: Fri, 7 Nov 2025 21:12:42 -0700 Subject: [PATCH 2/3] Add CST9217 touch controller --- README.md | 2 +- docs/drivers/touch.md | 1 + esp_panel_board_custom_conf.h | 3 +- .../touch/esp_panel_touch_conf_internal.h | 16 + src/drivers/touch/esp_panel_touch_cst9217.cpp | 52 ++++ src/drivers/touch/esp_panel_touch_cst9217.hpp | 80 +++++ src/drivers/touch/esp_panel_touch_factory.cpp | 3 + src/drivers/touch/esp_panel_touch_factory.hpp | 1 + .../touch/port/esp_lcd_touch_cst9217.c | 292 ++++++++++++++++++ .../touch/port/esp_lcd_touch_cst9217.h | 79 +++++ 10 files changed, 526 insertions(+), 3 deletions(-) create mode 100644 src/drivers/touch/esp_panel_touch_cst9217.cpp create mode 100644 src/drivers/touch/esp_panel_touch_cst9217.hpp create mode 100644 src/drivers/touch/port/esp_lcd_touch_cst9217.c create mode 100644 src/drivers/touch/port/esp_lcd_touch_cst9217.h diff --git a/README.md b/README.md index 630f97f4..1e830685 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ The functional block diagram is shown below: | Chipsemicorp | CHSC6540 | | FocalTech | FT5x06 | | GOODiX | GT911,GT1151 | -| Hynitron | CST816S,CST820 | +| Hynitron | CST816S,CST820,CST9217 | | Parade | TT21100 | | Sitronix | ST7123,ST1633 | | Solomon Systech | SPD2010 | diff --git a/docs/drivers/touch.md b/docs/drivers/touch.md index 771b4d0b..3c4833ab 100644 --- a/docs/drivers/touch.md +++ b/docs/drivers/touch.md @@ -7,6 +7,7 @@ | CHSC6540 | - | ✅ | | | [CST816S](https://components.espressif.com/components/espressif/esp_lcd_touch_cst816s) | 1.0.3~1 | ✅ | | | CST820 | - | ✅ | | +| CST9217 | 1.0.0 | ✅ | | | [FT5x06](https://components.espressif.com/components/espressif/esp_lcd_touch_ft5x06) | 1.0.6~1 | ✅ | | | [GT911](https://components.espressif.com/components/espressif/esp_lcd_touch_gt911) | 1.1.1~1 | ✅ | | | [GT1151](https://components.espressif.com/components/espressif/esp_lcd_touch_gt1151) | 1.0.5~2 | ✅ | | diff --git a/esp_panel_board_custom_conf.h b/esp_panel_board_custom_conf.h index b86014e0..f9c39b1a 100644 --- a/esp_panel_board_custom_conf.h +++ b/esp_panel_board_custom_conf.h @@ -346,8 +346,7 @@ * Supported controllers: * - `AXS15231B` * - `CHSC6540` - * - `CST816S` - * - `CST820` + * - `CST816S`, 'CST820', 'CST9217' * - `FT5x06` * - `GT911`, `GT1151` * - `SPD2010` diff --git a/src/drivers/touch/esp_panel_touch_conf_internal.h b/src/drivers/touch/esp_panel_touch_conf_internal.h index 218cae6d..634358bd 100644 --- a/src/drivers/touch/esp_panel_touch_conf_internal.h +++ b/src/drivers/touch/esp_panel_touch_conf_internal.h @@ -78,6 +78,14 @@ #endif #endif + #ifndef ESP_PANEL_DRIVERS_TOUCH_USE_CST9217 + #ifdef CONFIG_ESP_PANEL_DRIVERS_TOUCH_USE_CST9217 + #define ESP_PANEL_DRIVERS_TOUCH_USE_CST9217 CONFIG_ESP_PANEL_DRIVERS_TOUCH_USE_CST9217 + #else + #define ESP_PANEL_DRIVERS_TOUCH_USE_CST9217 (0) + #endif + #endif + #ifndef ESP_PANEL_DRIVERS_TOUCH_USE_FT5x06 #ifdef CONFIG_ESP_PANEL_DRIVERS_TOUCH_USE_FT5x06 #define ESP_PANEL_DRIVERS_TOUCH_USE_FT5x06 CONFIG_ESP_PANEL_DRIVERS_TOUCH_USE_FT5x06 @@ -243,6 +251,14 @@ #endif #endif +#ifndef ESP_PANEL_DRIVERS_TOUCH_ENABLE_CST9217 + #if ESP_PANEL_DRIVERS_TOUCH_COMPILE_UNUSED_DRIVERS || ESP_PANEL_DRIVERS_TOUCH_USE_CST9217 + #define ESP_PANEL_DRIVERS_TOUCH_ENABLE_CST9217 (1) + #else + #define ESP_PANEL_DRIVERS_TOUCH_ENABLE_CST9217 (0) + #endif +#endif + #ifndef ESP_PANEL_DRIVERS_TOUCH_ENABLE_FT5x06 #if ESP_PANEL_DRIVERS_TOUCH_COMPILE_UNUSED_DRIVERS || ESP_PANEL_DRIVERS_TOUCH_USE_FT5x06 #define ESP_PANEL_DRIVERS_TOUCH_ENABLE_FT5x06 (1) diff --git a/src/drivers/touch/esp_panel_touch_cst9217.cpp b/src/drivers/touch/esp_panel_touch_cst9217.cpp new file mode 100644 index 00000000..515c3642 --- /dev/null +++ b/src/drivers/touch/esp_panel_touch_cst9217.cpp @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_panel_touch_conf_internal.h" +#if ESP_PANEL_DRIVERS_TOUCH_ENABLE_CST9217 + +#include "utils/esp_panel_utils_log.h" +#include "esp_panel_touch_cst9217.hpp" + +namespace esp_panel::drivers { + +TouchCST9217::~TouchCST9217() +{ + ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); + + ESP_UTILS_CHECK_FALSE_EXIT(del(), "Delete failed"); + + ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); +} + +bool TouchCST9217::begin() +{ + ESP_UTILS_LOG_TRACE_ENTER_WITH_THIS(); + + ESP_UTILS_CHECK_FALSE_RETURN(!isOverState(State::BEGIN), false, "Already begun"); + + // Initialize the touch if not initialized + if (!isOverState(State::INIT)) { + ESP_UTILS_CHECK_FALSE_RETURN(init(), false, "Init failed"); + } + + // Create touch panel + ESP_UTILS_CHECK_ERROR_RETURN( + esp_lcd_touch_new_i2c_cst9217( + getBus()->getControlPanelHandle(), getConfig().getDeviceFullConfig(), &touch_panel + ), false, "Create touch panel failed" + ); + ESP_UTILS_LOGD("Create touch panel(@%p)", touch_panel); + + setState(State::BEGIN); + + ESP_UTILS_LOG_TRACE_EXIT_WITH_THIS(); + + return true; +} + +} // namespace esp_panel::drivers + +#endif // ESP_PANEL_DRIVERS_TOUCH_ENABLE_CST9217 diff --git a/src/drivers/touch/esp_panel_touch_cst9217.hpp b/src/drivers/touch/esp_panel_touch_cst9217.hpp new file mode 100644 index 00000000..3497f057 --- /dev/null +++ b/src/drivers/touch/esp_panel_touch_cst9217.hpp @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "port/esp_lcd_touch_cst9217.h" +#include "esp_panel_touch_conf_internal.h" +#include "esp_panel_touch.hpp" + +namespace esp_panel::drivers { + +/** + * @brief CST9217 touch controller + * + * This class provides implementation for CST9217 touch controller, inheriting from + * the base Touch class to provide common touch functionality + */ +class TouchCST9217 : public Touch { +public: + /** + * @brief Default basic attributes for CST9217 + */ + static constexpr BasicAttributes BASIC_ATTRIBUTES_DEFAULT = { + .name = "CST9217", + .max_points_num = 1, + }; + + /** + * @brief Construct a touch device instance with individual configuration parameters + * + * @param bus Bus interface for communicating with the touch device + * @param width Panel width in pixels + * @param height Panel height in pixels + * @param rst_io Reset GPIO pin number (-1 if unused) + * @param int_io Interrupt GPIO pin number (-1 if unused) + */ + TouchCST9217(Bus *bus, uint16_t width, uint16_t height, int rst_io = -1, int int_io = -1): + Touch(BASIC_ATTRIBUTES_DEFAULT, bus, width, height, rst_io, int_io) + { + } + + /** + * @brief Construct a touch device instance with configuration + * + * @param[in] bus Pointer to the bus interface for communicating with the touch device + * @param[in] config Configuration structure containing device settings and parameters + */ + TouchCST9217(Bus *bus, const Config &config): Touch(BASIC_ATTRIBUTES_DEFAULT, bus, config) {} + + /** + * @brief Construct a touch device instance with bus configuration and device configuration + * + * @param[in] bus_config Bus configuration + * @param[in] touch_config Touch configuration + * @note This constructor creates a new bus instance using the provided bus configuration + */ + TouchCST9217(const BusFactory::Config &bus_config, const Config &touch_config): + Touch(BASIC_ATTRIBUTES_DEFAULT, bus_config, touch_config) + { + } + + /** + * @brief Destruct touch device + */ + ~TouchCST9217() override; + + /** + * @brief Startup the touch device + * + * @return `true` if success, otherwise false + * + * @note This function should be called after `init()` + */ + bool begin() override; +}; + +} // namespace esp_panel::drivers diff --git a/src/drivers/touch/esp_panel_touch_factory.cpp b/src/drivers/touch/esp_panel_touch_factory.cpp index b44948c0..8c093c92 100644 --- a/src/drivers/touch/esp_panel_touch_factory.cpp +++ b/src/drivers/touch/esp_panel_touch_factory.cpp @@ -36,6 +36,9 @@ const utils::unordered_map To #if ESP_PANEL_DRIVERS_TOUCH_USE_CST820 MAP_ITEM(CST820), #endif // CONFIG_ESP_PANEL_TOUCH_CST820 +#if ESP_PANEL_DRIVERS_TOUCH_USE_CST9217 + MAP_ITEM(CST9217), +#endif // CONFIG_ESP_PANEL_TOUCH_CST9217 #if ESP_PANEL_DRIVERS_TOUCH_USE_FT5x06 MAP_ITEM(FT5x06), #endif // CONFIG_ESP_PANEL_TOUCH_FT5x06 diff --git a/src/drivers/touch/esp_panel_touch_factory.hpp b/src/drivers/touch/esp_panel_touch_factory.hpp index 67a30638..b301f968 100644 --- a/src/drivers/touch/esp_panel_touch_factory.hpp +++ b/src/drivers/touch/esp_panel_touch_factory.hpp @@ -14,6 +14,7 @@ #include "esp_panel_touch_chsc6540.hpp" #include "esp_panel_touch_cst816s.hpp" #include "esp_panel_touch_cst820.hpp" +#include "esp_panel_touch_cst9217.hpp" #include "esp_panel_touch_ft5x06.hpp" #include "esp_panel_touch_gt911.hpp" #include "esp_panel_touch_gt1151.hpp" diff --git a/src/drivers/touch/port/esp_lcd_touch_cst9217.c b/src/drivers/touch/port/esp_lcd_touch_cst9217.c new file mode 100644 index 00000000..1958aa2f --- /dev/null +++ b/src/drivers/touch/port/esp_lcd_touch_cst9217.c @@ -0,0 +1,292 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * @file esp_lcd_touch_cst9217.c + * @brief ESP LCD touch: CST9217 + */ + +#include "../esp_panel_touch_conf_internal.h" +#if ESP_PANEL_DRIVERS_TOUCH_ENABLE_CST9217 + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/gpio.h" +#include "esp_system.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_touch.h" + +#include "utils/esp_panel_utils_log.h" +#include "esp_utils_helpers.h" +#include "esp_lcd_touch_cst9217.h" + +#define CST9217_POINT_NUM_MAX (1) +#define CST9217_DATA_LENGTH (CST9217_POINT_NUM_MAX * 5 + 5) + +#define CST9217_REG_DATA (0xD000) +#define CST9217_REG_CMDMODE (0xD101) +#define CST9217_REG_CHECKCODE (0xD1FC) +#define CST9217_REG_RESOLUTION (0xD1F8) +#define CST9217_REG_PROJECT_ID (0xD204) + +#define CST9217_ACK (0xAB) + +#define DATA_START_REG (0x00) +#define CHIP_ID_REG (0xA7) + +static const char *TAG = "CST9217"; + +static esp_err_t cst9217_read_data(esp_lcd_touch_handle_t tp); +static bool cst9217_get_xy(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num); +static esp_err_t cst9217_del(esp_lcd_touch_handle_t tp); +static esp_err_t cst9217_reset(esp_lcd_touch_handle_t tp); +static esp_err_t cst9217_read_config(esp_lcd_touch_handle_t tp); +static esp_err_t i2c_read_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len); + +static esp_err_t cst9217_read_register(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, size_t len); +static esp_err_t cst9217_write_register(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, size_t len); + + +esp_err_t esp_lcd_touch_new_i2c_cst9217(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *tp) +{ + ESP_LOGI(TAG, "version: %d.%d.%d", ESP_LCD_TOUCH_CST9217_VER_MAJOR, ESP_LCD_TOUCH_CST9217_VER_MINOR, ESP_LCD_TOUCH_CST9217_VER_PATCH); + ESP_RETURN_ON_FALSE(io, ESP_ERR_INVALID_ARG, TAG, "Invalid io"); + ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Invalid config"); + ESP_RETURN_ON_FALSE(tp, ESP_ERR_INVALID_ARG, TAG, "Invalid touch handle"); + + /* Prepare main structure */ + esp_err_t ret = ESP_OK; + esp_lcd_touch_handle_t cst9217 = calloc(1, sizeof(esp_lcd_touch_t)); + ESP_GOTO_ON_FALSE(cst9217, ESP_ERR_NO_MEM, err, TAG, "Touch handle malloc failed"); + + /* Communication interface */ + cst9217->io = io; + /* Only supported callbacks are set */ + cst9217->read_data = cst9217_read_data; + cst9217->get_xy = cst9217_get_xy; + cst9217->del = cst9217_del; + /* Mutex */ + cst9217->data.lock.owner = portMUX_FREE_VAL; + /* Save config */ + memcpy(&cst9217->config, config, sizeof(esp_lcd_touch_config_t)); + + /* Prepare pin for touch controller reset */ + if (cst9217->config.rst_gpio_num != GPIO_NUM_NC) { + const gpio_config_t rst_gpio_config = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = BIT64(cst9217->config.rst_gpio_num) + }; + ESP_GOTO_ON_ERROR(gpio_config(&rst_gpio_config), err, TAG, "GPIO reset config failed"); + } + /* Reset controller */ + ESP_GOTO_ON_ERROR(cst9217_reset(cst9217), err, TAG, "Reset failed"); + /* Read config */ + ESP_GOTO_ON_ERROR(cst9217_read_config(cst9217), err, TAG, "Read config failed"); + *tp = cst9217; + + return ESP_OK; +err: + if (cst9217) { + cst9217_del(cst9217); + } + ESP_LOGE(TAG, "Initialization failed!"); + return ret; +} + +static esp_err_t cst9217_read_data(esp_lcd_touch_handle_t tp) +{ + uint8_t data[CST9217_DATA_LENGTH] = {0}; + esp_err_t ret = ESP_OK; + + ESP_RETURN_ON_ERROR(i2c_read_bytes(tp, CST9217_REG_DATA, (uint8_t *)data, sizeof(data)), TAG, "I2C read failed"); + + if (data[6] != CST9217_ACK) { + ESP_LOGE(TAG, "Invalid response when requesting data"); + return ESP_ERR_INVALID_RESPONSE; + } + + uint8_t points = data[5] & 0x7F; + if (points > CST9217_POINT_NUM_MAX) + points = CST9217_POINT_NUM_MAX; + + portENTER_CRITICAL(&tp->data.lock); + + tp->data.points = 0; + for (int i = 0; i < points; i++) { + uint8_t *p = &data[i * 5 + (i ? 2 : 0)]; + uint8_t status = p[0] & 0x0F; + + if (status == 0x06) { + tp->data.coords[i].x = ((p[1] << 4) | (p[3] >> 4)); + tp->data.coords[i].y = ((p[2] << 4) | (p[3] & 0x0F)); + tp->data.points++; + + ESP_LOGV(TAG, "Touch point %d: (%d, %d)", i, tp->data.coords[i].x, tp->data.coords[i].y); + } + } + + portEXIT_CRITICAL(&tp->data.lock); + + return ret; + + err: + if (tp->config.rst_gpio_num != GPIO_NUM_NC) { + gpio_set_level(tp->config.rst_gpio_num, 0); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level(tp->config.rst_gpio_num, 1); + vTaskDelay(pdMS_TO_TICKS(50)); + } + return ESP_FAIL; +} + +static bool cst9217_get_xy(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num) +{ + assert(tp && x && y && point_num); + + portENTER_CRITICAL(&tp->data.lock); + /* Count of points */ + *point_num = (tp->data.points > max_point_num ? max_point_num : tp->data.points); + for (size_t i = 0; i < *point_num; i++) { + x[i] = tp->data.coords[i].x; + y[i] = tp->data.coords[i].y; + + if (strength) { + strength[i] = 1; //Not supported + } + } + /* Invalidate */ + tp->data.points = 0; + portEXIT_CRITICAL(&tp->data.lock); + + return (*point_num > 0); +} + +static esp_err_t cst9217_del(esp_lcd_touch_handle_t tp) +{ + /* Reset GPIO pin settings */ + if (tp->config.int_gpio_num != GPIO_NUM_NC) { + gpio_reset_pin(tp->config.int_gpio_num); + } + if (tp->config.rst_gpio_num != GPIO_NUM_NC) { + gpio_reset_pin(tp->config.rst_gpio_num); + } + /* Release memory */ + free(tp); + + return ESP_OK; +} + +static esp_err_t cst9217_reset(esp_lcd_touch_handle_t tp) +{ + if (tp->config.rst_gpio_num != GPIO_NUM_NC) { + ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, tp->config.levels.reset), TAG, "GPIO set level failed"); + vTaskDelay(pdMS_TO_TICKS(10)); + ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, !tp->config.levels.reset), TAG, "GPIO set level failed"); + vTaskDelay(pdMS_TO_TICKS(50)); + } + + return ESP_OK; +} + +static esp_err_t cst9217_read_config(esp_lcd_touch_handle_t tp) +{ + uint8_t data[4] = {0}; + esp_err_t ret = ESP_OK; + + uint8_t cmd_mode[2] = {0xD1, 0x01}; + ESP_RETURN_ON_ERROR( cst9217_write_register(tp, CST9217_REG_CMDMODE, cmd_mode, sizeof(cmd_mode)), TAG, "Enter command mode failed"); + vTaskDelay(pdMS_TO_TICKS(10)); + + ESP_RETURN_ON_ERROR( cst9217_read_register(tp, CST9217_REG_CHECKCODE, data, 4), TAG, "Read checkcode failed"); + ESP_LOGI(TAG, "Checkcode: 0x%02X%02X%02X%02X", data[0], data[1], data[2], data[3]); + + ESP_RETURN_ON_ERROR( cst9217_read_register(tp, CST9217_REG_RESOLUTION, data, 4), TAG, "Read resolution failed"); + uint16_t res_x = (data[1] << 8) | data[0]; + uint16_t res_y = (data[3] << 8) | data[2]; + ESP_LOGI(TAG, "Resolution X: %d, Y: %d", res_x, res_y); + + ESP_RETURN_ON_ERROR( cst9217_read_register(tp, CST9217_REG_PROJECT_ID, data, 4), TAG, "Read project ID failed"); + uint16_t chipType = (data[3] << 8) | data[2]; + uint32_t projectID = (data[1] << 8) | data[0]; + ESP_LOGI(TAG, "Chip Type: 0x%04X, ProjectID: 0x%04lX", chipType, projectID); + + return ret; +} + +static esp_err_t i2c_read_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len) +{ + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "Invalid data"); + + return esp_lcd_panel_io_rx_param(tp->io, reg, data, len); +} + +static esp_err_t cst9217_read_register(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, size_t len) +{ + uint8_t reg_buf[2] = {reg >> 8, reg & 0xFF}; + const int max_retries = 5; + esp_err_t ret; + + for (int retry = 0; retry < max_retries; retry++) { + ret = esp_lcd_panel_io_tx_param(tp->io, reg_buf[0], ®_buf[1], 1); + if (ret != ESP_OK) { + ESP_LOGD(TAG, "TX failed, retry %d", retry); + vTaskDelay(pdMS_TO_TICKS(3)); + continue; + } + + vTaskDelay(pdMS_TO_TICKS(2)); + + ret = esp_lcd_panel_io_rx_param(tp->io, -1, data, len); + if (ret == ESP_OK) { + return ESP_OK; + } + ESP_LOGD(TAG, "RX failed, retry %d", retry); + vTaskDelay(pdMS_TO_TICKS(3)); + } + + if (tp->config.rst_gpio_num != GPIO_NUM_NC) { + ESP_LOGW(TAG, "Trigger hardware reset"); + gpio_set_level(tp->config.rst_gpio_num, 0); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level(tp->config.rst_gpio_num, 1); + vTaskDelay(pdMS_TO_TICKS(100)); + } + return ESP_FAIL; +} + +static esp_err_t cst9217_write_register(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, size_t len) +{ + uint8_t reg_buf[2] = {reg >> 8, reg & 0xFF}; + const int max_retries = 5; + esp_err_t ret; + + for (int retry = 0; retry < max_retries; retry++) { + ret = esp_lcd_panel_io_tx_param(tp->io, reg_buf[0], ®_buf[1], 1); + if (ret != ESP_OK) { + ESP_LOGD(TAG, "Addr TX failed, retry %d", retry); + vTaskDelay(pdMS_TO_TICKS(3)); + continue; + } + + vTaskDelay(pdMS_TO_TICKS(2)); + + ret = esp_lcd_panel_io_tx_param(tp->io, data[0], &data[1], len-1); + if (ret == ESP_OK) { + return ESP_OK; + } + ESP_LOGD(TAG, "Data TX failed, retry %d", retry); + vTaskDelay(pdMS_TO_TICKS(3)); + } + return ESP_FAIL; +} + +#endif // ESP_PANEL_DRIVERS_TOUCH_ENABLE_CST9217 diff --git a/src/drivers/touch/port/esp_lcd_touch_cst9217.h b/src/drivers/touch/port/esp_lcd_touch_cst9217.h new file mode 100644 index 00000000..8877fae9 --- /dev/null +++ b/src/drivers/touch/port/esp_lcd_touch_cst9217.h @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file esp_lcd_touch_cst9217.h + * @brief ESP LCD touch: CST9217 + */ + +#pragma once + +#include "esp_lcd_touch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_LCD_TOUCH_CST9217_VER_MAJOR (1) +#define ESP_LCD_TOUCH_CST9217_VER_MINOR (0) +#define ESP_LCD_TOUCH_CST9217_VER_PATCH (0) + +/** + * @brief Create a new CST9217 touch driver + * + * @note The I2C communication should be initialized before use this function. + * + * @param io LCD panel IO handle, it should be created by `esp_lcd_new_panel_io_i2c()` + * @param config Touch panel configuration + * @param tp Touch panel handle + * @return + * - ESP_OK: on success + */ +esp_err_t esp_lcd_touch_new_i2c_cst9217(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *tp); + +/** + * @brief I2C address of the CST9217 controller + * + */ +#define ESP_LCD_TOUCH_IO_I2C_CST9217_ADDRESS (0x5A) + +/** + * @brief Touch IO configuration structure + * + */ +#define ESP_LCD_TOUCH_IO_I2C_CST9217_CONFIG() \ + { \ + .dev_addr = ESP_LCD_TOUCH_IO_I2C_CST9217_ADDRESS, \ + .control_phase_bytes = 1, \ + .dc_bit_offset = 0, \ + .lcd_cmd_bits = 8, \ + .flags = \ + { \ + .disable_control_phase = 1, \ + } \ + } + +/** + * @brief Touch IO configuration structure with input address + * + * @param[in] addr I2C address of the touch panel + * + */ +#define ESP_LCD_TOUCH_IO_I2C_CST9217_CONFIG_WITH_ADDR(addr) \ + { \ + .dev_addr = addr, \ + .control_phase_bytes = 1, \ + .dc_bit_offset = 0, \ + .lcd_cmd_bits = 8, \ + .flags = \ + { \ + .disable_control_phase = 1, \ + } \ + } + +#ifdef __cplusplus +} +#endif From eed069a2f7619c6fcc35bf5703e8712c979dcafe Mon Sep 17 00:00:00 2001 From: AngryApostrophe Date: Fri, 7 Nov 2025 21:14:51 -0700 Subject: [PATCH 3/3] Add CST9217 touch controller --- src/drivers/touch/port/esp_lcd_touch_cst9217.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/drivers/touch/port/esp_lcd_touch_cst9217.c b/src/drivers/touch/port/esp_lcd_touch_cst9217.c index 1958aa2f..42e58749 100644 --- a/src/drivers/touch/port/esp_lcd_touch_cst9217.c +++ b/src/drivers/touch/port/esp_lcd_touch_cst9217.c @@ -40,9 +40,6 @@ #define CST9217_ACK (0xAB) -#define DATA_START_REG (0x00) -#define CHIP_ID_REG (0xA7) - static const char *TAG = "CST9217"; static esp_err_t cst9217_read_data(esp_lcd_touch_handle_t tp);