KSM edits to RA8875

Dependents:   Liz_Test_Code

Committer:
WiredHome
Date:
Sun Feb 24 19:28:26 2019 +0000
Revision:
166:53fd4a876dac
Parent:
165:695c24cc5197
Child:
168:37a0c4d8791c
Some refactoring, but mostly to improve support for GSL1680 controller to extract the touch id.

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 166:53fd4a876dac 17 /// in 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 166:53fd4a876dac 72 #if 0
WiredHome 165:695c24cc5197 73 // Translate from GSL1680 Event Flag to Touch Code to API-match the
WiredHome 165:695c24cc5197 74 // alternate resistive touch screen driver common in the RA8875
WiredHome 165:695c24cc5197 75 // displays.
WiredHome 165:695c24cc5197 76 static const TouchCode_t GSL1680_EventFlagToTouchCode[4] = {
WiredHome 165:695c24cc5197 77 touch, // 00b Put Down
WiredHome 165:695c24cc5197 78 release, // 01b Put Up
WiredHome 165:695c24cc5197 79 held, // 10b Contact
WiredHome 165:695c24cc5197 80 no_touch // 11b Reserved
WiredHome 165:695c24cc5197 81 };
WiredHome 166:53fd4a876dac 82 #endif
WiredHome 165:695c24cc5197 83
WiredHome 165:695c24cc5197 84 RetCode_t RA8875::GSL1680_Init() {
WiredHome 165:695c24cc5197 85 RetCode_t r = noerror;
WiredHome 165:695c24cc5197 86 uint8_t buf[5] = {0}; // addr + up to 4 Bytes data
WiredHome 165:695c24cc5197 87 unsigned int source_line = 0;
WiredHome 165:695c24cc5197 88 unsigned int source_len;
WiredHome 165:695c24cc5197 89 const struct fw_data *ptr_fw;
WiredHome 165:695c24cc5197 90
WiredHome 165:695c24cc5197 91 // Wake it
WiredHome 165:695c24cc5197 92 m_wake->write(false);
WiredHome 165:695c24cc5197 93 wait_ms(20);
WiredHome 165:695c24cc5197 94 m_wake->write(true);
WiredHome 165:695c24cc5197 95 wait_ms(20);
WiredHome 165:695c24cc5197 96
WiredHome 165:695c24cc5197 97 // Clear reg
WiredHome 165:695c24cc5197 98 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 99 buf[1] = 0x88;
WiredHome 165:695c24cc5197 100 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 101 wait_ms(1);
WiredHome 165:695c24cc5197 102 buf[0] = 0x80;
WiredHome 165:695c24cc5197 103 buf[1] = 0x03;
WiredHome 165:695c24cc5197 104 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 105 wait_ms(1);
WiredHome 165:695c24cc5197 106 buf[0] = 0xe4;
WiredHome 165:695c24cc5197 107 buf[1] = 0x04;
WiredHome 165:695c24cc5197 108 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 109 wait_ms(1);
WiredHome 165:695c24cc5197 110 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 111 buf[1] = 0x00;
WiredHome 165:695c24cc5197 112 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 113 wait_ms(1);
WiredHome 165:695c24cc5197 114
WiredHome 165:695c24cc5197 115 // Reset
WiredHome 165:695c24cc5197 116 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 117 buf[1] = 0x88;
WiredHome 165:695c24cc5197 118 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 119 wait_ms(1);
WiredHome 165:695c24cc5197 120 buf[0] = 0xe4;
WiredHome 165:695c24cc5197 121 buf[1] = 0x04;
WiredHome 165:695c24cc5197 122 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 123 wait_ms(1);
WiredHome 165:695c24cc5197 124 buf[0] = 0xbc;
WiredHome 165:695c24cc5197 125 buf[1] = 0x00;
WiredHome 165:695c24cc5197 126 buf[2] = 0x00;
WiredHome 165:695c24cc5197 127 buf[3] = 0x00;
WiredHome 165:695c24cc5197 128 buf[4] = 0x00;
WiredHome 165:695c24cc5197 129 m_i2c->write(m_addr, (char *)buf, 5);
WiredHome 165:695c24cc5197 130 wait_ms(1);
WiredHome 165:695c24cc5197 131
WiredHome 165:695c24cc5197 132 // Load Firmware
WiredHome 165:695c24cc5197 133 ptr_fw = GSLX680_FW;
WiredHome 165:695c24cc5197 134 source_len = ARRAY_SIZE(GSLX680_FW);
WiredHome 165:695c24cc5197 135 for (source_line = 0; source_line < source_len; source_line++)
WiredHome 165:695c24cc5197 136 {
WiredHome 165:695c24cc5197 137 /* init page trans, set the page val */
WiredHome 165:695c24cc5197 138 if (0xf0 == ptr_fw[source_line].offset)
WiredHome 165:695c24cc5197 139 {
WiredHome 165:695c24cc5197 140 buf[0] = 0xf0;
WiredHome 165:695c24cc5197 141 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff);
WiredHome 165:695c24cc5197 142 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 143 }
WiredHome 165:695c24cc5197 144 else
WiredHome 165:695c24cc5197 145 {
WiredHome 165:695c24cc5197 146 buf[0] = ptr_fw[source_line].offset;
WiredHome 165:695c24cc5197 147 buf[1] = (uint8_t)(ptr_fw[source_line].val & 0x000000ff);
WiredHome 165:695c24cc5197 148 buf[2] = (uint8_t)((ptr_fw[source_line].val & 0x0000ff00) >> 8);
WiredHome 165:695c24cc5197 149 buf[3] = (uint8_t)((ptr_fw[source_line].val & 0x00ff0000) >> 16);
WiredHome 165:695c24cc5197 150 buf[4] = (uint8_t)((ptr_fw[source_line].val & 0xff000000) >> 24);
WiredHome 165:695c24cc5197 151 m_i2c->write(m_addr, (char *)buf, 5);
WiredHome 165:695c24cc5197 152 }
WiredHome 165:695c24cc5197 153 }
WiredHome 165:695c24cc5197 154
WiredHome 165:695c24cc5197 155 // Startup chip
WiredHome 165:695c24cc5197 156 buf[0] = 0xe0;
WiredHome 165:695c24cc5197 157 buf[1] = 0x00;
WiredHome 165:695c24cc5197 158 m_i2c->write(m_addr, (char *)buf, 2);
WiredHome 165:695c24cc5197 159 wait_ms(100);
WiredHome 165:695c24cc5197 160
WiredHome 165:695c24cc5197 161 return r;
WiredHome 165:695c24cc5197 162 }
WiredHome 165:695c24cc5197 163
WiredHome 165:695c24cc5197 164 uint8_t RA8875::GSL1680_ReadRegU8(uint8_t reg, uint8_t * buf, int count) {
WiredHome 165:695c24cc5197 165 uint8_t lbuf[1];
WiredHome 165:695c24cc5197 166
WiredHome 165:695c24cc5197 167 if (buf == NULL) {
WiredHome 165:695c24cc5197 168 buf = lbuf;
WiredHome 165:695c24cc5197 169 count = 1;
WiredHome 165:695c24cc5197 170 }
WiredHome 165:695c24cc5197 171 m_i2c->write(m_addr, (char *)&reg, 1);
WiredHome 165:695c24cc5197 172 m_i2c->read(m_addr, (char *)buf, count);
WiredHome 165:695c24cc5197 173 return buf[0];
WiredHome 165:695c24cc5197 174 }
WiredHome 165:695c24cc5197 175
WiredHome 165:695c24cc5197 176
WiredHome 165:695c24cc5197 177 uint8_t RA8875::GSL1680_TouchPositions(void) {
WiredHome 166:53fd4a876dac 178 uint16_t fingerAndY, AndX;
WiredHome 166:53fd4a876dac 179
WiredHome 166:53fd4a876dac 180 // [80] = # touch points
WiredHome 166:53fd4a876dac 181 // [81] not used
WiredHome 166:53fd4a876dac 182 // [82] not used
WiredHome 166:53fd4a876dac 183 // [83] not used
WiredHome 166:53fd4a876dac 184 // [84] --+ Touch # 1 info
WiredHome 166:53fd4a876dac 185 // [85] |
WiredHome 166:53fd4a876dac 186 // [86] |
WiredHome 166:53fd4a876dac 187 // [87] --+
WiredHome 166:53fd4a876dac 188 // [88] --+ Touch # 2 info
WiredHome 166:53fd4a876dac 189 // [89] |
WiredHome 166:53fd4a876dac 190 // [8A] |
WiredHome 166:53fd4a876dac 191 // [8B] --+
WiredHome 166:53fd4a876dac 192 // ...
WiredHome 166:53fd4a876dac 193 #define TD_SPACE (4 + 4 * GSL1680_TOUCH_POINTS)
WiredHome 165:695c24cc5197 194 if (m_irq->read() == 1) {
WiredHome 166:53fd4a876dac 195 uint8_t touch_data[TD_SPACE];
WiredHome 165:695c24cc5197 196
WiredHome 166:53fd4a876dac 197 GSL1680_ReadRegU8(0x80, touch_data, TD_SPACE);
WiredHome 165:695c24cc5197 198 numberOfTouchPoints = touch_data[0];
WiredHome 165:695c24cc5197 199 gesture = FT5206_GEST_ID_NO_GESTURE; // no gesture support
WiredHome 165:695c24cc5197 200
WiredHome 166:53fd4a876dac 201 int tNdx = GSL1680_TOUCH_POINTS - 1;
WiredHome 166:53fd4a876dac 202 int dNdx = TD_SPACE - 1;
WiredHome 166:53fd4a876dac 203 for ( ; tNdx >= 0; tNdx--, dNdx -= 4) {
WiredHome 166:53fd4a876dac 204 fingerAndY = (uint16_t)(touch_data[dNdx-0])<<8 | (uint16_t)touch_data[dNdx-1];
WiredHome 166:53fd4a876dac 205 AndX = (uint16_t)(touch_data[dNdx-2])<<8 | (uint16_t)touch_data[dNdx-3];
WiredHome 166:53fd4a876dac 206 touchInfo[tNdx].coordinates.y = fingerAndY & 0x0FFF;
WiredHome 166:53fd4a876dac 207 touchInfo[tNdx].coordinates.x = AndX & 0x0FFFF;
WiredHome 166:53fd4a876dac 208 touchInfo[tNdx].touchID = (fingerAndY >> 12);
WiredHome 166:53fd4a876dac 209 touchInfo[tNdx].touchCode = (numberOfTouchPoints > tNdx) ? touch : no_touch;
WiredHome 166:53fd4a876dac 210 }
WiredHome 165:695c24cc5197 211 } else {
WiredHome 165:695c24cc5197 212 numberOfTouchPoints = 0;
WiredHome 165:695c24cc5197 213 }
WiredHome 165:695c24cc5197 214 return numberOfTouchPoints;
WiredHome 165:695c24cc5197 215 }