Library to control a Graphics TFT connected to 4-wire SPI - revised for the Raio RA8875 Display Controller.
Dependents: FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more
Fork of SPI_TFT by
RA8875_Touch_GSL1680.cpp
00001 /// 00002 /// Support for Touch Controller GSL1680 00003 /// 00004 /// Information is quite scarce for the SiLead GSL1680 Capacitive Touch controller. 00005 /// Further, this controller hosts a 32-bit micro, but is without flash memory, so 00006 /// after power-up, the program must be installed into the chip. This is done through 00007 /// the I2C interface. 00008 /// 00009 /// @attention To make it a bit more complicated, I cannot find any source 00010 /// for this micro, only "bytestream", which one has to hope is defect free. 00011 /// 00012 /// @attention To make it even more complicated, I do not have a display with this 00013 /// controller in it, so this body of work is the collective merge of what I've 00014 /// found and interpreted and interface converted to align with this library. 00015 /// 00016 /// @attention It is probably clear that this represents a work in process, and is 00017 /// an attempt to make a working driver. 00018 /// 00019 /// http://linux-sunxi.org/GSL1680 has some useful information, a bit of which 00020 /// is replicated here in case that site changes/disappears. 00021 /// 00022 /// To read from the chip, just write a single byte with the register number to 00023 /// start to read, and then do as many reads as registers to read. 00024 /// 00025 /// The known registers are: 00026 /// * 0x00-0x7F: these registers are used to load portions of the firmware. 00027 /// * 0x80: contains the number of touches in the screen. 00028 /// ** If zero, the user isn't touching the screen; 00029 /// ** if one, only one finger is on the screen; 00030 /// ** if two, there are two fingers; and so on. 00031 /// * 0x84-0x87: contains the coordinates for the first touch. 00032 /// * 0x88-0x8B: contains the coordinates for the second touch. 00033 /// * 0x8C-0xAB: contains the coordinates for the third, fourth, and so on 00034 /// ** (up to five in some devices, up to ten in other), touches, 00035 /// in the same format than the previous ones (four bytes for each touch). 00036 /// * 0xE0: STATUS register 00037 /// * 0xE4, 0xBC-0xBF: some kind of control registers. Needed for uploading 00038 /// the firmware and soft resetting the chip 00039 /// (there's not more data available about them). 00040 /// * 0xF0: PAGE register. Contains the memory page number currently mapped 00041 /// in the 0x00-0x7F registers. 00042 /// 00043 /// Touch coordinates format 00044 /// The four bytes of each group of coordinates contains the X and Y values, 00045 /// and also the finger. 00046 /// 00047 /// * The first two bytes contains, in little endian format, 00048 /// ** the X coordinate in the 12 lower bits. 00049 /// * The other two bytes contains, in little endian format, 00050 /// ** the Y coordinate in the 12 lower bits. 00051 /// ** The 4 upper bits in the Y coordinate contains the finger identifier. 00052 /// 00053 /// Example: 00054 /// Let's say that the user touches the screen with one finger. The register 0x80 00055 /// will contain 1, and registers 0x84 to 0x87 will contain the X and Y coordinates, 00056 /// and the finger identifier will be 1. 00057 /// 00058 /// Now the user, without removing the first finger, touches the screen with a second finger. 00059 /// The register 0x80 will contain 2. Registers 0x84 to 0x87 will contain the 00060 /// X and Y coordinates of the first touch and the finger identifier in them will be 1. 00061 /// Registers 0x88 to 0x8B will contain the X and Y coordinates of the second touch 00062 /// and the finger identifier in them will be 2. 00063 /// 00064 /// Now the user removes the first finger, keeping the second one. The register 0x80 00065 /// will contain 1. Registers 0x84 to 0x87 will contain the X and Y coordinates, 00066 /// but the finger identifier will be 2, because that's the finger that remains 00067 /// in the screen. 00068 00069 00070 #include "RA8875.h" 00071 #include "RA8875_Touch_GSL1680_Firmware.h" 00072 00073 //#define DEBUG "RAGL" 00074 // ... 00075 // INFO("Stuff to show %d", var); // new-line is automatically appended 00076 // 00077 #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) 00078 #define INFO(x, ...) std::printf("[INF %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00079 #define WARN(x, ...) std::printf("[WRN %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00080 #define ERR(x, ...) std::printf("[ERR %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00081 static void HexDump(const char * title, const uint8_t * p, int count) 00082 { 00083 int i; 00084 char buf[100] = "0000: "; 00085 00086 if (*title) 00087 INFO("%s", title); 00088 for (i=0; i<count; ) { 00089 sprintf(buf + strlen(buf), "%02X ", *(p+i)); 00090 if ((++i & 0x0F) == 0x00) { 00091 INFO("%s", buf); 00092 if (i < count) 00093 sprintf(buf, "%04X: ", i); 00094 else 00095 buf[0] = '\0'; 00096 } 00097 } 00098 if (strlen(buf)) 00099 INFO("%s", buf); 00100 } 00101 #else 00102 #define INFO(x, ...) 00103 #define WARN(x, ...) 00104 #define ERR(x, ...) 00105 #define HexDump(a, b, c) 00106 #endif 00107 00108 RetCode_t RA8875::GSL1680_Init() { 00109 RetCode_t r = noerror; 00110 uint8_t buf[5] = { 0 }; // addr + up to 4 Bytes data 00111 unsigned int source_line = 0; 00112 unsigned int source_len; 00113 const struct fw_data * ptr_fw; 00114 00115 INFO("GSL1680_Init()"); 00116 // Wake it 00117 m_wake->write(false); 00118 wait_us(20000); 00119 m_wake->write(true); 00120 wait_us(20000); 00121 00122 // Clear reg 00123 buf[0] = 0xe0; 00124 buf[1] = 0x88; 00125 m_i2c->write(m_addr, (char *)buf, 2); 00126 wait_us(1000); 00127 buf[0] = 0x80; 00128 buf[1] = 0x03; 00129 m_i2c->write(m_addr, (char *)buf, 2); 00130 wait_us(1000); 00131 buf[0] = 0xe4; 00132 buf[1] = 0x04; 00133 m_i2c->write(m_addr, (char *)buf, 2); 00134 wait_us(1000); 00135 buf[0] = 0xe0; 00136 buf[1] = 0x00; 00137 m_i2c->write(m_addr, (char *)buf, 2); 00138 wait_us(1000); 00139 00140 // Reset 00141 buf[0] = 0xe0; 00142 buf[1] = 0x88; 00143 m_i2c->write(m_addr, (char *)buf, 2); 00144 wait_us(1000); 00145 buf[0] = 0xe4; 00146 buf[1] = 0x04; 00147 m_i2c->write(m_addr, (char *)buf, 2); 00148 wait_us(1000); 00149 buf[0] = 0xbc; 00150 buf[1] = 0x00; 00151 buf[2] = 0x00; 00152 buf[3] = 0x00; 00153 buf[4] = 0x00; 00154 m_i2c->write(m_addr, (char *)buf, 5); 00155 wait_us(1000); 00156 00157 // Load Firmware 00158 ptr_fw = GSLX680_FW; 00159 source_len = ARRAY_SIZE(GSLX680_FW); 00160 for (source_line = 0; source_line < source_len; source_line++) 00161 00162 { 00163 /* init page trans, set the page val */ 00164 if (0xf0 == ptr_fw[source_line].offset) { 00165 buf[0] = 0xf0; 00166 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff); 00167 INFO("GSL1680 Firmware set page: %02X", buf[1]); 00168 m_i2c->write(m_addr, (char *)buf, 2); 00169 } else { 00170 buf[0] = ptr_fw[source_line].offset; 00171 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff); 00172 buf[2] = (uint8_t)((ptr_fw[source_line].val & 0x0000ff00) >> 8); 00173 buf[3] = (uint8_t)((ptr_fw[source_line].val & 0x00ff0000) >> 16); 00174 buf[4] = (uint8_t)((ptr_fw[source_line].val & 0xff000000) >> 24); 00175 //INFO("GSL1680 Firmware write[%02X] = %08X", ptr_fw[source_line].offset, ptr_fw[source_line].val); 00176 m_i2c->write(m_addr, (char *)buf, 5); 00177 } 00178 } 00179 00180 // Startup chip 00181 buf[0] = 0xe0; 00182 buf[1] = 0x00; 00183 m_i2c->write(m_addr, (char *)buf, 2); 00184 wait_us(100000); 00185 00186 return r; 00187 } 00188 00189 uint8_t RA8875::GSL1680_ReadRegU8(uint8_t reg, uint8_t * buf, int count) { 00190 uint8_t lbuf[1]; 00191 00192 if (buf == NULL) { 00193 buf = lbuf; 00194 count = 1; 00195 } 00196 m_i2c->write(m_addr, (char *)®, 1); 00197 m_i2c->read(m_addr, (char *)buf, count); 00198 return buf[0]; 00199 } 00200 00201 00202 uint8_t RA8875::GSL1680_TouchPositions(void) { 00203 // [80] = # touch points 00204 // [81] not used 00205 // [82] not used 00206 // [83] not used 00207 // [84] --+ Touch # 1 info 00208 // [85] | 00209 // [86] | 00210 // [87] --+ 00211 // [88] --+ Touch # 2 info 00212 // [89] | 00213 // [8A] | 00214 // [8B] --+ 00215 // ... 00216 00217 #define TD_SPACE (4 + 4 * GSL1680_TOUCH_POINTS) 00218 if (m_irq->read() == 0) { 00219 uint8_t touch_data[TD_SPACE]; 00220 00221 GSL1680_ReadRegU8(0x80, touch_data, TD_SPACE); 00222 numberOfTouchPoints = touch_data[0]; 00223 gesture = FT5206_GEST_ID_NO_GESTURE; // no gesture support 00224 00225 INFO("GSL1680 Touch %d points", numberOfTouchPoints); 00226 int tNdx = GSL1680_TOUCH_POINTS - 1; 00227 int dNdx = TD_SPACE - 1; 00228 for (; tNdx >= 0; tNdx--, dNdx -= 4) { 00229 uint16_t fingerAndY, AndX; 00230 fingerAndY = (uint16_t)(touch_data[dNdx - 0]) << 8 | (uint16_t)touch_data[dNdx - 1]; 00231 AndX = (uint16_t)(touch_data[dNdx - 2]) << 8 | (uint16_t)touch_data[dNdx - 3]; 00232 touchInfo[tNdx].coordinates = TranslateOrientation( AndX & 0x0FFFF, fingerAndY & 0x0FFF ); 00233 touchInfo[tNdx].touchID = (fingerAndY >> 12); 00234 touchInfo[tNdx].touchCode = (numberOfTouchPoints > tNdx) ? touch : no_touch; 00235 //INFO(" Code %d, Finger %d, xy (%4d,%4d)", 00236 // touchInfo[tNdx].touchCode, touchInfo[tNdx].touchID, 00237 // touchInfo[tNdx].coordinates.x, touchInfo[tNdx].coordinates.y); 00238 } 00239 } else { 00240 numberOfTouchPoints = 0; 00241 ERR("GSL1680 Touch - else path, unexpected."); 00242 } 00243 return numberOfTouchPoints; 00244 }
Generated on Tue Jul 12 2022 17:28:36 by 1.7.2