Skip to content

Commit 877ec3f

Browse files
Merge pull request #116 from javen13/javen
创建了触摸驱动cst328
2 parents ec023a9 + 55eca18 commit 877ec3f

File tree

11 files changed

+728
-0
lines changed

11 files changed

+728
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
idf_component_register(SRCS "esp_lcd_touch_cst328.c" INCLUDE_DIRS "include" REQUIRES "esp_lcd")
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# ESP LCD Touch CST328 Controller
2+
3+
[![Component Registry](https://components.espressif.com/components/waveshare/esp_lcd_touch_cst328/badge.svg)](https://components.espressif.com/components/waveshare/esp_lcd_touch_cst328)
4+
5+
Implementation of the CST328 touch controller with esp_lcd_touch component.
6+
7+
| Touch controller | Communication interface | Component name | Link to datasheet |
8+
| :--------------: | :---------------------: | :------------: | :---------------: |
9+
| CST328 | I2C | esp_lcd_touch_cst328 | [WIKI](https://www.waveshare.net/wiki/2.8inch_Capacitive_Touch_LCD) |
10+
11+
## Add to project
12+
13+
Packages from this repository are uploaded to [Espressif's component service](https://components.espressif.com/).
14+
You can add them to your project via `idf.py add-dependancy`, e.g.
15+
```
16+
idf.py add-dependency esp_lcd_touch_cst328==0.0.1
17+
```
18+
19+
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).
20+
21+
## Example use
22+
23+
Initialization of the touch component.
24+
25+
```
26+
27+
const i2c_master_bus_config_t bus_config = {
28+
.i2c_port = I2C_MASTER_NUM,
29+
.sda_io_num = I2C_MASTER_SDA_IO,
30+
.scl_io_num = I2C_MASTER_SCL_IO,
31+
.clk_source = I2C_CLK_SRC_DEFAULT,
32+
};
33+
34+
esp_err_t ret = i2c_new_master_bus(&bus_config, &i2c_handle);
35+
if (ret != ESP_OK) {
36+
ESP_LOGE(TAG, "I2C bus error!");
37+
return;
38+
}
39+
ESP_LOGI(TAG, "I2C bus sucessfull");
40+
41+
i2c_master_bus_handle_t i2c_handle;
42+
i2c_master_get_bus_handle(0,&i2c_handle);
43+
esp_lcd_touch_config_t tp_cfg = {
44+
.x_max = EXAMPLE_LCD_H_RES,
45+
.y_max = EXAMPLE_LCD_V_RES,
46+
.rst_gpio_num = TOUCH_RST,
47+
.int_gpio_num = TOUCH_INT,
48+
.flags = {
49+
.swap_xy = 0,
50+
.mirror_x = 0,
51+
.mirror_y = 0,
52+
},
53+
};
54+
55+
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_CST328_CONFIG();
56+
tp_io_config.scl_speed_hz = I2C_CLK_SPEED_HZ;
57+
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((i2c_master_bus_handle_t)i2c_handle, &tp_io_config, &tp_io_handle));
58+
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_cst328(tp_io_handle, &tp_cfg, &tp_handle));
59+
60+
```
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3+
* SPDX-FileCopyrightText: 2025 Waveshare
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <stdio.h>
9+
#include <string.h>
10+
#include "freertos/FreeRTOS.h"
11+
#include "freertos/task.h"
12+
#include "esp_system.h"
13+
#include "esp_err.h"
14+
#include "esp_log.h"
15+
#include "esp_check.h"
16+
#include "driver/gpio.h"
17+
#include "esp_lcd_panel_io.h"
18+
#include "esp_lcd_touch.h"
19+
#include "esp_lcd_touch_cst328.h"
20+
21+
static const char *TAG = "CST328";
22+
23+
//workmode
24+
#define CST328_REG_DEBUG_INFO_MODE 0xD101
25+
#define CST328_REG_RESET_MODE 0xD102
26+
#define CST328_REG_DEBUG_RECALIBRATION_MODE 0xD104
27+
#define CST328_REG_DEEP_SLEEP_MODE 0xD105
28+
#define CST328_REG_DEBUG_POINT_MODE 0xD108
29+
#define CST328_REG_NORMAL_MODE 0xD109
30+
31+
#define CST328_REG_DEBUG_RAWDATA_MODE 0xD10A
32+
#define CST328_REG_DEBUG_DIFF_MODE 0xD10D
33+
#define CST328_REG_DEBUG_FACTORY_MODE 0xD119
34+
#define CST328_REG_DEBUG_FACTORY_MODE_2 0xD120
35+
//debug info
36+
/****************CST328_REG_DEBUG_INFO_MODE address start***********/
37+
#define CST328_REG_DEBUG_INFO_BOOT_TIME 0xD1FC
38+
#define CST328_REG_DEBUG_INFO_RES_Y 0xD1FA
39+
#define CST328_REG_DEBUG_INFO_RES_X 0xD1F8
40+
#define CST328_REG_DEBUG_INFO_KEY_NUM 0xD1F7
41+
#define CST328_REG_DEBUG_INFO_TP_NRX 0xD1F6
42+
#define CST328_REG_DEBUG_INFO_TP_NTX 0xD1F4
43+
44+
/* CST328 registers */
45+
#define ESP_LCD_TOUCH_CST328_READ_Number_REG (0xD005)
46+
#define ESP_LCD_TOUCH_CST328_READ_XY_REG (0xD000)
47+
#define ESP_LCD_TOUCH_CST328_READ_Checksum_REG (0x80FF)
48+
#define ESP_LCD_TOUCH_CST328_CONFIG_REG (0x8047)
49+
50+
51+
/*******************************************************************************
52+
* Function definitions
53+
*******************************************************************************/
54+
static esp_err_t esp_lcd_touch_cst328_read_data(esp_lcd_touch_handle_t tp);
55+
static bool esp_lcd_touch_cst328_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);
56+
static esp_err_t esp_lcd_touch_cst328_del(esp_lcd_touch_handle_t tp);
57+
static esp_err_t touch_cst328_i2c_read(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len);
58+
static esp_err_t touch_cst328_i2c_write(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len);
59+
static esp_err_t touch_cst328_reset(esp_lcd_touch_handle_t tp);
60+
static void touch_cst328_read_cfg(esp_lcd_touch_handle_t tp);
61+
62+
63+
/*******************************************************************************
64+
* Public API functions
65+
*******************************************************************************/
66+
67+
esp_err_t esp_lcd_touch_new_i2c_cst328(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *out_touch)
68+
{
69+
esp_err_t ret = ESP_OK;
70+
71+
assert(io != NULL);
72+
assert(config != NULL);
73+
assert(out_touch != NULL);
74+
75+
/* Prepare main structure */
76+
esp_lcd_touch_handle_t esp_lcd_touch_cst328 = heap_caps_calloc(1, sizeof(esp_lcd_touch_t), MALLOC_CAP_DEFAULT);
77+
ESP_GOTO_ON_FALSE(esp_lcd_touch_cst328, ESP_ERR_NO_MEM, err, TAG, "no mem for CST328 controller");
78+
/* Communication interface */
79+
esp_lcd_touch_cst328->io = io;
80+
81+
/* Only supported callbacks are set */
82+
esp_lcd_touch_cst328->read_data = esp_lcd_touch_cst328_read_data;
83+
esp_lcd_touch_cst328->get_xy = esp_lcd_touch_cst328_get_xy;
84+
esp_lcd_touch_cst328->del = esp_lcd_touch_cst328_del;
85+
86+
/* Mutex */
87+
esp_lcd_touch_cst328->data.lock.owner = portMUX_FREE_VAL;
88+
89+
/* Save config */
90+
memcpy(&esp_lcd_touch_cst328->config, config, sizeof(esp_lcd_touch_config_t));
91+
92+
/* Prepare pin for touch interrupt */
93+
if (esp_lcd_touch_cst328->config.int_gpio_num != GPIO_NUM_NC) {
94+
const gpio_config_t int_gpio_config = {
95+
.mode = GPIO_MODE_INPUT,
96+
.intr_type = GPIO_INTR_NEGEDGE,
97+
.pin_bit_mask = BIT64(esp_lcd_touch_cst328->config.int_gpio_num)
98+
};
99+
ret = gpio_config(&int_gpio_config);
100+
ESP_GOTO_ON_ERROR(ret, err, TAG, "GPIO config failed");
101+
102+
}
103+
104+
/* Reset controller */
105+
ret = touch_cst328_reset(esp_lcd_touch_cst328);
106+
ESP_GOTO_ON_ERROR(ret, err, TAG, "CST328 reset failed");
107+
touch_cst328_read_cfg(esp_lcd_touch_cst328);
108+
109+
err:
110+
if (ret != ESP_OK) {
111+
ESP_LOGE(TAG, "Error (0x%x)! Touch controller CST328 initialization failed!", ret);
112+
if (esp_lcd_touch_cst328) {
113+
esp_lcd_touch_cst328_del(esp_lcd_touch_cst328);
114+
}
115+
}
116+
117+
*out_touch = esp_lcd_touch_cst328;
118+
119+
return ret;
120+
}
121+
122+
/*******************************************************************************
123+
* Private functions
124+
*******************************************************************************/
125+
126+
static esp_err_t esp_lcd_touch_cst328_read_data(esp_lcd_touch_handle_t tp)
127+
{
128+
esp_err_t err;
129+
uint8_t buf[41];
130+
uint8_t touch_cnt = 0;
131+
uint8_t clear = 0;
132+
size_t i = 0,num=0;
133+
134+
assert(tp != NULL);
135+
136+
err = touch_cst328_i2c_read(tp, ESP_LCD_TOUCH_CST328_READ_Number_REG, buf, 1);
137+
ESP_RETURN_ON_ERROR(err, TAG, "I2C read error!");
138+
/* Any touch data? */
139+
if ((buf[0] & 0x0F) == 0x00) {
140+
touch_cst328_i2c_write(tp, ESP_LCD_TOUCH_CST328_READ_Number_REG, &clear, 1); // No touch data
141+
} else {
142+
/* Count of touched points */
143+
touch_cnt = buf[0] & 0x0F;
144+
if (touch_cnt > 5 || touch_cnt == 0) {
145+
touch_cst328_i2c_write(tp, ESP_LCD_TOUCH_CST328_READ_Number_REG, &clear, 1);
146+
return ESP_OK;
147+
}
148+
149+
/* Read all points */
150+
err = touch_cst328_i2c_read(tp, ESP_LCD_TOUCH_CST328_READ_XY_REG, &buf[1], 27);
151+
ESP_RETURN_ON_ERROR(err, TAG, "I2C read error!");
152+
153+
/* Clear all */
154+
err = touch_cst328_i2c_write(tp, ESP_LCD_TOUCH_CST328_READ_Number_REG, &clear, 1);
155+
ESP_RETURN_ON_ERROR(err, TAG, "I2C read error!");
156+
157+
taskENTER_CRITICAL(&tp->data.lock);
158+
159+
/* Number of touched points */
160+
if(touch_cnt > CONFIG_ESP_LCD_TOUCH_MAX_POINTS)
161+
touch_cnt = CONFIG_ESP_LCD_TOUCH_MAX_POINTS;
162+
tp->data.points = (uint8_t)touch_cnt;
163+
164+
/* Fill all coordinates */
165+
for (i = 0; i < touch_cnt; i++) {
166+
if(i>0) num = 2;
167+
tp->data.coords[i].x = (uint16_t)(((uint16_t)buf[(i * 5) + 2 + num] << 4) + ((buf[(i * 5) + 4 + num] & 0xF0)>> 4));
168+
tp->data.coords[i].y = (uint16_t)(((uint16_t)buf[(i * 5) + 3 + num] << 4) + ( buf[(i * 5) + 4 + num] & 0x0F));
169+
tp->data.coords[i].strength = ((uint16_t)buf[(i * 5) + 5 + num]);
170+
}
171+
172+
taskEXIT_CRITICAL(&tp->data.lock);
173+
}
174+
175+
return ESP_OK;
176+
}
177+
178+
179+
180+
static bool esp_lcd_touch_cst328_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)
181+
{
182+
assert(tp != NULL);
183+
assert(x != NULL);
184+
assert(y != NULL);
185+
assert(point_num != NULL);
186+
assert(max_point_num > 0);
187+
188+
taskENTER_CRITICAL(&tp->data.lock);
189+
190+
/* Count of points */
191+
if(tp->data.points > max_point_num)
192+
tp->data.points = max_point_num;
193+
194+
for (size_t i = 0; i < tp->data.points; i++) {
195+
x[i] = tp->data.coords[i].x;
196+
y[i] = tp->data.coords[i].y;
197+
198+
if (strength) {
199+
strength[i] = tp->data.coords[i].strength;
200+
}
201+
}
202+
*point_num = tp->data.points;
203+
/* Invalidate */
204+
tp->data.points = 0;
205+
206+
207+
taskEXIT_CRITICAL(&tp->data.lock);
208+
return (*point_num > 0);
209+
}
210+
211+
212+
static esp_err_t esp_lcd_touch_cst328_del(esp_lcd_touch_handle_t tp)
213+
{
214+
assert(tp != NULL);
215+
216+
/* Reset GPIO pin settings */
217+
if (tp->config.int_gpio_num != GPIO_NUM_NC) {
218+
gpio_reset_pin(tp->config.int_gpio_num);
219+
}
220+
221+
/* Reset GPIO pin settings */
222+
if (tp->config.rst_gpio_num != GPIO_NUM_NC) {
223+
gpio_reset_pin(tp->config.rst_gpio_num);
224+
}
225+
226+
free(tp);
227+
228+
return ESP_OK;
229+
}
230+
231+
232+
233+
static esp_err_t touch_cst328_reset(esp_lcd_touch_handle_t tp)
234+
{
235+
assert(tp != NULL);
236+
237+
ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, !tp->config.levels.reset), TAG, "GPIO set level error!");
238+
vTaskDelay(pdMS_TO_TICKS(10));
239+
ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, tp->config.levels.reset), TAG, "GPIO set level error!");
240+
vTaskDelay(pdMS_TO_TICKS(10));
241+
242+
return ESP_OK;
243+
}
244+
245+
static void touch_cst328_read_cfg(esp_lcd_touch_handle_t tp)
246+
{
247+
uint8_t buf[24];
248+
249+
assert(tp != NULL);
250+
touch_cst328_i2c_write(tp, CST328_REG_DEBUG_INFO_MODE, buf, 0);
251+
touch_cst328_i2c_read(tp, CST328_REG_DEBUG_INFO_BOOT_TIME, (uint8_t *)&buf[0], 4);
252+
ESP_LOGI(TAG, "TouchPad_ID:0x%02x,0x%02x,0x%02x,0x%02x", buf[0], buf[1], buf[2], buf[3]);
253+
254+
touch_cst328_i2c_read(tp, CST328_REG_DEBUG_INFO_RES_X, (uint8_t *)&buf[0], 1);
255+
touch_cst328_i2c_read(tp, CST328_REG_DEBUG_INFO_RES_X+1, (uint8_t *)&buf[1], 1);
256+
ESP_LOGI(TAG, "TouchPad_X_MAX:%d", buf[1]*256+buf[0]);
257+
touch_cst328_i2c_read(tp, CST328_REG_DEBUG_INFO_RES_Y, (uint8_t *)&buf[2], 1);
258+
touch_cst328_i2c_read(tp, CST328_REG_DEBUG_INFO_RES_Y+1, (uint8_t *)&buf[3], 1);
259+
ESP_LOGI(TAG, "TouchPad_Y_MAX:%d", buf[3]*256+buf[2]);
260+
261+
touch_cst328_i2c_read(tp, CST328_REG_DEBUG_INFO_TP_NTX, buf, 24);
262+
ESP_LOGI(TAG, "D1F4:0x%02x,0x%02x,0x%02x,0x%02x", buf[0], buf[1], buf[2], buf[3]);
263+
ESP_LOGI(TAG, "D1F8:0x%02x,0x%02x,0x%02x,0x%02x", buf[4], buf[5], buf[6], buf[7]);
264+
ESP_LOGI(TAG, "D1FC:0x%02x,0x%02x,0x%02x,0x%02x", buf[8], buf[9], buf[10], buf[11]);
265+
ESP_LOGI(TAG, "D200:0x%02x,0x%02x,0x%02x,0x%02x", buf[12], buf[13], buf[14], buf[15]);
266+
ESP_LOGI(TAG, "D204:0x%02x,0x%02x,0x%02x,0x%02x", buf[16], buf[17], buf[18], buf[19]);
267+
ESP_LOGI(TAG, "D208:0x%02x,0x%02x,0x%02x,0x%02x", buf[20], buf[21], buf[22], buf[23]);
268+
269+
touch_cst328_i2c_write(tp, CST328_REG_NORMAL_MODE, buf, 0);
270+
}
271+
272+
273+
static esp_err_t touch_cst328_i2c_read(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len)
274+
{
275+
assert(tp != NULL);
276+
assert(data != NULL);
277+
278+
/* Read data */
279+
return esp_lcd_panel_io_rx_param(tp->io, reg, data, len);
280+
}
281+
282+
static esp_err_t touch_cst328_i2c_write(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t* data, uint8_t len)
283+
{
284+
assert(tp != NULL);
285+
/* Write data */
286+
return esp_lcd_panel_io_tx_param(tp->io, reg, data, len);
287+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
dependencies:
2+
esp_lcd_touch:
3+
public: true
4+
version: "^1.0.0"
5+
idf: '>=4.4.2'
6+
description: "ESP LCD Touch CST328 -The touch controller CST328 is adapted by waveshare"
7+
url: "https://github.com/waveshareteam/Waveshare-ESP32-components/tree/master/display/touch/esp_lcd_touch_cst328"
8+
version: "1.0.4"

0 commit comments

Comments
 (0)