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 Peter Drescher

See Components - RA8875 Based Display

Enhanced touch-screen support - where it previous supported both the Resistive Touch and Capacitive Touch based on the FT5206 Touch Controller, now it also has support for the GSL1680 Touch Controller.

Offline Help Manual (Windows chm)

/media/uploads/WiredHome/ra8875.zip.bin (download, rename to .zip and unzip)

Committer:
WiredHome
Date:
Mon May 25 16:08:50 2020 +0000
Revision:
206:83edda283d90
Parent:
202:a22cbc04f332
Pick up a change in the touch ISR to pick up the final release.

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 197:853d08e2fb53 7 /// the I2C interface.
WiredHome 166:53fd4a876dac 8 ///
WiredHome 182:8832d03a2a29 9 /// @attention 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 197:853d08e2fb53 11 ///
WiredHome 182:8832d03a2a29 12 /// @attention 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 197:853d08e2fb53 16 /// @attention 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 197:853d08e2fb53 22 /// To read from the chip, just write a single byte with the register number to
WiredHome 197:853d08e2fb53 23 /// start to read, and then do as many reads as registers to read.
WiredHome 197:853d08e2fb53 24 ///
WiredHome 197:853d08e2fb53 25 /// The known registers are:
WiredHome 166:53fd4a876dac 26 /// * 0x00-0x7F: these registers are used to load portions of the firmware.
WiredHome 197:853d08e2fb53 27 /// * 0x80: contains the number of touches in the screen.
WiredHome 197:853d08e2fb53 28 /// ** If zero, the user isn't touching the screen;
WiredHome 197:853d08e2fb53 29 /// ** if one, only one finger is on the screen;
WiredHome 197:853d08e2fb53 30 /// ** if two, there are two fingers; and so on.
WiredHome 197:853d08e2fb53 31 /// * 0x84-0x87: contains the coordinates for the first touch.
WiredHome 197:853d08e2fb53 32 /// * 0x88-0x8B: contains the coordinates for the second touch.
WiredHome 197:853d08e2fb53 33 /// * 0x8C-0xAB: contains the coordinates for the third, fourth, and so on
WiredHome 197:853d08e2fb53 34 /// ** (up to five in some devices, up to ten in other), touches,
WiredHome 197:853d08e2fb53 35 /// in the same format than the previous ones (four bytes for each touch).
WiredHome 197:853d08e2fb53 36 /// * 0xE0: STATUS register
WiredHome 197:853d08e2fb53 37 /// * 0xE4, 0xBC-0xBF: some kind of control registers. Needed for uploading
WiredHome 197:853d08e2fb53 38 /// the firmware and soft resetting the chip
WiredHome 197:853d08e2fb53 39 /// (there's not more data available about them).
WiredHome 197:853d08e2fb53 40 /// * 0xF0: PAGE register. Contains the memory page number currently mapped
WiredHome 197:853d08e2fb53 41 /// in the 0x00-0x7F registers.
WiredHome 166:53fd4a876dac 42 ///
WiredHome 166:53fd4a876dac 43 /// Touch coordinates format
WiredHome 197:853d08e2fb53 44 /// The four bytes of each group of coordinates contains the X and Y values,
WiredHome 197:853d08e2fb53 45 /// and also the finger.
WiredHome 197:853d08e2fb53 46 ///
WiredHome 197:853d08e2fb53 47 /// * The first two bytes contains, in little endian format,
WiredHome 197:853d08e2fb53 48 /// ** the X coordinate in the 12 lower bits.
WiredHome 197:853d08e2fb53 49 /// * The other two bytes contains, in little endian format,
WiredHome 197:853d08e2fb53 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 197:853d08e2fb53 52 ///
WiredHome 197:853d08e2fb53 53 /// Example:
WiredHome 197:853d08e2fb53 54 /// Let's say that the user touches the screen with one finger. The register 0x80
WiredHome 197:853d08e2fb53 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 197:853d08e2fb53 57 ///
WiredHome 197:853d08e2fb53 58 /// Now the user, without removing the first finger, touches the screen with a second finger.
WiredHome 197:853d08e2fb53 59 /// The register 0x80 will contain 2. Registers 0x84 to 0x87 will contain the
WiredHome 197:853d08e2fb53 60 /// X and Y coordinates of the first touch and the finger identifier in them will be 1.
WiredHome 197:853d08e2fb53 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 197:853d08e2fb53 63 ///
WiredHome 197:853d08e2fb53 64 /// Now the user removes the first finger, keeping the second one. The register 0x80
WiredHome 197:853d08e2fb53 65 /// will contain 1. Registers 0x84 to 0x87 will contain the X and Y coordinates,
WiredHome 197:853d08e2fb53 66 /// but the finger identifier will be 2, because that's the finger that remains
WiredHome 197:853d08e2fb53 67 /// in the screen.
WiredHome 197:853d08e2fb53 68
WiredHome 165:695c24cc5197 69
WiredHome 165:695c24cc5197 70 #include "RA8875.h"
WiredHome 166:53fd4a876dac 71 #include "RA8875_Touch_GSL1680_Firmware.h"
WiredHome 165:695c24cc5197 72
WiredHome 171:f92c0f1f6db4 73 //#define DEBUG "RAGL"
WiredHome 168:37a0c4d8791c 74 // ...
WiredHome 168:37a0c4d8791c 75 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 168:37a0c4d8791c 76 //
WiredHome 168:37a0c4d8791c 77 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 197:853d08e2fb53 78 #define INFO(x, ...) std::printf("[INF %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 197:853d08e2fb53 79 #define WARN(x, ...) std::printf("[WRN %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 197:853d08e2fb53 80 #define ERR(x, ...) std::printf("[ERR %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 197:853d08e2fb53 81 static void HexDump(const char * title, const uint8_t * p, int count)
WiredHome 197:853d08e2fb53 82 {
WiredHome 168:37a0c4d8791c 83 int i;
WiredHome 168:37a0c4d8791c 84 char buf[100] = "0000: ";
WiredHome 168:37a0c4d8791c 85
WiredHome 168:37a0c4d8791c 86 if (*title)
WiredHome 168:37a0c4d8791c 87 INFO("%s", title);
WiredHome 168:37a0c4d8791c 88 for (i=0; i<count; ) {
WiredHome 168:37a0c4d8791c 89 sprintf(buf + strlen(buf), "%02X ", *(p+i));
WiredHome 168:37a0c4d8791c 90 if ((++i & 0x0F) == 0x00) {
WiredHome 168:37a0c4d8791c 91 INFO("%s", buf);
WiredHome 168:37a0c4d8791c 92 if (i < count)
WiredHome 168:37a0c4d8791c 93 sprintf(buf, "%04X: ", i);
WiredHome 168:37a0c4d8791c 94 else
WiredHome 168:37a0c4d8791c 95 buf[0] = '\0';
WiredHome 168:37a0c4d8791c 96 }
WiredHome 168:37a0c4d8791c 97 }
WiredHome 168:37a0c4d8791c 98 if (strlen(buf))
WiredHome 168:37a0c4d8791c 99 INFO("%s", buf);
WiredHome 168:37a0c4d8791c 100 }
WiredHome 168:37a0c4d8791c 101 #else
WiredHome 168:37a0c4d8791c 102 #define INFO(x, ...)
WiredHome 168:37a0c4d8791c 103 #define WARN(x, ...)
WiredHome 168:37a0c4d8791c 104 #define ERR(x, ...)
WiredHome 168:37a0c4d8791c 105 #define HexDump(a, b, c)
WiredHome 168:37a0c4d8791c 106 #endif
WiredHome 168:37a0c4d8791c 107
WiredHome 165:695c24cc5197 108 RetCode_t RA8875::GSL1680_Init() {
WiredHome 165:695c24cc5197 109 RetCode_t r = noerror;
WiredHome 197:853d08e2fb53 110 uint8_t buf[5] = { 0 }; // addr + up to 4 Bytes data
WiredHome 165:695c24cc5197 111 unsigned int source_line = 0;
WiredHome 165:695c24cc5197 112 unsigned int source_len;
WiredHome 197:853d08e2fb53 113 const struct fw_data * ptr_fw;
WiredHome 165:695c24cc5197 114
WiredHome 168:37a0c4d8791c 115 INFO("GSL1680_Init()");
WiredHome 165:695c24cc5197 116 // Wake it
WiredHome 165:695c24cc5197 117 m_wake->write(false);
WiredHome 197:853d08e2fb53 118 wait_us(20000);
WiredHome 165:695c24cc5197 119 m_wake->write(true);
WiredHome 197:853d08e2fb53 120 wait_us(20000);
WiredHome 197:853d08e2fb53 121
WiredHome 165:695c24cc5197 122 // Clear reg
WiredHome 165:695c24cc5197 123 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 124 buf[1] = 0x88;
WiredHome 165:695c24cc5197 125 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 197:853d08e2fb53 126 wait_us(1000);
WiredHome 165:695c24cc5197 127 buf[0] = 0x80;
WiredHome 165:695c24cc5197 128 buf[1] = 0x03;
WiredHome 165:695c24cc5197 129 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 197:853d08e2fb53 130 wait_us(1000);
WiredHome 165:695c24cc5197 131 buf[0] = 0xe4;
WiredHome 165:695c24cc5197 132 buf[1] = 0x04;
WiredHome 165:695c24cc5197 133 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 197:853d08e2fb53 134 wait_us(1000);
WiredHome 165:695c24cc5197 135 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 136 buf[1] = 0x00;
WiredHome 165:695c24cc5197 137 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 197:853d08e2fb53 138 wait_us(1000);
WiredHome 197:853d08e2fb53 139
WiredHome 165:695c24cc5197 140 // Reset
WiredHome 165:695c24cc5197 141 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 142 buf[1] = 0x88;
WiredHome 165:695c24cc5197 143 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 197:853d08e2fb53 144 wait_us(1000);
WiredHome 165:695c24cc5197 145 buf[0] = 0xe4;
WiredHome 165:695c24cc5197 146 buf[1] = 0x04;
WiredHome 165:695c24cc5197 147 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 197:853d08e2fb53 148 wait_us(1000);
WiredHome 165:695c24cc5197 149 buf[0] = 0xbc;
WiredHome 165:695c24cc5197 150 buf[1] = 0x00;
WiredHome 165:695c24cc5197 151 buf[2] = 0x00;
WiredHome 165:695c24cc5197 152 buf[3] = 0x00;
WiredHome 165:695c24cc5197 153 buf[4] = 0x00;
WiredHome 165:695c24cc5197 154 m_i2c->write(m_addr, (char *)buf, 5);
WiredHome 197:853d08e2fb53 155 wait_us(1000);
WiredHome 197:853d08e2fb53 156
WiredHome 165:695c24cc5197 157 // Load Firmware
WiredHome 165:695c24cc5197 158 ptr_fw = GSLX680_FW;
WiredHome 165:695c24cc5197 159 source_len = ARRAY_SIZE(GSLX680_FW);
WiredHome 197:853d08e2fb53 160 for (source_line = 0; source_line < source_len; source_line++)
WiredHome 193:74f80834d59d 161
WiredHome 165:695c24cc5197 162 {
WiredHome 165:695c24cc5197 163 /* init page trans, set the page val */
WiredHome 193:74f80834d59d 164 if (0xf0 == ptr_fw[source_line].offset) {
WiredHome 165:695c24cc5197 165 buf[0] = 0xf0;
WiredHome 165:695c24cc5197 166 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff);
WiredHome 168:37a0c4d8791c 167 INFO("GSL1680 Firmware set page: %02X", buf[1]);
WiredHome 165:695c24cc5197 168 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 193:74f80834d59d 169 } else {
WiredHome 165:695c24cc5197 170 buf[0] = ptr_fw[source_line].offset;
WiredHome 165:695c24cc5197 171 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff);
WiredHome 165:695c24cc5197 172 buf[2] = (uint8_t)((ptr_fw[source_line].val & 0x0000ff00) >> 8);
WiredHome 165:695c24cc5197 173 buf[3] = (uint8_t)((ptr_fw[source_line].val & 0x00ff0000) >> 16);
WiredHome 165:695c24cc5197 174 buf[4] = (uint8_t)((ptr_fw[source_line].val & 0xff000000) >> 24);
WiredHome 168:37a0c4d8791c 175 //INFO("GSL1680 Firmware write[%02X] = %08X", ptr_fw[source_line].offset, ptr_fw[source_line].val);
WiredHome 165:695c24cc5197 176 m_i2c->write(m_addr, (char *)buf, 5);
WiredHome 165:695c24cc5197 177 }
WiredHome 165:695c24cc5197 178 }
WiredHome 197:853d08e2fb53 179
WiredHome 165:695c24cc5197 180 // Startup chip
WiredHome 165:695c24cc5197 181 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 182 buf[1] = 0x00;
WiredHome 165:695c24cc5197 183 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 197:853d08e2fb53 184 wait_us(100000);
WiredHome 197:853d08e2fb53 185
WiredHome 165:695c24cc5197 186 return r;
WiredHome 165:695c24cc5197 187 }
WiredHome 165:695c24cc5197 188
WiredHome 165:695c24cc5197 189 uint8_t RA8875::GSL1680_ReadRegU8(uint8_t reg, uint8_t * buf, int count) {
WiredHome 165:695c24cc5197 190 uint8_t lbuf[1];
WiredHome 197:853d08e2fb53 191
WiredHome 165:695c24cc5197 192 if (buf == NULL) {
WiredHome 165:695c24cc5197 193 buf = lbuf;
WiredHome 165:695c24cc5197 194 count = 1;
WiredHome 165:695c24cc5197 195 }
WiredHome 165:695c24cc5197 196 m_i2c->write(m_addr, (char *)&reg, 1);
WiredHome 165:695c24cc5197 197 m_i2c->read(m_addr, (char *)buf, count);
WiredHome 165:695c24cc5197 198 return buf[0];
WiredHome 165:695c24cc5197 199 }
WiredHome 165:695c24cc5197 200
WiredHome 165:695c24cc5197 201
WiredHome 165:695c24cc5197 202 uint8_t RA8875::GSL1680_TouchPositions(void) {
WiredHome 166:53fd4a876dac 203 // [80] = # touch points
WiredHome 166:53fd4a876dac 204 // [81] not used
WiredHome 166:53fd4a876dac 205 // [82] not used
WiredHome 166:53fd4a876dac 206 // [83] not used
WiredHome 166:53fd4a876dac 207 // [84] --+ Touch # 1 info
WiredHome 166:53fd4a876dac 208 // [85] |
WiredHome 166:53fd4a876dac 209 // [86] |
WiredHome 166:53fd4a876dac 210 // [87] --+
WiredHome 166:53fd4a876dac 211 // [88] --+ Touch # 2 info
WiredHome 166:53fd4a876dac 212 // [89] |
WiredHome 166:53fd4a876dac 213 // [8A] |
WiredHome 166:53fd4a876dac 214 // [8B] --+
WiredHome 197:853d08e2fb53 215 // ...
WiredHome 193:74f80834d59d 216
WiredHome 197:853d08e2fb53 217 #define TD_SPACE (4 + 4 * GSL1680_TOUCH_POINTS)
WiredHome 170:7e26d51bc48b 218 if (m_irq->read() == 0) {
WiredHome 166:53fd4a876dac 219 uint8_t touch_data[TD_SPACE];
WiredHome 165:695c24cc5197 220
WiredHome 166:53fd4a876dac 221 GSL1680_ReadRegU8(0x80, touch_data, TD_SPACE);
WiredHome 165:695c24cc5197 222 numberOfTouchPoints = touch_data[0];
WiredHome 165:695c24cc5197 223 gesture = FT5206_GEST_ID_NO_GESTURE; // no gesture support
WiredHome 165:695c24cc5197 224
WiredHome 168:37a0c4d8791c 225 INFO("GSL1680 Touch %d points", numberOfTouchPoints);
WiredHome 166:53fd4a876dac 226 int tNdx = GSL1680_TOUCH_POINTS - 1;
WiredHome 166:53fd4a876dac 227 int dNdx = TD_SPACE - 1;
WiredHome 197:853d08e2fb53 228 for (; tNdx >= 0; tNdx--, dNdx -= 4) {
WiredHome 182:8832d03a2a29 229 uint16_t fingerAndY, AndX;
WiredHome 197:853d08e2fb53 230 fingerAndY = (uint16_t)(touch_data[dNdx - 0]) << 8 | (uint16_t)touch_data[dNdx - 1];
WiredHome 197:853d08e2fb53 231 AndX = (uint16_t)(touch_data[dNdx - 2]) << 8 | (uint16_t)touch_data[dNdx - 3];
WiredHome 202:a22cbc04f332 232 touchInfo[tNdx].coordinates = TranslateOrientation( AndX & 0x0FFFF, fingerAndY & 0x0FFF );
WiredHome 166:53fd4a876dac 233 touchInfo[tNdx].touchID = (fingerAndY >> 12);
WiredHome 168:37a0c4d8791c 234 touchInfo[tNdx].touchCode = (numberOfTouchPoints > tNdx) ? touch : no_touch;
WiredHome 168:37a0c4d8791c 235 //INFO(" Code %d, Finger %d, xy (%4d,%4d)",
WiredHome 168:37a0c4d8791c 236 // touchInfo[tNdx].touchCode, touchInfo[tNdx].touchID,
WiredHome 168:37a0c4d8791c 237 // touchInfo[tNdx].coordinates.x, touchInfo[tNdx].coordinates.y);
WiredHome 166:53fd4a876dac 238 }
WiredHome 165:695c24cc5197 239 } else {
WiredHome 165:695c24cc5197 240 numberOfTouchPoints = 0;
WiredHome 170:7e26d51bc48b 241 ERR("GSL1680 Touch - else path, unexpected.");
WiredHome 165:695c24cc5197 242 }
WiredHome 165:695c24cc5197 243 return numberOfTouchPoints;
WiredHome 165:695c24cc5197 244 }