Skip to content

Commit 0358e7d

Browse files
VIEWESMARTLzw655
authored andcommitted
feat(touch): add touch controller CHSC6540 @VIEWESMART (#128)
1 parent 32cdcee commit 0358e7d

File tree

4 files changed

+367
-0
lines changed

4 files changed

+367
-0
lines changed

src/touch/CHSC6540.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "ESP_PanelLog.h"
8+
#include "CHSC6540.h"
9+
10+
static const char *TAG = "CHSC6540_CPP";
11+
12+
ESP_PanelTouch_CHSC6540::ESP_PanelTouch_CHSC6540(ESP_PanelBus *bus, uint16_t width, uint16_t height,
13+
int rst_io, int int_io):
14+
ESP_PanelTouch(bus, width, height, rst_io, int_io)
15+
{
16+
}
17+
18+
ESP_PanelTouch_CHSC6540::ESP_PanelTouch_CHSC6540(ESP_PanelBus *bus, const esp_lcd_touch_config_t &config):
19+
ESP_PanelTouch(bus, config)
20+
{
21+
}
22+
23+
ESP_PanelTouch_CHSC6540::~ESP_PanelTouch_CHSC6540()
24+
{
25+
ESP_PANEL_ENABLE_TAG_DEBUG_LOG();
26+
27+
if (handle == NULL) {
28+
goto end;
29+
}
30+
31+
if (!del()) {
32+
ESP_LOGE(TAG, "Delete device failed");
33+
}
34+
35+
end:
36+
ESP_LOGD(TAG, "Destroyed");
37+
}
38+
39+
bool ESP_PanelTouch_CHSC6540::begin(void)
40+
{
41+
ESP_PANEL_CHECK_NULL_RET(bus, false, "Invalid bus");
42+
43+
ESP_PANEL_CHECK_ERR_RET(esp_lcd_touch_new_i2c_chsc6540(bus->getHandle(), &config, &handle), false, "New driver failed");
44+
45+
return true;
46+
}

src/touch/CHSC6540.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include "base/esp_lcd_touch_chsc6540.h"
10+
#include "ESP_PanelTouch.h"
11+
12+
/**
13+
* @brief CHSC6540 touch device object class
14+
*
15+
* @note This class is a derived class of `ESP_PanelTouch`, user can use it directly
16+
*/
17+
class ESP_PanelTouch_CHSC6540 : public ESP_PanelTouch {
18+
public:
19+
/**
20+
* @brief Construct a new touch device in a simple way, the `init()` function should be called after this function
21+
*
22+
* @param bus Pointer to panel bus
23+
* @param width The width of the touch screen
24+
* @param height The height of the touch screen
25+
* @param rst_io The reset pin of the touch screen, set to `-1` if not used
26+
* @param int_io The interrupt pin of the touch screen, set to `-1` if not used
27+
*/
28+
ESP_PanelTouch_CHSC6540(ESP_PanelBus *bus, uint16_t width, uint16_t height, int rst_io = -1, int int_io = -1);
29+
30+
/**
31+
* @brief Construct a new touch device in a complex way, the `init()` function should be called after this function
32+
*
33+
* @param bus Pointer to panel bus
34+
* @param config Touch device configuration
35+
*/
36+
ESP_PanelTouch_CHSC6540(ESP_PanelBus *bus, const esp_lcd_touch_config_t &config);
37+
38+
/**
39+
* @brief Destroy the LCD device
40+
*
41+
*/
42+
~ESP_PanelTouch_CHSC6540() override;
43+
44+
/**
45+
* @brief Startup the touch device
46+
*
47+
* @return true if success, otherwise false
48+
*/
49+
bool begin(void) override;
50+
};
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "ESP_PanelLog.h"
8+
9+
#include <inttypes.h>
10+
#include <stdio.h>
11+
#include <string.h>
12+
#include "freertos/FreeRTOS.h"
13+
#include "freertos/task.h"
14+
#include "driver/gpio.h"
15+
#include "driver/i2c.h"
16+
#include "esp_system.h"
17+
#include "esp_err.h"
18+
#include "esp_log.h"
19+
#include "esp_check.h"
20+
#include "esp_lcd_panel_io.h"
21+
#include "esp_lcd_touch.h"
22+
23+
#include "esp_lcd_touch_chsc6540.h"
24+
25+
#define POINT_NUM_MAX (1)
26+
27+
#define DATA_START_REG (0x00)
28+
29+
#define CHIP_ID_REG (0xA7)
30+
31+
static const char *TAG = "CHSC6540";
32+
33+
static esp_err_t read_data(esp_lcd_touch_handle_t tp);
34+
static bool 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);
35+
static esp_err_t del(esp_lcd_touch_handle_t tp);
36+
37+
static esp_err_t i2c_read_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len);
38+
39+
static esp_err_t reset(esp_lcd_touch_handle_t tp);
40+
static esp_err_t read_id(esp_lcd_touch_handle_t tp);
41+
42+
esp_err_t esp_lcd_touch_new_i2c_chsc6540(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *tp)
43+
{
44+
ESP_RETURN_ON_FALSE(io, ESP_ERR_INVALID_ARG, TAG, "Invalid io");
45+
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Invalid config");
46+
ESP_RETURN_ON_FALSE(tp, ESP_ERR_INVALID_ARG, TAG, "Invalid touch handle");
47+
48+
ESP_PANEL_ENABLE_TAG_DEBUG_LOG();
49+
50+
/* Prepare main structure */
51+
esp_err_t ret = ESP_OK;
52+
esp_lcd_touch_handle_t chsc6540 = calloc(1, sizeof(esp_lcd_touch_t));
53+
ESP_GOTO_ON_FALSE(chsc6540, ESP_ERR_NO_MEM, err, TAG, "Touch handle malloc failed");
54+
55+
/* Communication interface */
56+
chsc6540->io = io;
57+
/* Only supported callbacks are set */
58+
chsc6540->read_data = read_data;
59+
chsc6540->get_xy = get_xy;
60+
chsc6540->del = del;
61+
/* Mutex */
62+
chsc6540->data.lock.owner = portMUX_FREE_VAL;
63+
/* Save config */
64+
memcpy(&chsc6540->config, config, sizeof(esp_lcd_touch_config_t));
65+
66+
/* Prepare pin for touch interrupt */
67+
if (chsc6540->config.int_gpio_num != GPIO_NUM_NC) {
68+
const gpio_config_t int_gpio_config = {
69+
.mode = GPIO_MODE_INPUT,
70+
.intr_type = (chsc6540->config.levels.interrupt ? GPIO_INTR_POSEDGE : GPIO_INTR_NEGEDGE),
71+
.pin_bit_mask = BIT64(chsc6540->config.int_gpio_num)
72+
};
73+
ESP_GOTO_ON_ERROR(gpio_config(&int_gpio_config), err, TAG, "GPIO intr config failed");
74+
75+
/* Register interrupt callback */
76+
if (chsc6540->config.interrupt_callback) {
77+
esp_lcd_touch_register_interrupt_callback(chsc6540, chsc6540->config.interrupt_callback);
78+
}
79+
}
80+
/* Prepare pin for touch controller reset */
81+
if (chsc6540->config.rst_gpio_num != GPIO_NUM_NC) {
82+
const gpio_config_t rst_gpio_config = {
83+
.mode = GPIO_MODE_OUTPUT,
84+
.pin_bit_mask = BIT64(chsc6540->config.rst_gpio_num)
85+
};
86+
ESP_GOTO_ON_ERROR(gpio_config(&rst_gpio_config), err, TAG, "GPIO reset config failed");
87+
}
88+
/* Reset controller */
89+
ESP_GOTO_ON_ERROR(reset(chsc6540), err, TAG, "Reset failed");
90+
/* Read product id */
91+
// ESP_GOTO_ON_ERROR(read_id(chsc6540), err, TAG, "Read version failed");
92+
*tp = chsc6540;
93+
94+
ESP_LOGI(TAG, "LCD touch panel create success, version: %d.%d.%d", ESP_LCD_TOUCH_CHSC6540_VER_MAJOR, ESP_LCD_TOUCH_CHSC6540_VER_MINOR,
95+
ESP_LCD_TOUCH_CHSC6540_VER_PATCH);
96+
97+
return ESP_OK;
98+
err:
99+
if (chsc6540) {
100+
del(chsc6540);
101+
}
102+
ESP_LOGE(TAG, "Initialization failed!");
103+
return ret;
104+
}
105+
106+
static esp_err_t read_data(esp_lcd_touch_handle_t tp)
107+
{
108+
typedef struct {
109+
uint8_t num;
110+
uint8_t x_h : 4;
111+
uint8_t : 4;
112+
uint8_t x_l;
113+
uint8_t y_h : 4;
114+
uint8_t : 4;
115+
uint8_t y_l;
116+
} data_t;
117+
118+
data_t point;
119+
120+
uint8_t buf[15]={0};
121+
uint8_t touch_num=0;
122+
uint16_t x=0;
123+
uint16_t y=0;
124+
uint8_t gc=0;//报点过程
125+
ESP_RETURN_ON_ERROR(i2c_read_bytes(tp, DATA_START_REG, buf, sizeof(buf)), TAG, "I2C read failed");
126+
127+
point.num=buf[2];
128+
129+
gc=buf[3]>>4;
130+
131+
x= (uint16_t)(((buf[3]&0x0F)<<8)+buf[4]);
132+
y= (uint16_t)(((buf[5]&0x0F)<<8)+buf[6]);
133+
134+
135+
portENTER_CRITICAL(&tp->data.lock);
136+
point.num = (point.num > POINT_NUM_MAX ? POINT_NUM_MAX : point.num);
137+
tp->data.points = point.num;
138+
/* Fill all coordinates */
139+
for (int i = 0; i < tp->data.points ; i++) {
140+
tp->data.coords[i].x = x;
141+
tp->data.coords[i].y = y;
142+
}
143+
portEXIT_CRITICAL(&tp->data.lock);
144+
145+
return ESP_OK;
146+
}
147+
148+
static bool 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)
149+
{
150+
portENTER_CRITICAL(&tp->data.lock);
151+
/* Count of points */
152+
*point_num = (tp->data.points > max_point_num ? max_point_num : tp->data.points);
153+
for (size_t i = 0; i < *point_num; i++) {
154+
x[i] = tp->data.coords[i].x;
155+
y[i] = tp->data.coords[i].y;
156+
157+
if (strength) {
158+
strength[i] = tp->data.coords[i].strength;
159+
}
160+
}
161+
/* Invalidate */
162+
tp->data.points = 0;
163+
portEXIT_CRITICAL(&tp->data.lock);
164+
165+
return (*point_num > 0);
166+
}
167+
168+
static esp_err_t del(esp_lcd_touch_handle_t tp)
169+
{
170+
/* Reset GPIO pin settings */
171+
if (tp->config.int_gpio_num != GPIO_NUM_NC) {
172+
gpio_reset_pin(tp->config.int_gpio_num);
173+
if (tp->config.interrupt_callback) {
174+
gpio_isr_handler_remove(tp->config.int_gpio_num);
175+
}
176+
}
177+
if (tp->config.rst_gpio_num != GPIO_NUM_NC) {
178+
gpio_reset_pin(tp->config.rst_gpio_num);
179+
}
180+
/* Release memory */
181+
free(tp);
182+
183+
return ESP_OK;
184+
}
185+
186+
static esp_err_t reset(esp_lcd_touch_handle_t tp)
187+
{
188+
if (tp->config.rst_gpio_num != GPIO_NUM_NC) {
189+
ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, tp->config.levels.reset), TAG, "GPIO set level failed");
190+
vTaskDelay(pdMS_TO_TICKS(200));
191+
ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, !tp->config.levels.reset), TAG, "GPIO set level failed");
192+
vTaskDelay(pdMS_TO_TICKS(200));
193+
}
194+
195+
return ESP_OK;
196+
}
197+
198+
static esp_err_t read_id(esp_lcd_touch_handle_t tp)
199+
{
200+
uint8_t id;
201+
ESP_RETURN_ON_ERROR(i2c_read_bytes(tp, CHIP_ID_REG, &id, 1), TAG, "I2C read failed");
202+
ESP_LOGI(TAG, "IC id: %d", id);
203+
return ESP_OK;
204+
}
205+
206+
static esp_err_t i2c_read_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len)
207+
{
208+
ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "Invalid data");
209+
210+
return esp_lcd_panel_io_rx_param(tp->io, reg, data, len);
211+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file
9+
* @brief ESP LCD touch: CHSC6540
10+
*/
11+
12+
#pragma once
13+
14+
#include "esp_lcd_touch.h"
15+
16+
#ifdef __cplusplus
17+
extern "C" {
18+
#endif
19+
20+
#define ESP_LCD_TOUCH_CHSC6540_VER_MAJOR (1)
21+
#define ESP_LCD_TOUCH_CHSC6540_VER_MINOR (0)
22+
#define ESP_LCD_TOUCH_CHSC6540_VER_PATCH (0)
23+
24+
/**
25+
* @brief Create a new CHSC6540 touch driver
26+
*
27+
* @note The I2C communication should be initialized before use this function.
28+
*
29+
* @param io LCD panel IO handle, it should be created by `esp_lcd_new_panel_io_i2c()`
30+
* @param config Touch panel configuration
31+
* @param tp Touch panel handle
32+
* @return
33+
* - ESP_OK: on success
34+
*/
35+
esp_err_t esp_lcd_touch_new_i2c_chsc6540(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *tp);
36+
37+
/**
38+
* @brief I2C address of the CHSC6540 controller
39+
*
40+
*/
41+
#define ESP_LCD_TOUCH_IO_I2C_CHSC6540_ADDRESS (0x2E)
42+
/**
43+
* @brief Touch IO configuration structure
44+
*
45+
*/
46+
#define ESP_LCD_TOUCH_IO_I2C_CHSC6540_CONFIG() \
47+
{ \
48+
.dev_addr = ESP_LCD_TOUCH_IO_I2C_CHSC6540_ADDRESS, \
49+
.control_phase_bytes = 1, \
50+
.dc_bit_offset = 0, \
51+
.lcd_cmd_bits = 8, \
52+
.flags = \
53+
{ \
54+
.disable_control_phase = 1, \
55+
} \
56+
}
57+
58+
#ifdef __cplusplus
59+
}
60+
#endif

0 commit comments

Comments
 (0)