KSM edits to RA8875
Embed:
(wiki syntax)
Show/hide line numbers
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 /// @caution 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 /// @caution 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 /// @caution 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 #include "RA8875.h" 00070 #include "RA8875_Touch_GSL1680_Firmware.h" 00071 00072 //#define DEBUG "RAGL" 00073 // ... 00074 // INFO("Stuff to show %d", var); // new-line is automatically appended 00075 // 00076 #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) 00077 #define INFO(x, ...) std::printf("[INF %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00078 #define WARN(x, ...) std::printf("[WRN %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00079 #define ERR(x, ...) std::printf("[ERR %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00080 static void HexDump(const char * title, const uint8_t * p, int count) 00081 { 00082 int i; 00083 char buf[100] = "0000: "; 00084 00085 if (*title) 00086 INFO("%s", title); 00087 for (i=0; i<count; ) { 00088 sprintf(buf + strlen(buf), "%02X ", *(p+i)); 00089 if ((++i & 0x0F) == 0x00) { 00090 INFO("%s", buf); 00091 if (i < count) 00092 sprintf(buf, "%04X: ", i); 00093 else 00094 buf[0] = '\0'; 00095 } 00096 } 00097 if (strlen(buf)) 00098 INFO("%s", buf); 00099 } 00100 #else 00101 #define INFO(x, ...) 00102 #define WARN(x, ...) 00103 #define ERR(x, ...) 00104 #define HexDump(a, b, c) 00105 #endif 00106 00107 00108 #if 0 00109 // Translate from GSL1680 Event Flag to Touch Code to API-match the 00110 // alternate resistive touch screen driver common in the RA8875 00111 // displays. 00112 static const TouchCode_t GSL1680_EventFlagToTouchCode[4] = { 00113 touch, // 00b Put Down 00114 release, // 01b Put Up 00115 held, // 10b Contact 00116 no_touch // 11b Reserved 00117 }; 00118 #endif 00119 00120 RetCode_t RA8875::GSL1680_Init() { 00121 RetCode_t r = noerror; 00122 uint8_t buf[5] = {0}; // addr + up to 4 Bytes data 00123 unsigned int source_line = 0; 00124 unsigned int source_len; 00125 const struct fw_data *ptr_fw; 00126 00127 INFO("GSL1680_Init()"); 00128 // Wake it 00129 m_wake->write(false); 00130 wait_ms(20); 00131 m_wake->write(true); 00132 wait_ms(20); 00133 00134 // Clear reg 00135 buf[0] = 0xe0; 00136 buf[1] = 0x88; 00137 m_i2c->write(m_addr, (char *)buf, 2); 00138 wait_ms(1); 00139 buf[0] = 0x80; 00140 buf[1] = 0x03; 00141 m_i2c->write(m_addr, (char *)buf, 2); 00142 wait_ms(1); 00143 buf[0] = 0xe4; 00144 buf[1] = 0x04; 00145 m_i2c->write(m_addr, (char *)buf, 2); 00146 wait_ms(1); 00147 buf[0] = 0xe0; 00148 buf[1] = 0x00; 00149 m_i2c->write(m_addr, (char *)buf, 2); 00150 wait_ms(1); 00151 00152 // Reset 00153 buf[0] = 0xe0; 00154 buf[1] = 0x88; 00155 m_i2c->write(m_addr, (char *)buf, 2); 00156 wait_ms(1); 00157 buf[0] = 0xe4; 00158 buf[1] = 0x04; 00159 m_i2c->write(m_addr, (char *)buf, 2); 00160 wait_ms(1); 00161 buf[0] = 0xbc; 00162 buf[1] = 0x00; 00163 buf[2] = 0x00; 00164 buf[3] = 0x00; 00165 buf[4] = 0x00; 00166 m_i2c->write(m_addr, (char *)buf, 5); 00167 wait_ms(1); 00168 00169 // Load Firmware 00170 ptr_fw = GSLX680_FW; 00171 source_len = ARRAY_SIZE(GSLX680_FW); 00172 for (source_line = 0; source_line < source_len; source_line++) 00173 { 00174 /* init page trans, set the page val */ 00175 if (0xf0 == ptr_fw[source_line].offset) 00176 { 00177 buf[0] = 0xf0; 00178 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff); 00179 INFO("GSL1680 Firmware set page: %02X", buf[1]); 00180 m_i2c->write(m_addr, (char *)buf, 2); 00181 } 00182 else 00183 { 00184 buf[0] = ptr_fw[source_line].offset; 00185 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff); 00186 buf[2] = (uint8_t)((ptr_fw[source_line].val & 0x0000ff00) >> 8); 00187 buf[3] = (uint8_t)((ptr_fw[source_line].val & 0x00ff0000) >> 16); 00188 buf[4] = (uint8_t)((ptr_fw[source_line].val & 0xff000000) >> 24); 00189 //INFO("GSL1680 Firmware write[%02X] = %08X", ptr_fw[source_line].offset, ptr_fw[source_line].val); 00190 m_i2c->write(m_addr, (char *)buf, 5); 00191 } 00192 } 00193 00194 // Startup chip 00195 buf[0] = 0xe0; 00196 buf[1] = 0x00; 00197 m_i2c->write(m_addr, (char *)buf, 2); 00198 wait_ms(100); 00199 00200 return r; 00201 } 00202 00203 uint8_t RA8875::GSL1680_ReadRegU8(uint8_t reg, uint8_t * buf, int count) { 00204 uint8_t lbuf[1]; 00205 00206 if (buf == NULL) { 00207 buf = lbuf; 00208 count = 1; 00209 } 00210 m_i2c->write(m_addr, (char *)®, 1); 00211 m_i2c->read(m_addr, (char *)buf, count); 00212 return buf[0]; 00213 } 00214 00215 00216 uint8_t RA8875::GSL1680_TouchPositions(void) { 00217 uint16_t fingerAndY, AndX; 00218 00219 // [80] = # touch points 00220 // [81] not used 00221 // [82] not used 00222 // [83] not used 00223 // [84] --+ Touch # 1 info 00224 // [85] | 00225 // [86] | 00226 // [87] --+ 00227 // [88] --+ Touch # 2 info 00228 // [89] | 00229 // [8A] | 00230 // [8B] --+ 00231 // ... 00232 #define TD_SPACE (4 + 4 * GSL1680_TOUCH_POINTS) 00233 if (m_irq->read() == 0) { 00234 uint8_t touch_data[TD_SPACE]; 00235 00236 GSL1680_ReadRegU8(0x80, touch_data, TD_SPACE); 00237 numberOfTouchPoints = touch_data[0]; 00238 gesture = FT5206_GEST_ID_NO_GESTURE; // no gesture support 00239 00240 INFO("GSL1680 Touch %d points", numberOfTouchPoints); 00241 int tNdx = GSL1680_TOUCH_POINTS - 1; 00242 int dNdx = TD_SPACE - 1; 00243 for ( ; tNdx >= 0; tNdx--, dNdx -= 4) { 00244 fingerAndY = (uint16_t)(touch_data[dNdx-0])<<8 | (uint16_t)touch_data[dNdx-1]; 00245 AndX = (uint16_t)(touch_data[dNdx-2])<<8 | (uint16_t)touch_data[dNdx-3]; 00246 touchInfo[tNdx].coordinates.y = fingerAndY & 0x0FFF; 00247 touchInfo[tNdx].coordinates.x = AndX & 0x0FFFF; 00248 touchInfo[tNdx].touchID = (fingerAndY >> 12); 00249 touchInfo[tNdx].touchCode = (numberOfTouchPoints > tNdx) ? touch : no_touch; 00250 //INFO(" Code %d, Finger %d, xy (%4d,%4d)", 00251 // touchInfo[tNdx].touchCode, touchInfo[tNdx].touchID, 00252 // touchInfo[tNdx].coordinates.x, touchInfo[tNdx].coordinates.y); 00253 } 00254 } else { 00255 numberOfTouchPoints = 0; 00256 ERR("GSL1680 Touch - else path, unexpected."); 00257 } 00258 return numberOfTouchPoints; 00259 }
Generated on Tue Jul 26 2022 07:46:24 by 1.7.2