roo_display
API Documentation for roo_display
Loading...
Searching...
No Matches
touch_gt911.cpp
Go to the documentation of this file.
2
5#include "roo_threads.h"
6#include "roo_threads/thread.h"
7#include "roo_time.h"
8
9namespace roo_display {
10
11namespace {
12
13static constexpr int kAddr1 = 0x5D;
14static constexpr int kAddr2 = 0x14;
15
16static constexpr int kTouchRead = 0x814e;
17static constexpr int kPointBuffer = 0x814f;
18
19TouchPoint ReadPoint(const roo::byte* data) {
20 TouchPoint tp;
21 tp.id = (uint16_t)data[0];
22 tp.x = ((int16_t)data[2] << 8) | (int16_t)data[1];
23 tp.y = ((int16_t)data[4] << 8) | (int16_t)data[3];
24 tp.z = 1024;
25 return tp;
26}
27
28} // namespace
29
34
37 : BasicTouchDevice<5>(Config{.min_sampling_interval_ms = 20,
38 .touch_intertia_ms = 30,
39 .smoothing_factor = 0.0}),
40 addr_(kAddr1),
41 pinIntr_(pinIntr),
42 pinRst_(pinRst),
43 i2c_slave_(i2c, addr_),
44 reset_low_hold_ms_(reset_low_hold_ms),
45 ready_(false) {}
46
48 pinRst_.init();
49 pinRst_.setLow();
50 if (pinIntr_.isDefined()) {
51 pinIntr_.init();
52 pinIntr_.setLow();
53 }
54 i2c_slave_.init();
55 reset();
56}
57
59 if (reset_thread_.joinable()) {
60 return;
61 }
62 ready_ = false;
63 // Initialize the reset asynchronously to avoid blocking the main thread.
64 reset_thread_ = roo::thread([this]() {
65 if (pinIntr_.isDefined()) {
66 pinIntr_.setLow();
67 }
68 pinRst_.setLow();
69 roo::this_thread::sleep_for(roo_time::Millis((reset_low_hold_ms_)));
70 if (pinIntr_.isDefined()) {
71 if (addr_ == kAddr1) {
72 pinIntr_.setLow();
73 } else {
74 pinIntr_.setHigh();
75 }
76 roo::this_thread::sleep_for(roo_time::Millis(1));
77 }
78 pinRst_.setHigh();
79 if (pinIntr_.isDefined()) {
80 roo::this_thread::sleep_for(roo_time::Millis(5));
81 pinIntr_.setLow();
82 }
83 // Note: the programming guide for 911 says that it is at least 50ms until
84 // the interrupts start working, and up to 100 ms before scan starts
85 // clocking.
86 roo::this_thread::sleep_for(roo_time::Millis(100));
87 ready_ = true;
88 });
89}
90
92 if (!ready_) return 0;
93 if (reset_thread_.joinable()) {
94 reset_thread_.join();
95 }
96 roo::byte status;
97 if (!readByte(kTouchRead, status)) {
98 reset();
99 return 0;
100 }
101 bool ready = (status & roo::byte{0x80}) != roo::byte{0};
102 // uint8_t have_key = (status & 0x10) != 0;
103 if (!ready) return 0;
104 int touches = (int)(status & roo::byte{0xF});
105 roo::byte data[7];
106 for (uint8_t i = 0; i < touches; i++) {
107 readBlock(data, kPointBuffer + i * 8, 7);
108 points[i] = ReadPoint(data);
109 }
110 // Clear the 'ready' flag.
111 writeByte(kTouchRead, roo::byte{0});
112 return touches;
113}
114
115bool TouchGt911::readByte(uint16_t reg, roo::byte& result) {
116 roo::byte addr[] = {(roo::byte)(reg >> 8), (roo::byte)(reg & 0xFF)};
117 if (!i2c_slave_.transmit(addr, 2)) return false;
118 return (i2c_slave_.receive(&result, 1) == 1);
119}
120
121void TouchGt911::writeByte(uint16_t reg, roo::byte val) {
122 roo::byte buf[] = {(roo::byte)(reg >> 8), (roo::byte)(reg & 0xFF), val};
123 i2c_slave_.transmit(buf, 3);
124}
125
126void TouchGt911::readBlock(roo::byte* buf, uint16_t reg, uint8_t size) {
127 roo::byte addr[] = {(roo::byte)(reg >> 8), (roo::byte)(reg & 0xFF)};
128 i2c_slave_.transmit(addr, 2);
129 i2c_slave_.receive(buf, size);
130}
131
132} // namespace roo_display
TouchGt911(GpioSetter pinIntr, GpioSetter pinRst, long reset_low_hold_ms=1)
void initTouch() override
Initialize the touch controller.
int readTouch(TouchPoint *point) override
Defines 140 opaque HTML named colors.
A single touch point returned by a touch controller.
Definition device.h:390