Updated standard library

Committer:
WiredHome
Date:
Sun Jul 28 00:21:15 2019 +0000
Revision:
180:4882e80cfcfe
Parent:
171:f92c0f1f6db4
new constructor for rect_t; much faster thick line drawing; additional debug diagnostics.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 166:53fd4a876dac 1 ///
WiredHome 166:53fd4a876dac 2 /// Support for Touch Controller GSL1680
WiredHome 166:53fd4a876dac 3 ///
WiredHome 166:53fd4a876dac 4 /// Information is quite scarce for the SiLead GSL1680 Capacitive Touch controller.
WiredHome 166:53fd4a876dac 5 /// Further, this controller hosts a 32-bit micro, but is without flash memory, so
WiredHome 166:53fd4a876dac 6 /// after power-up, the program must be installed into the chip. This is done through
WiredHome 166:53fd4a876dac 7 /// the I2C interface.
WiredHome 166:53fd4a876dac 8 ///
WiredHome 166:53fd4a876dac 9 /// @caution To make it a bit more complicated, I cannot find any source
WiredHome 166:53fd4a876dac 10 /// for this micro, only "bytestream", which one has to hope is defect free.
WiredHome 166:53fd4a876dac 11 ///
WiredHome 166:53fd4a876dac 12 /// @caution To make it even more complicated, I do not have a display with this
WiredHome 166:53fd4a876dac 13 /// controller in it, so this body of work is the collective merge of what I've
WiredHome 166:53fd4a876dac 14 /// found and interpreted and interface converted to align with this library.
WiredHome 166:53fd4a876dac 15 ///
WiredHome 166:53fd4a876dac 16 /// @caution It is probably clear that this represents a work in process, and is
WiredHome 170:7e26d51bc48b 17 /// an attempt to make a working driver.
WiredHome 166:53fd4a876dac 18 ///
WiredHome 166:53fd4a876dac 19 /// http://linux-sunxi.org/GSL1680 has some useful information, a bit of which
WiredHome 166:53fd4a876dac 20 /// is replicated here in case that site changes/disappears.
WiredHome 166:53fd4a876dac 21 ///
WiredHome 166:53fd4a876dac 22 /// To read from the chip, just write a single byte with the register number to
WiredHome 166:53fd4a876dac 23 /// start to read, and then do as many reads as registers to read.
WiredHome 166:53fd4a876dac 24 ///
WiredHome 166:53fd4a876dac 25 /// The known registers are:
WiredHome 166:53fd4a876dac 26 /// * 0x00-0x7F: these registers are used to load portions of the firmware.
WiredHome 166:53fd4a876dac 27 /// * 0x80: contains the number of touches in the screen.
WiredHome 166:53fd4a876dac 28 /// ** If zero, the user isn't touching the screen;
WiredHome 166:53fd4a876dac 29 /// ** if one, only one finger is on the screen;
WiredHome 166:53fd4a876dac 30 /// ** if two, there are two fingers; and so on.
WiredHome 166:53fd4a876dac 31 /// * 0x84-0x87: contains the coordinates for the first touch.
WiredHome 166:53fd4a876dac 32 /// * 0x88-0x8B: contains the coordinates for the second touch.
WiredHome 166:53fd4a876dac 33 /// * 0x8C-0xAB: contains the coordinates for the third, fourth, and so on
WiredHome 166:53fd4a876dac 34 /// ** (up to five in some devices, up to ten in other), touches,
WiredHome 166:53fd4a876dac 35 /// in the same format than the previous ones (four bytes for each touch).
WiredHome 166:53fd4a876dac 36 /// * 0xE0: STATUS register
WiredHome 166:53fd4a876dac 37 /// * 0xE4, 0xBC-0xBF: some kind of control registers. Needed for uploading
WiredHome 166:53fd4a876dac 38 /// the firmware and soft resetting the chip
WiredHome 166:53fd4a876dac 39 /// (there's not more data available about them).
WiredHome 166:53fd4a876dac 40 /// * 0xF0: PAGE register. Contains the memory page number currently mapped
WiredHome 166:53fd4a876dac 41 /// in the 0x00-0x7F registers.
WiredHome 166:53fd4a876dac 42 ///
WiredHome 166:53fd4a876dac 43 /// Touch coordinates format
WiredHome 166:53fd4a876dac 44 /// The four bytes of each group of coordinates contains the X and Y values,
WiredHome 166:53fd4a876dac 45 /// and also the finger.
WiredHome 166:53fd4a876dac 46 ///
WiredHome 166:53fd4a876dac 47 /// * The first two bytes contains, in little endian format,
WiredHome 166:53fd4a876dac 48 /// ** the X coordinate in the 12 lower bits.
WiredHome 166:53fd4a876dac 49 /// * The other two bytes contains, in little endian format,
WiredHome 166:53fd4a876dac 50 /// ** the Y coordinate in the 12 lower bits.
WiredHome 166:53fd4a876dac 51 /// ** The 4 upper bits in the Y coordinate contains the finger identifier.
WiredHome 166:53fd4a876dac 52 ///
WiredHome 166:53fd4a876dac 53 /// Example:
WiredHome 166:53fd4a876dac 54 /// Let's say that the user touches the screen with one finger. The register 0x80
WiredHome 166:53fd4a876dac 55 /// will contain 1, and registers 0x84 to 0x87 will contain the X and Y coordinates,
WiredHome 166:53fd4a876dac 56 /// and the finger identifier will be 1.
WiredHome 166:53fd4a876dac 57 ///
WiredHome 166:53fd4a876dac 58 /// Now the user, without removing the first finger, touches the screen with a second finger.
WiredHome 166:53fd4a876dac 59 /// The register 0x80 will contain 2. Registers 0x84 to 0x87 will contain the
WiredHome 166:53fd4a876dac 60 /// X and Y coordinates of the first touch and the finger identifier in them will be 1.
WiredHome 166:53fd4a876dac 61 /// Registers 0x88 to 0x8B will contain the X and Y coordinates of the second touch
WiredHome 166:53fd4a876dac 62 /// and the finger identifier in them will be 2.
WiredHome 166:53fd4a876dac 63 ///
WiredHome 166:53fd4a876dac 64 /// Now the user removes the first finger, keeping the second one. The register 0x80
WiredHome 166:53fd4a876dac 65 /// will contain 1. Registers 0x84 to 0x87 will contain the X and Y coordinates,
WiredHome 166:53fd4a876dac 66 /// but the finger identifier will be 2, because that's the finger that remains
WiredHome 166:53fd4a876dac 67 /// in the screen.
WiredHome 165:695c24cc5197 68
WiredHome 165:695c24cc5197 69 #include "RA8875.h"
WiredHome 166:53fd4a876dac 70 #include "RA8875_Touch_GSL1680_Firmware.h"
WiredHome 165:695c24cc5197 71
WiredHome 171:f92c0f1f6db4 72 //#define DEBUG "RAGL"
WiredHome 168:37a0c4d8791c 73 // ...
WiredHome 168:37a0c4d8791c 74 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 168:37a0c4d8791c 75 //
WiredHome 168:37a0c4d8791c 76 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 168:37a0c4d8791c 77 #define INFO(x, ...) std::printf("[INF %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 168:37a0c4d8791c 78 #define WARN(x, ...) std::printf("[WRN %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 168:37a0c4d8791c 79 #define ERR(x, ...) std::printf("[ERR %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 168:37a0c4d8791c 80 static void HexDump(const char * title, const uint8_t * p, int count)
WiredHome 168:37a0c4d8791c 81 {
WiredHome 168:37a0c4d8791c 82 int i;
WiredHome 168:37a0c4d8791c 83 char buf[100] = "0000: ";
WiredHome 168:37a0c4d8791c 84
WiredHome 168:37a0c4d8791c 85 if (*title)
WiredHome 168:37a0c4d8791c 86 INFO("%s", title);
WiredHome 168:37a0c4d8791c 87 for (i=0; i<count; ) {
WiredHome 168:37a0c4d8791c 88 sprintf(buf + strlen(buf), "%02X ", *(p+i));
WiredHome 168:37a0c4d8791c 89 if ((++i & 0x0F) == 0x00) {
WiredHome 168:37a0c4d8791c 90 INFO("%s", buf);
WiredHome 168:37a0c4d8791c 91 if (i < count)
WiredHome 168:37a0c4d8791c 92 sprintf(buf, "%04X: ", i);
WiredHome 168:37a0c4d8791c 93 else
WiredHome 168:37a0c4d8791c 94 buf[0] = '\0';
WiredHome 168:37a0c4d8791c 95 }
WiredHome 168:37a0c4d8791c 96 }
WiredHome 168:37a0c4d8791c 97 if (strlen(buf))
WiredHome 168:37a0c4d8791c 98 INFO("%s", buf);
WiredHome 168:37a0c4d8791c 99 }
WiredHome 168:37a0c4d8791c 100 #else
WiredHome 168:37a0c4d8791c 101 #define INFO(x, ...)
WiredHome 168:37a0c4d8791c 102 #define WARN(x, ...)
WiredHome 168:37a0c4d8791c 103 #define ERR(x, ...)
WiredHome 168:37a0c4d8791c 104 #define HexDump(a, b, c)
WiredHome 168:37a0c4d8791c 105 #endif
WiredHome 168:37a0c4d8791c 106
WiredHome 168:37a0c4d8791c 107
WiredHome 166:53fd4a876dac 108 #if 0
WiredHome 165:695c24cc5197 109 // Translate from GSL1680 Event Flag to Touch Code to API-match the
WiredHome 165:695c24cc5197 110 // alternate resistive touch screen driver common in the RA8875
WiredHome 165:695c24cc5197 111 // displays.
WiredHome 165:695c24cc5197 112 static const TouchCode_t GSL1680_EventFlagToTouchCode[4] = {
WiredHome 165:695c24cc5197 113 touch, // 00b Put Down
WiredHome 165:695c24cc5197 114 release, // 01b Put Up
WiredHome 165:695c24cc5197 115 held, // 10b Contact
WiredHome 165:695c24cc5197 116 no_touch // 11b Reserved
WiredHome 165:695c24cc5197 117 };
WiredHome 166:53fd4a876dac 118 #endif
WiredHome 165:695c24cc5197 119
WiredHome 165:695c24cc5197 120 RetCode_t RA8875::GSL1680_Init() {
WiredHome 165:695c24cc5197 121 RetCode_t r = noerror;
WiredHome 165:695c24cc5197 122 uint8_t buf[5] = {0}; // addr + up to 4 Bytes data
WiredHome 165:695c24cc5197 123 unsigned int source_line = 0;
WiredHome 165:695c24cc5197 124 unsigned int source_len;
WiredHome 165:695c24cc5197 125 const struct fw_data *ptr_fw;
WiredHome 165:695c24cc5197 126
WiredHome 168:37a0c4d8791c 127 INFO("GSL1680_Init()");
WiredHome 165:695c24cc5197 128 // Wake it
WiredHome 165:695c24cc5197 129 m_wake->write(false);
WiredHome 165:695c24cc5197 130 wait_ms(20);
WiredHome 165:695c24cc5197 131 m_wake->write(true);
WiredHome 165:695c24cc5197 132 wait_ms(20);
WiredHome 165:695c24cc5197 133
WiredHome 165:695c24cc5197 134 // Clear reg
WiredHome 165:695c24cc5197 135 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 136 buf[1] = 0x88;
WiredHome 165:695c24cc5197 137 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 138 wait_ms(1);
WiredHome 165:695c24cc5197 139 buf[0] = 0x80;
WiredHome 165:695c24cc5197 140 buf[1] = 0x03;
WiredHome 165:695c24cc5197 141 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 142 wait_ms(1);
WiredHome 165:695c24cc5197 143 buf[0] = 0xe4;
WiredHome 165:695c24cc5197 144 buf[1] = 0x04;
WiredHome 165:695c24cc5197 145 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 146 wait_ms(1);
WiredHome 165:695c24cc5197 147 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 148 buf[1] = 0x00;
WiredHome 165:695c24cc5197 149 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 150 wait_ms(1);
WiredHome 165:695c24cc5197 151
WiredHome 165:695c24cc5197 152 // Reset
WiredHome 165:695c24cc5197 153 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 154 buf[1] = 0x88;
WiredHome 165:695c24cc5197 155 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 156 wait_ms(1);
WiredHome 165:695c24cc5197 157 buf[0] = 0xe4;
WiredHome 165:695c24cc5197 158 buf[1] = 0x04;
WiredHome 165:695c24cc5197 159 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 160 wait_ms(1);
WiredHome 165:695c24cc5197 161 buf[0] = 0xbc;
WiredHome 165:695c24cc5197 162 buf[1] = 0x00;
WiredHome 165:695c24cc5197 163 buf[2] = 0x00;
WiredHome 165:695c24cc5197 164 buf[3] = 0x00;
WiredHome 165:695c24cc5197 165 buf[4] = 0x00;
WiredHome 165:695c24cc5197 166 m_i2c->write(m_addr, (char *)buf, 5);
WiredHome 165:695c24cc5197 167 wait_ms(1);
WiredHome 165:695c24cc5197 168
WiredHome 165:695c24cc5197 169 // Load Firmware
WiredHome 165:695c24cc5197 170 ptr_fw = GSLX680_FW;
WiredHome 165:695c24cc5197 171 source_len = ARRAY_SIZE(GSLX680_FW);
WiredHome 165:695c24cc5197 172 for (source_line = 0; source_line < source_len; source_line++)
WiredHome 165:695c24cc5197 173 {
WiredHome 165:695c24cc5197 174 /* init page trans, set the page val */
WiredHome 165:695c24cc5197 175 if (0xf0 == ptr_fw[source_line].offset)
WiredHome 165:695c24cc5197 176 {
WiredHome 165:695c24cc5197 177 buf[0] = 0xf0;
WiredHome 165:695c24cc5197 178 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff);
WiredHome 168:37a0c4d8791c 179 INFO("GSL1680 Firmware set page: %02X", buf[1]);
WiredHome 165:695c24cc5197 180 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 181 }
WiredHome 165:695c24cc5197 182 else
WiredHome 165:695c24cc5197 183 {
WiredHome 165:695c24cc5197 184 buf[0] = ptr_fw[source_line].offset;
WiredHome 165:695c24cc5197 185 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff);
WiredHome 165:695c24cc5197 186 buf[2] = (uint8_t)((ptr_fw[source_line].val & 0x0000ff00) >> 8);
WiredHome 165:695c24cc5197 187 buf[3] = (uint8_t)((ptr_fw[source_line].val & 0x00ff0000) >> 16);
WiredHome 165:695c24cc5197 188 buf[4] = (uint8_t)((ptr_fw[source_line].val & 0xff000000) >> 24);
WiredHome 168:37a0c4d8791c 189 //INFO("GSL1680 Firmware write[%02X] = %08X", ptr_fw[source_line].offset, ptr_fw[source_line].val);
WiredHome 165:695c24cc5197 190 m_i2c->write(m_addr, (char *)buf, 5);
WiredHome 165:695c24cc5197 191 }
WiredHome 165:695c24cc5197 192 }
WiredHome 165:695c24cc5197 193
WiredHome 165:695c24cc5197 194 // Startup chip
WiredHome 165:695c24cc5197 195 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 196 buf[1] = 0x00;
WiredHome 165:695c24cc5197 197 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 198 wait_ms(100);
WiredHome 165:695c24cc5197 199
WiredHome 165:695c24cc5197 200 return r;
WiredHome 165:695c24cc5197 201 }
WiredHome 165:695c24cc5197 202
WiredHome 165:695c24cc5197 203 uint8_t RA8875::GSL1680_ReadRegU8(uint8_t reg, uint8_t * buf, int count) {
WiredHome 165:695c24cc5197 204 uint8_t lbuf[1];
WiredHome 165:695c24cc5197 205
WiredHome 165:695c24cc5197 206 if (buf == NULL) {
WiredHome 165:695c24cc5197 207 buf = lbuf;
WiredHome 165:695c24cc5197 208 count = 1;
WiredHome 165:695c24cc5197 209 }
WiredHome 165:695c24cc5197 210 m_i2c->write(m_addr, (char *)&reg, 1);
WiredHome 165:695c24cc5197 211 m_i2c->read(m_addr, (char *)buf, count);
WiredHome 165:695c24cc5197 212 return buf[0];
WiredHome 165:695c24cc5197 213 }
WiredHome 165:695c24cc5197 214
WiredHome 165:695c24cc5197 215
WiredHome 165:695c24cc5197 216 uint8_t RA8875::GSL1680_TouchPositions(void) {
WiredHome 166:53fd4a876dac 217 uint16_t fingerAndY, AndX;
WiredHome 166:53fd4a876dac 218
WiredHome 166:53fd4a876dac 219 // [80] = # touch points
WiredHome 166:53fd4a876dac 220 // [81] not used
WiredHome 166:53fd4a876dac 221 // [82] not used
WiredHome 166:53fd4a876dac 222 // [83] not used
WiredHome 166:53fd4a876dac 223 // [84] --+ Touch # 1 info
WiredHome 166:53fd4a876dac 224 // [85] |
WiredHome 166:53fd4a876dac 225 // [86] |
WiredHome 166:53fd4a876dac 226 // [87] --+
WiredHome 166:53fd4a876dac 227 // [88] --+ Touch # 2 info
WiredHome 166:53fd4a876dac 228 // [89] |
WiredHome 166:53fd4a876dac 229 // [8A] |
WiredHome 166:53fd4a876dac 230 // [8B] --+
WiredHome 166:53fd4a876dac 231 // ...
WiredHome 166:53fd4a876dac 232 #define TD_SPACE (4 + 4 * GSL1680_TOUCH_POINTS)
WiredHome 170:7e26d51bc48b 233 if (m_irq->read() == 0) {
WiredHome 166:53fd4a876dac 234 uint8_t touch_data[TD_SPACE];
WiredHome 165:695c24cc5197 235
WiredHome 166:53fd4a876dac 236 GSL1680_ReadRegU8(0x80, touch_data, TD_SPACE);
WiredHome 165:695c24cc5197 237 numberOfTouchPoints = touch_data[0];
WiredHome 165:695c24cc5197 238 gesture = FT5206_GEST_ID_NO_GESTURE; // no gesture support
WiredHome 165:695c24cc5197 239
WiredHome 168:37a0c4d8791c 240 INFO("GSL1680 Touch %d points", numberOfTouchPoints);
WiredHome 166:53fd4a876dac 241 int tNdx = GSL1680_TOUCH_POINTS - 1;
WiredHome 166:53fd4a876dac 242 int dNdx = TD_SPACE - 1;
WiredHome 166:53fd4a876dac 243 for ( ; tNdx >= 0; tNdx--, dNdx -= 4) {
WiredHome 166:53fd4a876dac 244 fingerAndY = (uint16_t)(touch_data[dNdx-0])<<8 | (uint16_t)touch_data[dNdx-1];
WiredHome 166:53fd4a876dac 245 AndX = (uint16_t)(touch_data[dNdx-2])<<8 | (uint16_t)touch_data[dNdx-3];
WiredHome 166:53fd4a876dac 246 touchInfo[tNdx].coordinates.y = fingerAndY & 0x0FFF;
WiredHome 166:53fd4a876dac 247 touchInfo[tNdx].coordinates.x = AndX & 0x0FFFF;
WiredHome 166:53fd4a876dac 248 touchInfo[tNdx].touchID = (fingerAndY >> 12);
WiredHome 168:37a0c4d8791c 249 touchInfo[tNdx].touchCode = (numberOfTouchPoints > tNdx) ? touch : no_touch;
WiredHome 168:37a0c4d8791c 250 //INFO(" Code %d, Finger %d, xy (%4d,%4d)",
WiredHome 168:37a0c4d8791c 251 // touchInfo[tNdx].touchCode, touchInfo[tNdx].touchID,
WiredHome 168:37a0c4d8791c 252 // touchInfo[tNdx].coordinates.x, touchInfo[tNdx].coordinates.y);
WiredHome 166:53fd4a876dac 253 }
WiredHome 165:695c24cc5197 254 } else {
WiredHome 165:695c24cc5197 255 numberOfTouchPoints = 0;
WiredHome 170:7e26d51bc48b 256 ERR("GSL1680 Touch - else path, unexpected.");
WiredHome 165:695c24cc5197 257 }
WiredHome 165:695c24cc5197 258 return numberOfTouchPoints;
WiredHome 165:695c24cc5197 259 }