SensorLib 0.5.0
Multi-platform sensor driver library for Arduino, PlatformIO, and ESP-IDF
Loading...
Searching...
No Matches
TouchDrvGT9895.cpp
Go to the documentation of this file.
1
30#include "../SensorBuildOpt.h"
31#if !SENSORLIB_EXCLUDE_TOUCH_GT9895
32
33#include "TouchDrvGT9895.hpp"
34
36{
37 if (_pinsCfg.irqPin != -1) {
38 hal->pinMode(_pinsCfg.irqPin, OUTPUT);
39 hal->digitalWrite(_pinsCfg.irqPin, LOW);
40 }
41
42 uint8_t sleep_cmd[10] = {0};
43 addrToBeBuf(REG_CMD, sleep_cmd);
44 sleep_cmd[4] = 0x00;
45 sleep_cmd[5] = 0x00;
46 sleep_cmd[6] = 0x04;
47 sleep_cmd[7] = 0x84;
48 sleep_cmd[8] = 0x88;
49 sleep_cmd[9] = 0x00;
50 writeBuff(sleep_cmd, sizeof(sleep_cmd));
51}
52
54{
55 if (_pinsCfg.irqPin != -1) {
56 hal->pinMode(_pinsCfg.irqPin, OUTPUT);
57 hal->digitalWrite(_pinsCfg.irqPin, HIGH);
58 hal->delay(8);
59 }
60 reset();
61}
62
64{
65 uint8_t type = 0;
66 uint8_t write_buffer[4];
67 uint8_t buffer[IRQ_EVENT_HEAD_LEN + MAX_FINGER_NUM * BYTES_PER_POINT + 2] = {0};
68
70
71 // Read the event header (8 bytes) to get the number of fingers.
72 addrToBeBuf(REG_POINT, write_buffer);
73 if (writeThenRead(write_buffer, 4, buffer, IRQ_EVENT_HEAD_LEN) != 0) {
74 return _touchPoints;
75 }
76 // Check if touch event is valid
77 if (buffer[0] == 0x00) {
78 return _touchPoints;
79 }
80 // Check if the number of touch points is valid
81 uint8_t numPoints = buffer[2] & 0x0F;
82 if (numPoints == 0 || numPoints > MAX_FINGER_NUM) {
83 clearStatus();
84 return _touchPoints;
85 }
86 // Read the remaining data from the offset address.
87 uint16_t remaining_len = numPoints * BYTES_PER_POINT + COORDS_DATA_CHECKSUM_SIZE;
89 if (writeThenRead(write_buffer, 4, &buffer[IRQ_EVENT_HEAD_LEN], remaining_len) != 0) {
90 return _touchPoints;
91 }
92
93 if (calculateChecksum(buffer, IRQ_EVENT_HEAD_LEN, CHECKSUM_MODE_U8_LE)) {
94 // If touch data checksum fails
95 clearStatus();
96 return _touchPoints;
97 }
98
99 if (buffer[0] & 0x80) {
100 type = buffer[IRQ_EVENT_HEAD_LEN] & 0x0F;
101 uint16_t checksum_size = (type == POINT_TYPE_STYLUS || type == POINT_TYPE_STYLUS_HOVER) ?
102 (BYTES_PER_POINT * 2 + 2) : (numPoints * BYTES_PER_POINT + 2);
103
104 if (calculateChecksum(&buffer[IRQ_EVENT_HEAD_LEN], checksum_size, CHECKSUM_MODE_U8_LE)) {
105 // If touch data checksum fails
106 clearStatus();
107 return _touchPoints;
108 }
109 // Add touch points
110 for (int i = 0; i < numPoints; i++) {
111 uint8_t offset = IRQ_EVENT_HEAD_LEN + i * BYTES_PER_POINT;
112 uint16_t x = buffer[offset + 2] | (buffer[offset + 3] << 8);
113 uint16_t y = buffer[offset + 4] | (buffer[offset + 5] << 8);
114 uint16_t w = buffer[offset + 6] | (buffer[offset + 7] << 8);
115 uint8_t id = (buffer[offset] >> 4) & 0x0F;
116 _touchPoints.addPoint(x, y, w, id);
117 }
118 // Swap XY or mirroring coordinates,if set
120 }
121
122 clearStatus();
123 return _touchPoints;
124}
125
127{
128 return "GT9895";
129}
130
131int TouchDrvGT9895::calculateChecksum(const uint8_t *data, int size, CheckSumMode mode)
132{
133 uint32_t cal_checksum = 0;
134 uint32_t r_checksum = 0;
135 if (mode == CHECKSUM_MODE_U8_LE) {
136 if (size < 2)
137 return 1;
138 for (int i = 0; i < size - 2; i++)
139 cal_checksum += data[i];
140 r_checksum = data[size - 2] + (data[size - 1] << 8);
141 return (cal_checksum & 0xFFFF) == r_checksum ? 0 : 1;
142 }
143
144 if (size < 4)
145 return 1;
146 for (int i = 0; i < size - 4; i += 2)
147 cal_checksum += data[i] + (data[i + 1] << 8);
148 r_checksum = data[size - 4] + (data[size - 3] << 8) +
149 (data[size - 2] << 16) + (data[size - 1] << 24);
150 return cal_checksum == r_checksum ? 0 : 1;
151}
152
153uint32_t TouchDrvGT9895::getChipPID()
154{
155 struct ChipInfo {
156 uint8_t rom_pid[6];
157 uint8_t rom_vid[3];
158 uint8_t rom_vid_reserved;
159 uint8_t patch_pid[8];
160 uint8_t patch_vid[4];
161 uint8_t patch_vid_reserved;
162 uint8_t sensor_id;
163 uint8_t reserved[2];
164 uint16_t checksum;
165 } info;
166
167 int ret = 0;
168 uint8_t temp_pid[8] = {0};
169 uint8_t buffer[28] = {0};
171 for (int i = 0; i < 2; i++) {
172 if (writeThenRead(buffer, 4, buffer, sizeof(buffer)) == -1) {
173 SENSORLIB_LOG_E("Failed to read firmware version");
174 ret = -1;
175 hal->delay(5);
176 continue;
177 }
178 if (!calculateChecksum(buffer, sizeof(buffer), CHECKSUM_MODE_U8_LE)) {
179 ret = 0;
180 break;
181 }
182 SENSORLIB_LOG_E("Invalid fw version: checksum error!");
183 ret = -1;
184 hal->delay(15);
185 }
186 if (ret == -1) {
187 SENSORLIB_LOG_E("Failed get valid firmware version");
188 return 0;
189 }
190 memcpy(&info, buffer, sizeof(info));
191 memcpy(temp_pid, info.rom_pid, sizeof(info.rom_pid));
192 SENSORLIB_LOG_D("ROM_PID:%s", (const char *)temp_pid);
193 SENSORLIB_LOG_D("ROM_VID:%*p", (int)sizeof(info.rom_vid), info.rom_vid);
194 SENSORLIB_LOG_D("PID:%s", (const char *)info.patch_pid);
195 SENSORLIB_LOG_D("VID:%*p", (int)sizeof(info.patch_vid), info.patch_vid);
196 SENSORLIB_LOG_D("Sensor ID:%d", info.sensor_id);
197 if (info.patch_pid[0] == '9' && info.patch_pid[1] == '8'
198 && info.patch_pid[2] == '9' && info.patch_pid[3] == '5') {
199 return CHIP_PID;
200 }
201 return 0;
202}
203
204void TouchDrvGT9895::clearStatus()
205{
206 uint8_t buffer[5] = { 0x00, 0x01, 0x03, 0x08, 0x00};
207 writeBuff(buffer, 5);
208}
209
210bool TouchDrvGT9895::initImpl(uint8_t)
211{
212 if (getChipPID() != 0x9895) {
213 return false;
214 }
217 return true;
218}
219
220/*
221[ 572][D][TouchDrvGT9895.cpp:236] getChipPID(): ROM_PID:BERLIN
222[ 578][D][TouchDrvGT9895.cpp:237] getChipPID(): ROM_VID:0x4ff3d66a
223[ 584][D][TouchDrvGT9895.cpp:238] getChipPID(): PID:9895
224[ 589][D][TouchDrvGT9895.cpp:239] getChipPID(): VID:0x4ff3d676
225[ 595][D][TouchDrvGT9895.cpp:240] getChipPID(): Sensor ID:255
226*/
227
228#endif
#define SENSORLIB_LOG_E(...)
#define SENSORLIB_LOG_D(...)
void addrToBeBuf(uint32_t addr, uint8_t buf[4])
std::unique_ptr< SensorHal > hal
int writeBuff(uint8_t *buf, size_t len)
int writeThenRead(const uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len)
static constexpr uint8_t IRQ_EVENT_HEAD_LEN
const char * getModelName() override
Get the model name.
void wakeup() override
Wake up the touch driver.
void sleep() override
Puts the touch driver to sleep.
static constexpr uint8_t MAX_FINGER_NUM
static constexpr uint32_t REG_CMD
static constexpr uint8_t BYTES_PER_POINT
const TouchPoints & getTouchPoints() override
Get the touch points.
static constexpr uint8_t POINT_TYPE_STYLUS
static constexpr uint32_t CHIP_PID
static constexpr uint32_t REG_FW_VERSION
static constexpr uint8_t COORDS_DATA_CHECKSUM_SIZE
static constexpr uint32_t REG_POINT
static constexpr uint8_t POINT_TYPE_STYLUS_HOVER
uint32_t _chipID
Chip identification value.
virtual void reset()
Reset the touch controller.
virtual void updateXY(TouchPoints &points) const
Apply coordinate transformations (swap, scale, mirror) to all touch points.
TouchPinsCfg _pinsCfg
Configuration for reset and interrupt pins.
TouchPoints _touchPoints
Touch points data.
uint8_t _maxTouchPoints
Maximum supported touch points.
Container for touch point data and optional gesture information.
bool addPoint(uint16_t x, uint16_t y, uint16_t pressure=0, uint8_t id=0, uint8_t event=0)
Adds a touch point to the container.
void clear()
Clears all stored touch points and gesture.
uint8_t i
int16_t x[5]
int16_t y[5]