Skip to content

Commit 49f5518

Browse files
committed
feat(t-deck): WIP t-deck support
* Added gt911 component for t-deck touchscreen (does not seem to work yet) * Updated config and code to work for t-deck screen
1 parent 0403d9b commit 49f5518

File tree

5 files changed

+364
-11
lines changed

5 files changed

+364
-11
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ set(EXTRA_COMPONENT_DIRS
1313

1414
set(
1515
COMPONENTS
16-
"main esptool_py driver lwip button display display_drivers input_drivers logger lvgl mdns socket task tt21100 wifi gui"
16+
"main esptool_py driver lwip button display display_drivers input_drivers logger lvgl mdns socket task tt21100 gt911 wifi gui"
1717
CACHE STRING
1818
"List of components to include"
1919
)

components/gt911/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
idf_component_register(
2+
INCLUDE_DIRS "include"
3+
REQUIRES "logger"
4+
)

components/gt911/include/gt911.hpp

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
#pragma once
2+
3+
#include <functional>
4+
5+
#include "logger.hpp"
6+
7+
class Gt911 {
8+
public:
9+
static constexpr uint8_t DEFAULT_ADDRESS_1 = 0x5D;
10+
static constexpr uint8_t DEFAULT_ADDRESS_2 = 0x14;
11+
12+
typedef std::function<void(uint8_t, uint16_t, uint8_t*, size_t)> read_fn;
13+
typedef std::function<void(uint8_t, uint8_t*, size_t)> write_fn;
14+
15+
struct Config {
16+
read_fn read;
17+
write_fn write;
18+
uint8_t address = DEFAULT_ADDRESS_1; /**< Which address to use for this chip? */
19+
espp::Logger::Verbosity log_level{espp::Logger::Verbosity::WARN}; /**< Log verbosity for the input driver. */
20+
};
21+
22+
Gt911(const Config& config)
23+
: read_(config.read),
24+
write_(config.write),
25+
address_(config.address),
26+
logger_({.tag = "Gt911", .level = config.log_level}) {
27+
init();
28+
}
29+
30+
bool read() {
31+
static constexpr size_t DATA_LEN = CONTACT_SIZE * MAX_CONTACTS;
32+
static uint8_t data[DATA_LEN];
33+
read(Registers::POINT_INFO, data, DATA_LEN);
34+
num_touch_points_ = data[0] & 0x0f;
35+
if (num_touch_points_ > 0) {
36+
logger_.debug("Got {} touch points", num_touch_points_);
37+
// convert the data pointer to a GTPoint*
38+
GTPoint* point = (GTPoint*)&data[1];
39+
x_ = point->x;
40+
y_ = point->y;
41+
logger_.debug("Touch at ({}, {})", x_, y_);
42+
}
43+
write(Registers::POINT_INFO, 0x00); // sync signal
44+
45+
return num_touch_points_ > 0;
46+
}
47+
48+
uint8_t get_num_touch_points() {
49+
return num_touch_points_;
50+
}
51+
52+
void get_touch_point(uint8_t *num_touch_points, uint16_t *x, uint16_t *y) {
53+
*num_touch_points = get_num_touch_points();
54+
if (*num_touch_points != 0) {
55+
*x = x_;
56+
*y = y_;
57+
logger_.info("Got touch ({}, {})", *x, *y);
58+
}
59+
}
60+
61+
uint8_t get_home_button_state() {
62+
return home_button_pressed_;
63+
}
64+
65+
protected:
66+
void init() {
67+
using namespace std::chrono_literals;
68+
/*
69+
*/
70+
// write 0x02 (software reset) to GT911 COMMAND register
71+
write(Registers::COMMAND, 0x02);
72+
// delay 200 ms
73+
std::this_thread::sleep_for(200ms);
74+
// val = read SWITCH_1
75+
uint8_t val = read(Registers::SWITCH_1);
76+
val &= 0xFC;
77+
val |= 0x03;
78+
// write back val to switch 1
79+
write(Registers::SWITCH_1, val);
80+
// delay 200 ms
81+
std::this_thread::sleep_for(200ms);
82+
}
83+
84+
static constexpr int CONTACT_SIZE = 8;
85+
static constexpr int MAX_CONTACTS = 5;
86+
static constexpr int CONFIG_MAX_LEN = 240;
87+
static constexpr int CONFIG_911_LEN = 186;
88+
static constexpr int CONFIG_967_LEN = 228;
89+
90+
enum class Registers : uint16_t {
91+
COMMAND = 0x8040,
92+
CONFIG = 0x8047,
93+
SWITCH_1 = 0x804D,
94+
SWITCH_2 = 0x804E,
95+
REFRESH_RATE = 0x8056,
96+
DATA = 0x8140,
97+
POINT_INFO = 0x814E,
98+
POINTS = 0x814F,
99+
POINT_1 = 0x814F,
100+
POINT_2 = 0x8157,
101+
POINT_3 = 0x815F,
102+
POINT_4 = 0x8167,
103+
POINT_5 = 0x816F,
104+
};
105+
106+
// From Goodix library
107+
struct GTInfo {
108+
// 0x8140-0x814A
109+
char productId[4];
110+
uint16_t fwId;
111+
uint16_t xResolution;
112+
uint16_t yResolution;
113+
uint8_t vendorId;
114+
} __attribute__((packed));
115+
116+
struct GTPoint {
117+
// 0x814F-0x8156, ... 0x8176 (5 points)
118+
uint8_t trackId;
119+
uint16_t x;
120+
uint16_t y;
121+
uint16_t area;
122+
uint8_t reserved;
123+
} __attribute__((packed));
124+
125+
struct GTLevelConfig {
126+
uint8_t touch; // Threshold of touch grow out of nothing
127+
uint8_t leave; // Threshold of touch decrease to nothing
128+
} __attribute__((packed));
129+
130+
struct GTStylusConfig {
131+
uint8_t txGain;
132+
uint8_t rxGain;
133+
uint8_t dumpShift;
134+
GTLevelConfig level;
135+
uint8_t control; //Pen mode escape time out period (Unit: Sec)
136+
} __attribute__((packed));
137+
138+
struct GTFreqHoppingConfig {
139+
uint16_t hoppingBitFreq;
140+
uint8_t hoppingFactor;
141+
} __attribute__((packed));
142+
143+
struct GTKeyConfig {
144+
// Key position: 0-255 valid
145+
// 0 means no touch, it means independent touch key when 4 of the keys are 8 multiples
146+
uint8_t pos1;
147+
uint8_t pos2;
148+
uint8_t pos3;
149+
uint8_t pos4;
150+
uint8_t area;
151+
GTLevelConfig level;
152+
uint8_t sens12;
153+
uint8_t sens34;
154+
uint8_t restrain;
155+
} __attribute__((packed));
156+
157+
struct GTConfig {
158+
// start at 0x8047
159+
uint8_t configVersion;
160+
uint16_t xResolution;
161+
uint16_t yResolution;
162+
// 0x804C
163+
uint8_t touchNumber; // 3:0 Touch No.: 1~10
164+
165+
// 7:6 Reserved, 5:4 Stretch rank, 3 X2Y, 2 Sito
166+
// 1:0 INT trig method: 00-rising, 01-falling, 02-low level, 03-high level enquiry
167+
uint8_t moduleSwitch1;
168+
uint8_t moduleSwitch2; // bit0 TouchKey
169+
uint8_t shakeCount; // 3:0 Finger shake count
170+
// 0x8050
171+
// 7:6 First filter, 5:0 Normal filter (filtering value of original coordinate window, coefficiency is 1)
172+
uint8_t filter;
173+
uint8_t largeTouch;
174+
uint8_t noiseReduction;
175+
GTLevelConfig screenLevel;
176+
177+
uint8_t lowPowerControl; // Time to low power consumption (0~15s)
178+
uint8_t refreshRate; // Coordinate report rate (Cycle: 5+N ms)
179+
uint8_t xThreshold; //res
180+
uint8_t yThreshold; //res
181+
uint8_t xSpeedLimit; //res
182+
uint8_t ySpeedLimit; //res
183+
uint8_t vSpace; // 4bit top/bottom (coefficient 32)
184+
uint8_t hSpace; // 4bit left/right
185+
//0x805D-0x8061
186+
uint8_t stretchRate; //Level of weak stretch (Strtch X/16 Pitch)
187+
uint8_t stretchR0; // Interval 1 coefficient
188+
uint8_t stretchR1; // Interval 2 coefficient
189+
uint8_t stretchR2; // Interval 3 coefficient
190+
uint8_t stretchRM; // All intervals base number
191+
192+
uint8_t drvGroupANum;
193+
uint8_t drvGroupBNum;
194+
uint8_t sensorNum;
195+
uint8_t freqAFactor;
196+
uint8_t freqBFactor;
197+
// 0x8067
198+
uint16_t pannelBitFreq; //Baseband of Driver group A\B (1526HZ<baseband<14600Hz)
199+
uint16_t pannelSensorTime; //res
200+
uint8_t pannelTxGain;
201+
uint8_t pannelRxGain;
202+
uint8_t pannelDumpShift;
203+
uint8_t drvFrameControl;
204+
// 0x806F - 0x8071
205+
uint8_t NC_2[3];
206+
GTStylusConfig stylusConfig;
207+
// 0x8078-0x8079
208+
uint8_t NC_3[2];
209+
uint8_t freqHoppingStart; // Frequency hopping start frequency (Unit: 2KHz, 50 means 100KHz )
210+
uint8_t freqHoppingEnd; // Frequency hopping stop frequency (Unit: 2KHz, 150 means 300KHz )
211+
uint8_t noiseDetectTims;
212+
uint8_t hoppingFlag;
213+
uint8_t hoppingThreshold;
214+
215+
uint8_t noiseThreshold;
216+
uint8_t NC_4[2];
217+
// 0x8082
218+
GTFreqHoppingConfig hoppingSegments[5];
219+
// 0x8091
220+
uint8_t NC_5[2];
221+
GTKeyConfig keys;
222+
} __attribute__((packed));
223+
224+
void write(Registers reg, uint8_t val) {
225+
write(reg, &val, 1);
226+
}
227+
228+
void write(Registers reg, uint8_t* data, size_t len) {
229+
uint16_t reg_addr = (uint16_t)reg;
230+
size_t d_len = 2 + len;
231+
uint8_t d[d_len];
232+
d[0] = reg_addr >> 8;
233+
d[1] = reg_addr & 0xFF;
234+
memcpy(&d[2], data, len);
235+
write_(address_, d, d_len);
236+
}
237+
238+
uint8_t read(Registers reg) {
239+
uint8_t val = 0x00;
240+
read(reg, &val, 1);
241+
return val;
242+
}
243+
244+
void read(Registers reg, uint8_t* data, size_t len) {
245+
uint16_t reg_addr = (uint16_t)reg;
246+
read_(address_, reg_addr, data, len);
247+
}
248+
249+
read_fn read_;
250+
write_fn write_;
251+
uint8_t address_;
252+
std::atomic<bool> home_button_pressed_{false};
253+
std::atomic<uint8_t> num_touch_points_;
254+
std::atomic<uint16_t> x_;
255+
std::atomic<uint16_t> y_;
256+
espp::Logger logger_;
257+
};

main/Kconfig.projbuild

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ menu "Wireless Debug Display Configuration"
99
bool "ESP32 WROVER KIT V4"
1010
config HARDWARE_BOX
1111
bool "ESP BOX"
12+
config HARDWARE_TDECK
13+
bool "LILYGO T DECK"
1214
endchoice
1315

1416
config DEBUG_SERVER_PORT

0 commit comments

Comments
 (0)