Graphical demo for the LPC4088 Experiment Base Board with one of the Display Expansion Kits. This program displays how to write text in different fonts.

Dependencies:   EALib mbed

Committer:
embeddedartists
Date:
Thu Jun 25 10:30:15 2015 +0000
Revision:
0:5e5e9ec91fc8
First version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 0:5e5e9ec91fc8 1 /*
embeddedartists 0:5e5e9ec91fc8 2 * Copyright 2013 Embedded Artists AB
embeddedartists 0:5e5e9ec91fc8 3 *
embeddedartists 0:5e5e9ec91fc8 4 * Licensed under the Apache License, Version 2.0 (the "License");
embeddedartists 0:5e5e9ec91fc8 5 * you may not use this file except in compliance with the License.
embeddedartists 0:5e5e9ec91fc8 6 * You may obtain a copy of the License at
embeddedartists 0:5e5e9ec91fc8 7 *
embeddedartists 0:5e5e9ec91fc8 8 * http://www.apache.org/licenses/LICENSE-2.0
embeddedartists 0:5e5e9ec91fc8 9 *
embeddedartists 0:5e5e9ec91fc8 10 * Unless required by applicable law or agreed to in writing, software
embeddedartists 0:5e5e9ec91fc8 11 * distributed under the License is distributed on an "AS IS" BASIS,
embeddedartists 0:5e5e9ec91fc8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
embeddedartists 0:5e5e9ec91fc8 13 * See the License for the specific language governing permissions and
embeddedartists 0:5e5e9ec91fc8 14 * limitations under the License.
embeddedartists 0:5e5e9ec91fc8 15 */
embeddedartists 0:5e5e9ec91fc8 16
embeddedartists 0:5e5e9ec91fc8 17 /******************************************************************************
embeddedartists 0:5e5e9ec91fc8 18 * Includes
embeddedartists 0:5e5e9ec91fc8 19 *****************************************************************************/
embeddedartists 0:5e5e9ec91fc8 20
embeddedartists 0:5e5e9ec91fc8 21 #include "mbed.h"
embeddedartists 0:5e5e9ec91fc8 22 #include "mbed_debug.h"
embeddedartists 0:5e5e9ec91fc8 23
embeddedartists 0:5e5e9ec91fc8 24 #include "AR1021I2C.h"
embeddedartists 0:5e5e9ec91fc8 25
embeddedartists 0:5e5e9ec91fc8 26 /******************************************************************************
embeddedartists 0:5e5e9ec91fc8 27 * Defines and typedefs
embeddedartists 0:5e5e9ec91fc8 28 *****************************************************************************/
embeddedartists 0:5e5e9ec91fc8 29
embeddedartists 0:5e5e9ec91fc8 30 #define AR1021_REG_TOUCH_THRESHOLD (0x02)
embeddedartists 0:5e5e9ec91fc8 31 #define AR1021_REG_SENS_FILTER (0x03)
embeddedartists 0:5e5e9ec91fc8 32 #define AR1021_REG_SAMPLING_FAST (0x04)
embeddedartists 0:5e5e9ec91fc8 33 #define AR1021_REG_SAMPLING_SLOW (0x05)
embeddedartists 0:5e5e9ec91fc8 34 #define AR1021_REG_ACC_FILTER_FAST (0x06)
embeddedartists 0:5e5e9ec91fc8 35 #define AR1021_REG_ACC_FILTER_SLOW (0x07)
embeddedartists 0:5e5e9ec91fc8 36 #define AR1021_REG_SPEED_THRESHOLD (0x08)
embeddedartists 0:5e5e9ec91fc8 37 #define AR1021_REG_SLEEP_DELAY (0x0A)
embeddedartists 0:5e5e9ec91fc8 38 #define AR1021_REG_PEN_UP_DELAY (0x0B)
embeddedartists 0:5e5e9ec91fc8 39 #define AR1021_REG_TOUCH_MODE (0x0C)
embeddedartists 0:5e5e9ec91fc8 40 #define AR1021_REG_TOUCH_OPTIONS (0x0D)
embeddedartists 0:5e5e9ec91fc8 41 #define AR1021_REG_CALIB_INSETS (0x0E)
embeddedartists 0:5e5e9ec91fc8 42 #define AR1021_REG_PEN_STATE_REPORT_DELAY (0x0F)
embeddedartists 0:5e5e9ec91fc8 43 #define AR1021_REG_TOUCH_REPORT_DELAY (0x11)
embeddedartists 0:5e5e9ec91fc8 44
embeddedartists 0:5e5e9ec91fc8 45
embeddedartists 0:5e5e9ec91fc8 46 #define AR1021_CMD_GET_VERSION (0x10)
embeddedartists 0:5e5e9ec91fc8 47 #define AR1021_CMD_ENABLE_TOUCH (0x12)
embeddedartists 0:5e5e9ec91fc8 48 #define AR1021_CMD_DISABLE_TOUCH (0x13)
embeddedartists 0:5e5e9ec91fc8 49 #define AR1021_CMD_CALIBRATE_MODE (0x14)
embeddedartists 0:5e5e9ec91fc8 50 #define AR1021_CMD_REGISTER_READ (0x20)
embeddedartists 0:5e5e9ec91fc8 51 #define AR1021_CMD_REGISTER_WRITE (0x21)
embeddedartists 0:5e5e9ec91fc8 52 #define AR1021_CMD_REGISTER_START_ADDR_REQUEST (0x22)
embeddedartists 0:5e5e9ec91fc8 53 #define AR1021_CMD_REGISTER_WRITE_TO_EEPROM (0x23)
embeddedartists 0:5e5e9ec91fc8 54 #define AR1021_CMD_EEPROM_READ (0x28)
embeddedartists 0:5e5e9ec91fc8 55 #define AR1021_CMD_EEPROM_WRITE (0x29)
embeddedartists 0:5e5e9ec91fc8 56 #define AR1021_CMD_EEPROM_WRITE_TO_REGISTERS (0x2B)
embeddedartists 0:5e5e9ec91fc8 57
embeddedartists 0:5e5e9ec91fc8 58 #define AR1021_RESP_STAT_OK (0x00)
embeddedartists 0:5e5e9ec91fc8 59 #define AR1021_RESP_STAT_CMD_UNREC (0x01)
embeddedartists 0:5e5e9ec91fc8 60 #define AR1021_RESP_STAT_HDR_UNREC (0x03)
embeddedartists 0:5e5e9ec91fc8 61 #define AR1021_RESP_STAT_TIMEOUT (0x04)
embeddedartists 0:5e5e9ec91fc8 62 #define AR1021_RESP_STAT_CANCEL_CALIB (0xFC)
embeddedartists 0:5e5e9ec91fc8 63
embeddedartists 0:5e5e9ec91fc8 64
embeddedartists 0:5e5e9ec91fc8 65 #define AR1021_ERR_NO_HDR (-1000)
embeddedartists 0:5e5e9ec91fc8 66 #define AR1021_ERR_INV_LEN (-1001)
embeddedartists 0:5e5e9ec91fc8 67 #define AR1021_ERR_INV_RESP (-1002)
embeddedartists 0:5e5e9ec91fc8 68 #define AR1021_ERR_INV_RESPLEN (-1003)
embeddedartists 0:5e5e9ec91fc8 69 #define AR1021_ERR_TIMEOUT (-1004)
embeddedartists 0:5e5e9ec91fc8 70
embeddedartists 0:5e5e9ec91fc8 71 // bit 7 is always 1 and bit 0 defines pen up or down
embeddedartists 0:5e5e9ec91fc8 72 #define AR1021_PEN_MASK (0x81)
embeddedartists 0:5e5e9ec91fc8 73
embeddedartists 0:5e5e9ec91fc8 74 #define AR1021_NUM_CALIB_POINTS (4)
embeddedartists 0:5e5e9ec91fc8 75
embeddedartists 0:5e5e9ec91fc8 76 #define AR1021_ADDR (0x4D << 1)
embeddedartists 0:5e5e9ec91fc8 77
embeddedartists 0:5e5e9ec91fc8 78 #define AR1021_TIMEOUT 1000 //how many ms to wait for responce
embeddedartists 0:5e5e9ec91fc8 79 #define AR1021_RETRY 5 //how many times to retry sending command
embeddedartists 0:5e5e9ec91fc8 80
embeddedartists 0:5e5e9ec91fc8 81 #define AR1021_MIN(__a, __b) (((__a)<(__b))?(__a):(__b))
embeddedartists 0:5e5e9ec91fc8 82
embeddedartists 0:5e5e9ec91fc8 83
embeddedartists 0:5e5e9ec91fc8 84 AR1021I2C::AR1021I2C(PinName sda, PinName scl, PinName siq) :
embeddedartists 0:5e5e9ec91fc8 85 _i2c(sda, scl), _siq(siq), _siqIrq(siq)
embeddedartists 0:5e5e9ec91fc8 86 {
embeddedartists 0:5e5e9ec91fc8 87 _i2c.frequency(200000);
embeddedartists 0:5e5e9ec91fc8 88
embeddedartists 0:5e5e9ec91fc8 89 // default calibration inset is 25 -> (25/2 = 12.5%)
embeddedartists 0:5e5e9ec91fc8 90 _inset = 25;
embeddedartists 0:5e5e9ec91fc8 91
embeddedartists 0:5e5e9ec91fc8 92 // make sure _calibPoint has an invalid value to begin with
embeddedartists 0:5e5e9ec91fc8 93 // correct value is set in calibrateStart()
embeddedartists 0:5e5e9ec91fc8 94 _calibPoint = AR1021_NUM_CALIB_POINTS+1;
embeddedartists 0:5e5e9ec91fc8 95
embeddedartists 0:5e5e9ec91fc8 96 _x = 0;
embeddedartists 0:5e5e9ec91fc8 97 _y = 0;
embeddedartists 0:5e5e9ec91fc8 98 _pen = 0;
embeddedartists 0:5e5e9ec91fc8 99
embeddedartists 0:5e5e9ec91fc8 100 _initialized = false;
embeddedartists 0:5e5e9ec91fc8 101 }
embeddedartists 0:5e5e9ec91fc8 102
embeddedartists 0:5e5e9ec91fc8 103
embeddedartists 0:5e5e9ec91fc8 104 bool AR1021I2C::read(touchCoordinate_t &coord) {
embeddedartists 0:5e5e9ec91fc8 105
embeddedartists 0:5e5e9ec91fc8 106 if (!_initialized) return false;
embeddedartists 0:5e5e9ec91fc8 107
embeddedartists 0:5e5e9ec91fc8 108 coord.x = _x * _width/4095;
embeddedartists 0:5e5e9ec91fc8 109 coord.y = _y * _height/4095;
embeddedartists 0:5e5e9ec91fc8 110 coord.z = _pen;
embeddedartists 0:5e5e9ec91fc8 111
embeddedartists 0:5e5e9ec91fc8 112 return true;
embeddedartists 0:5e5e9ec91fc8 113 }
embeddedartists 0:5e5e9ec91fc8 114
embeddedartists 0:5e5e9ec91fc8 115
embeddedartists 0:5e5e9ec91fc8 116 bool AR1021I2C::init(uint16_t width, uint16_t height) {
embeddedartists 0:5e5e9ec91fc8 117 int result = 0;
embeddedartists 0:5e5e9ec91fc8 118 bool ok = false;
embeddedartists 0:5e5e9ec91fc8 119 int attempts = 0;
embeddedartists 0:5e5e9ec91fc8 120
embeddedartists 0:5e5e9ec91fc8 121 _width = width;
embeddedartists 0:5e5e9ec91fc8 122 _height = height;
embeddedartists 0:5e5e9ec91fc8 123
embeddedartists 0:5e5e9ec91fc8 124 while (1) {
embeddedartists 0:5e5e9ec91fc8 125
embeddedartists 0:5e5e9ec91fc8 126 do {
embeddedartists 0:5e5e9ec91fc8 127 // disable touch
embeddedartists 0:5e5e9ec91fc8 128 result = cmd(AR1021_CMD_DISABLE_TOUCH, NULL, 0, NULL, 0);
embeddedartists 0:5e5e9ec91fc8 129 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 130 debug("disable touch failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 131 break;
embeddedartists 0:5e5e9ec91fc8 132 }
embeddedartists 0:5e5e9ec91fc8 133
embeddedartists 0:5e5e9ec91fc8 134 char regOffset = 0;
embeddedartists 0:5e5e9ec91fc8 135 int regOffLen = 1;
embeddedartists 0:5e5e9ec91fc8 136 result = cmd(AR1021_CMD_REGISTER_START_ADDR_REQUEST, NULL, 0,
embeddedartists 0:5e5e9ec91fc8 137 &regOffset, &regOffLen);
embeddedartists 0:5e5e9ec91fc8 138 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 139 debug("register offset request failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 140 break;
embeddedartists 0:5e5e9ec91fc8 141 }
embeddedartists 0:5e5e9ec91fc8 142
embeddedartists 0:5e5e9ec91fc8 143 // enable calibrated coordinates
embeddedartists 0:5e5e9ec91fc8 144 // high, low address, len, value
embeddedartists 0:5e5e9ec91fc8 145 char toptions[4] = {0x00, AR1021_REG_TOUCH_OPTIONS+regOffset, 0x01, 0x01};
embeddedartists 0:5e5e9ec91fc8 146 result = cmd(AR1021_CMD_REGISTER_WRITE, toptions, 4, NULL, 0);
embeddedartists 0:5e5e9ec91fc8 147 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 148 debug("register write request failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 149 break;
embeddedartists 0:5e5e9ec91fc8 150 }
embeddedartists 0:5e5e9ec91fc8 151
embeddedartists 0:5e5e9ec91fc8 152 // save registers to eeprom
embeddedartists 0:5e5e9ec91fc8 153 result = cmd(AR1021_CMD_REGISTER_WRITE_TO_EEPROM, NULL, 0, NULL, 0);
embeddedartists 0:5e5e9ec91fc8 154 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 155 debug("register write to eeprom failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 156 break;
embeddedartists 0:5e5e9ec91fc8 157 }
embeddedartists 0:5e5e9ec91fc8 158
embeddedartists 0:5e5e9ec91fc8 159 // enable touch
embeddedartists 0:5e5e9ec91fc8 160 result = cmd(AR1021_CMD_ENABLE_TOUCH, NULL, 0, NULL, 0);
embeddedartists 0:5e5e9ec91fc8 161 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 162 debug("enable touch failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 163 break;
embeddedartists 0:5e5e9ec91fc8 164 }
embeddedartists 0:5e5e9ec91fc8 165
embeddedartists 0:5e5e9ec91fc8 166 _siqIrq.rise(this, &AR1021I2C::readTouchIrq);
embeddedartists 0:5e5e9ec91fc8 167
embeddedartists 0:5e5e9ec91fc8 168 _initialized = true;
embeddedartists 0:5e5e9ec91fc8 169 ok = true;
embeddedartists 0:5e5e9ec91fc8 170
embeddedartists 0:5e5e9ec91fc8 171 } while(0);
embeddedartists 0:5e5e9ec91fc8 172
embeddedartists 0:5e5e9ec91fc8 173 if (ok) break;
embeddedartists 0:5e5e9ec91fc8 174
embeddedartists 0:5e5e9ec91fc8 175 // try to run the initialize sequence at most 2 times
embeddedartists 0:5e5e9ec91fc8 176 if(++attempts >= 2) break;
embeddedartists 0:5e5e9ec91fc8 177 }
embeddedartists 0:5e5e9ec91fc8 178
embeddedartists 0:5e5e9ec91fc8 179
embeddedartists 0:5e5e9ec91fc8 180 return ok;
embeddedartists 0:5e5e9ec91fc8 181 }
embeddedartists 0:5e5e9ec91fc8 182
embeddedartists 0:5e5e9ec91fc8 183 bool AR1021I2C::calibrateStart() {
embeddedartists 0:5e5e9ec91fc8 184 bool ok = false;
embeddedartists 0:5e5e9ec91fc8 185 int result = 0;
embeddedartists 0:5e5e9ec91fc8 186 int attempts = 0;
embeddedartists 0:5e5e9ec91fc8 187
embeddedartists 0:5e5e9ec91fc8 188 if (!_initialized) return false;
embeddedartists 0:5e5e9ec91fc8 189
embeddedartists 0:5e5e9ec91fc8 190 _siqIrq.rise(NULL);
embeddedartists 0:5e5e9ec91fc8 191
embeddedartists 0:5e5e9ec91fc8 192 while(1) {
embeddedartists 0:5e5e9ec91fc8 193
embeddedartists 0:5e5e9ec91fc8 194 do {
embeddedartists 0:5e5e9ec91fc8 195 // disable touch
embeddedartists 0:5e5e9ec91fc8 196 result = cmd(AR1021_CMD_DISABLE_TOUCH, NULL, 0, NULL, 0);
embeddedartists 0:5e5e9ec91fc8 197 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 198 debug("disable touch failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 199 break;
embeddedartists 0:5e5e9ec91fc8 200 }
embeddedartists 0:5e5e9ec91fc8 201
embeddedartists 0:5e5e9ec91fc8 202 char regOffset = 0;
embeddedartists 0:5e5e9ec91fc8 203 int regOffLen = 1;
embeddedartists 0:5e5e9ec91fc8 204 result = cmd(AR1021_CMD_REGISTER_START_ADDR_REQUEST, NULL, 0,
embeddedartists 0:5e5e9ec91fc8 205 &regOffset, &regOffLen);
embeddedartists 0:5e5e9ec91fc8 206 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 207 debug("register offset request failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 208 break;
embeddedartists 0:5e5e9ec91fc8 209 }
embeddedartists 0:5e5e9ec91fc8 210
embeddedartists 0:5e5e9ec91fc8 211 // set insets
embeddedartists 0:5e5e9ec91fc8 212 // enable calibrated coordinates
embeddedartists 0:5e5e9ec91fc8 213 // high, low address, len, value
embeddedartists 0:5e5e9ec91fc8 214 char insets[4] = {0x00, AR1021_REG_CALIB_INSETS+regOffset, 0x01, _inset};
embeddedartists 0:5e5e9ec91fc8 215 result = cmd(AR1021_CMD_REGISTER_WRITE, insets, 4, NULL, 0);
embeddedartists 0:5e5e9ec91fc8 216 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 217 debug("register write request failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 218 break;
embeddedartists 0:5e5e9ec91fc8 219 }
embeddedartists 0:5e5e9ec91fc8 220
embeddedartists 0:5e5e9ec91fc8 221 // calibration mode
embeddedartists 0:5e5e9ec91fc8 222 char calibType = 4;
embeddedartists 0:5e5e9ec91fc8 223 result = cmd(AR1021_CMD_CALIBRATE_MODE, &calibType, 1, NULL, 0, false);
embeddedartists 0:5e5e9ec91fc8 224 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 225 debug("calibration mode failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 226 break;
embeddedartists 0:5e5e9ec91fc8 227 }
embeddedartists 0:5e5e9ec91fc8 228
embeddedartists 0:5e5e9ec91fc8 229 _calibPoint = 0;
embeddedartists 0:5e5e9ec91fc8 230 ok = true;
embeddedartists 0:5e5e9ec91fc8 231
embeddedartists 0:5e5e9ec91fc8 232 } while(0);
embeddedartists 0:5e5e9ec91fc8 233
embeddedartists 0:5e5e9ec91fc8 234 if (ok) break;
embeddedartists 0:5e5e9ec91fc8 235
embeddedartists 0:5e5e9ec91fc8 236 // try to run the calibrate mode sequence at most 2 times
embeddedartists 0:5e5e9ec91fc8 237 if (++attempts >= 2) break;
embeddedartists 0:5e5e9ec91fc8 238 }
embeddedartists 0:5e5e9ec91fc8 239
embeddedartists 0:5e5e9ec91fc8 240 return ok;
embeddedartists 0:5e5e9ec91fc8 241 }
embeddedartists 0:5e5e9ec91fc8 242
embeddedartists 0:5e5e9ec91fc8 243 bool AR1021I2C::getNextCalibratePoint(uint16_t* x, uint16_t* y) {
embeddedartists 0:5e5e9ec91fc8 244
embeddedartists 0:5e5e9ec91fc8 245 if (!_initialized) return false;
embeddedartists 0:5e5e9ec91fc8 246 if (x == NULL || y == NULL) return false;
embeddedartists 0:5e5e9ec91fc8 247
embeddedartists 0:5e5e9ec91fc8 248 int xInset = (_width * _inset / 100) / 2;
embeddedartists 0:5e5e9ec91fc8 249 int yInset = (_height * _inset / 100) / 2;
embeddedartists 0:5e5e9ec91fc8 250
embeddedartists 0:5e5e9ec91fc8 251 switch(_calibPoint) {
embeddedartists 0:5e5e9ec91fc8 252 case 0:
embeddedartists 0:5e5e9ec91fc8 253 *x = xInset;
embeddedartists 0:5e5e9ec91fc8 254 *y = yInset;
embeddedartists 0:5e5e9ec91fc8 255 break;
embeddedartists 0:5e5e9ec91fc8 256 case 1:
embeddedartists 0:5e5e9ec91fc8 257 *x = _width - xInset;
embeddedartists 0:5e5e9ec91fc8 258 *y = yInset;
embeddedartists 0:5e5e9ec91fc8 259 break;
embeddedartists 0:5e5e9ec91fc8 260 case 2:
embeddedartists 0:5e5e9ec91fc8 261 *x = _width - xInset;
embeddedartists 0:5e5e9ec91fc8 262 *y = _height - yInset;
embeddedartists 0:5e5e9ec91fc8 263 break;
embeddedartists 0:5e5e9ec91fc8 264 case 3:
embeddedartists 0:5e5e9ec91fc8 265 *x = xInset;
embeddedartists 0:5e5e9ec91fc8 266 *y = _height - yInset;
embeddedartists 0:5e5e9ec91fc8 267 break;
embeddedartists 0:5e5e9ec91fc8 268 default:
embeddedartists 0:5e5e9ec91fc8 269 return false;
embeddedartists 0:5e5e9ec91fc8 270 }
embeddedartists 0:5e5e9ec91fc8 271
embeddedartists 0:5e5e9ec91fc8 272 return true;
embeddedartists 0:5e5e9ec91fc8 273 }
embeddedartists 0:5e5e9ec91fc8 274
embeddedartists 0:5e5e9ec91fc8 275 bool AR1021I2C::waitForCalibratePoint(bool* morePoints, uint32_t timeout) {
embeddedartists 0:5e5e9ec91fc8 276 int result = 0;
embeddedartists 0:5e5e9ec91fc8 277 bool ret = false;
embeddedartists 0:5e5e9ec91fc8 278
embeddedartists 0:5e5e9ec91fc8 279 if (!_initialized) return false;
embeddedartists 0:5e5e9ec91fc8 280
embeddedartists 0:5e5e9ec91fc8 281 do {
embeddedartists 0:5e5e9ec91fc8 282 if (morePoints == NULL || _calibPoint >= AR1021_NUM_CALIB_POINTS) {
embeddedartists 0:5e5e9ec91fc8 283 break;
embeddedartists 0:5e5e9ec91fc8 284 }
embeddedartists 0:5e5e9ec91fc8 285
embeddedartists 0:5e5e9ec91fc8 286 // wait for response
embeddedartists 0:5e5e9ec91fc8 287 result = waitForCalibResponse(timeout);
embeddedartists 0:5e5e9ec91fc8 288 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 289 debug("wait for calibration response failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 290 break;
embeddedartists 0:5e5e9ec91fc8 291 }
embeddedartists 0:5e5e9ec91fc8 292
embeddedartists 0:5e5e9ec91fc8 293 _calibPoint++;
embeddedartists 0:5e5e9ec91fc8 294 *morePoints = (_calibPoint < AR1021_NUM_CALIB_POINTS);
embeddedartists 0:5e5e9ec91fc8 295
embeddedartists 0:5e5e9ec91fc8 296
embeddedartists 0:5e5e9ec91fc8 297 // no more points -> enable touch
embeddedartists 0:5e5e9ec91fc8 298 if (!(*morePoints)) {
embeddedartists 0:5e5e9ec91fc8 299
embeddedartists 0:5e5e9ec91fc8 300 // wait for calibration data to be written to eeprom
embeddedartists 0:5e5e9ec91fc8 301 // before enabling touch
embeddedartists 0:5e5e9ec91fc8 302 result = waitForCalibResponse(timeout);
embeddedartists 0:5e5e9ec91fc8 303 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 304 debug("wait for calibration response failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 305 break;
embeddedartists 0:5e5e9ec91fc8 306 }
embeddedartists 0:5e5e9ec91fc8 307
embeddedartists 0:5e5e9ec91fc8 308
embeddedartists 0:5e5e9ec91fc8 309 // clear chip-select since calibration is done;
embeddedartists 0:5e5e9ec91fc8 310 // _cs = 1;
embeddedartists 0:5e5e9ec91fc8 311
embeddedartists 0:5e5e9ec91fc8 312 result = cmd(AR1021_CMD_ENABLE_TOUCH, NULL, 0, NULL, 0);
embeddedartists 0:5e5e9ec91fc8 313 if (result != 0) {
embeddedartists 0:5e5e9ec91fc8 314 debug("enable touch failed (%d)\n", result);
embeddedartists 0:5e5e9ec91fc8 315 break;
embeddedartists 0:5e5e9ec91fc8 316 }
embeddedartists 0:5e5e9ec91fc8 317
embeddedartists 0:5e5e9ec91fc8 318 _siqIrq.rise(this, &AR1021I2C::readTouchIrq);
embeddedartists 0:5e5e9ec91fc8 319 }
embeddedartists 0:5e5e9ec91fc8 320
embeddedartists 0:5e5e9ec91fc8 321 ret = true;
embeddedartists 0:5e5e9ec91fc8 322
embeddedartists 0:5e5e9ec91fc8 323 } while (0);
embeddedartists 0:5e5e9ec91fc8 324
embeddedartists 0:5e5e9ec91fc8 325
embeddedartists 0:5e5e9ec91fc8 326
embeddedartists 0:5e5e9ec91fc8 327 if (!ret) {
embeddedartists 0:5e5e9ec91fc8 328 // make sure to set chip-select off in case of an error
embeddedartists 0:5e5e9ec91fc8 329 // _cs = 1;
embeddedartists 0:5e5e9ec91fc8 330 // calibration must restart if an error occurred
embeddedartists 0:5e5e9ec91fc8 331 _calibPoint = AR1021_NUM_CALIB_POINTS+1;
embeddedartists 0:5e5e9ec91fc8 332 }
embeddedartists 0:5e5e9ec91fc8 333
embeddedartists 0:5e5e9ec91fc8 334
embeddedartists 0:5e5e9ec91fc8 335
embeddedartists 0:5e5e9ec91fc8 336 return ret;
embeddedartists 0:5e5e9ec91fc8 337 }
embeddedartists 0:5e5e9ec91fc8 338
embeddedartists 0:5e5e9ec91fc8 339 int AR1021I2C::cmd(char cmd, char* data, int len, char* respBuf, int* respLen,
embeddedartists 0:5e5e9ec91fc8 340 bool setCsOff) {
embeddedartists 0:5e5e9ec91fc8 341
embeddedartists 0:5e5e9ec91fc8 342 int ret = 0;
embeddedartists 0:5e5e9ec91fc8 343 int readLen = (respLen == NULL) ? 0 : *respLen;
embeddedartists 0:5e5e9ec91fc8 344 for (int attempt = 1; attempt <= AR1021_RETRY; attempt++) {
embeddedartists 0:5e5e9ec91fc8 345 if (attempt > 1) {
embeddedartists 0:5e5e9ec91fc8 346 wait_ms(50);
embeddedartists 0:5e5e9ec91fc8 347 }
embeddedartists 0:5e5e9ec91fc8 348
embeddedartists 0:5e5e9ec91fc8 349 // command request
embeddedartists 0:5e5e9ec91fc8 350 // ---------------
embeddedartists 0:5e5e9ec91fc8 351 // 0x00 0x55 len cmd data
embeddedartists 0:5e5e9ec91fc8 352 // 0x00 = protocol command byte
embeddedartists 0:5e5e9ec91fc8 353 // 0x55 = header
embeddedartists 0:5e5e9ec91fc8 354 // len = data length + cmd (1)
embeddedartists 0:5e5e9ec91fc8 355 // data = data to send
embeddedartists 0:5e5e9ec91fc8 356
embeddedartists 0:5e5e9ec91fc8 357 _i2c.start();
embeddedartists 0:5e5e9ec91fc8 358 _i2c.write(AR1021_ADDR); //send write address
embeddedartists 0:5e5e9ec91fc8 359 _i2c.write(0x00);
embeddedartists 0:5e5e9ec91fc8 360 _i2c.write(0x55); //header
embeddedartists 0:5e5e9ec91fc8 361 _i2c.write(len+1); //message length
embeddedartists 0:5e5e9ec91fc8 362 _i2c.write(cmd);
embeddedartists 0:5e5e9ec91fc8 363 for (int i = 0; i < len; i++) {
embeddedartists 0:5e5e9ec91fc8 364 _i2c.write(data[i]);
embeddedartists 0:5e5e9ec91fc8 365 }
embeddedartists 0:5e5e9ec91fc8 366 wait_us(60);
embeddedartists 0:5e5e9ec91fc8 367 _i2c.stop();
embeddedartists 0:5e5e9ec91fc8 368
embeddedartists 0:5e5e9ec91fc8 369 // wait for response (siq goes high when response is available)
embeddedartists 0:5e5e9ec91fc8 370 Timer t;
embeddedartists 0:5e5e9ec91fc8 371 t.start();
embeddedartists 0:5e5e9ec91fc8 372 while(_siq.read() != 1 && t.read_ms() < AR1021_TIMEOUT);
embeddedartists 0:5e5e9ec91fc8 373
embeddedartists 0:5e5e9ec91fc8 374 if (t.read_ms() < AR1021_TIMEOUT) {
embeddedartists 0:5e5e9ec91fc8 375
embeddedartists 0:5e5e9ec91fc8 376 // command response
embeddedartists 0:5e5e9ec91fc8 377 // ---------------
embeddedartists 0:5e5e9ec91fc8 378 // 0x55 len status cmd data
embeddedartists 0:5e5e9ec91fc8 379 // 0x55 = header
embeddedartists 0:5e5e9ec91fc8 380 // len = number of bytes following the len byte (i.e. including the status&cmd)
embeddedartists 0:5e5e9ec91fc8 381 // status = status
embeddedartists 0:5e5e9ec91fc8 382 // cmd = command ID
embeddedartists 0:5e5e9ec91fc8 383 // data = data to receive
embeddedartists 0:5e5e9ec91fc8 384 _i2c.start();
embeddedartists 0:5e5e9ec91fc8 385 _i2c.write(AR1021_ADDR + 1); //send read address
embeddedartists 0:5e5e9ec91fc8 386 char header = _i2c.read(1); //header should always be 0x55
embeddedartists 0:5e5e9ec91fc8 387 if (header != 0x55) {
embeddedartists 0:5e5e9ec91fc8 388 ret = AR1021_ERR_NO_HDR;
embeddedartists 0:5e5e9ec91fc8 389 continue;
embeddedartists 0:5e5e9ec91fc8 390 }
embeddedartists 0:5e5e9ec91fc8 391 char length = _i2c.read(1); //data length
embeddedartists 0:5e5e9ec91fc8 392 if (length < 2) {
embeddedartists 0:5e5e9ec91fc8 393 ret = AR1021_ERR_INV_LEN; //must have at least status and command bytes
embeddedartists 0:5e5e9ec91fc8 394 continue;
embeddedartists 0:5e5e9ec91fc8 395 }
embeddedartists 0:5e5e9ec91fc8 396 length -= 2;
embeddedartists 0:5e5e9ec91fc8 397 if (length > readLen) {
embeddedartists 0:5e5e9ec91fc8 398 ret = AR1021_ERR_INV_LEN; //supplied buffer is not enough
embeddedartists 0:5e5e9ec91fc8 399 continue;
embeddedartists 0:5e5e9ec91fc8 400 }
embeddedartists 0:5e5e9ec91fc8 401
embeddedartists 0:5e5e9ec91fc8 402 char status = _i2c.read(1); //command status
embeddedartists 0:5e5e9ec91fc8 403 char usedCmd;
embeddedartists 0:5e5e9ec91fc8 404 if (readLen <= 0) {
embeddedartists 0:5e5e9ec91fc8 405 usedCmd = _i2c.read(0); //no data => read command byte + NACK
embeddedartists 0:5e5e9ec91fc8 406 } else {
embeddedartists 0:5e5e9ec91fc8 407 usedCmd = _i2c.read(1); //which command
embeddedartists 0:5e5e9ec91fc8 408
embeddedartists 0:5e5e9ec91fc8 409 //we need to send a NACK on the last read.
embeddedartists 0:5e5e9ec91fc8 410 int i;
embeddedartists 0:5e5e9ec91fc8 411 for (i = 0; i < (length-1); i++) {
embeddedartists 0:5e5e9ec91fc8 412 respBuf[i] = _i2c.read(1);
embeddedartists 0:5e5e9ec91fc8 413 }
embeddedartists 0:5e5e9ec91fc8 414 respBuf[i] = _i2c.read(0); //last returned data byte + NACK
embeddedartists 0:5e5e9ec91fc8 415 }
embeddedartists 0:5e5e9ec91fc8 416 _i2c.stop();
embeddedartists 0:5e5e9ec91fc8 417
embeddedartists 0:5e5e9ec91fc8 418
embeddedartists 0:5e5e9ec91fc8 419 if (status != AR1021_RESP_STAT_OK) {
embeddedartists 0:5e5e9ec91fc8 420 ret = -status;
embeddedartists 0:5e5e9ec91fc8 421 continue;
embeddedartists 0:5e5e9ec91fc8 422 }
embeddedartists 0:5e5e9ec91fc8 423 if (usedCmd != cmd) {
embeddedartists 0:5e5e9ec91fc8 424 ret = AR1021_ERR_INV_RESP;
embeddedartists 0:5e5e9ec91fc8 425 continue;
embeddedartists 0:5e5e9ec91fc8 426 }
embeddedartists 0:5e5e9ec91fc8 427
embeddedartists 0:5e5e9ec91fc8 428 // success
embeddedartists 0:5e5e9ec91fc8 429 ret = 0;
embeddedartists 0:5e5e9ec91fc8 430 break;
embeddedartists 0:5e5e9ec91fc8 431
embeddedartists 0:5e5e9ec91fc8 432 } else {
embeddedartists 0:5e5e9ec91fc8 433 ret = AR1021_ERR_TIMEOUT;
embeddedartists 0:5e5e9ec91fc8 434 continue;
embeddedartists 0:5e5e9ec91fc8 435 }
embeddedartists 0:5e5e9ec91fc8 436 }
embeddedartists 0:5e5e9ec91fc8 437
embeddedartists 0:5e5e9ec91fc8 438 return ret;
embeddedartists 0:5e5e9ec91fc8 439 }
embeddedartists 0:5e5e9ec91fc8 440
embeddedartists 0:5e5e9ec91fc8 441 int AR1021I2C::waitForCalibResponse(uint32_t timeout) {
embeddedartists 0:5e5e9ec91fc8 442 Timer t;
embeddedartists 0:5e5e9ec91fc8 443 int ret = 0;
embeddedartists 0:5e5e9ec91fc8 444
embeddedartists 0:5e5e9ec91fc8 445 t.start();
embeddedartists 0:5e5e9ec91fc8 446
embeddedartists 0:5e5e9ec91fc8 447 // wait for siq
embeddedartists 0:5e5e9ec91fc8 448 while (_siq.read() != 1 &&
embeddedartists 0:5e5e9ec91fc8 449 (timeout == 0 || (uint32_t)t.read_ms() < (int)timeout));
embeddedartists 0:5e5e9ec91fc8 450
embeddedartists 0:5e5e9ec91fc8 451
embeddedartists 0:5e5e9ec91fc8 452 do {
embeddedartists 0:5e5e9ec91fc8 453
embeddedartists 0:5e5e9ec91fc8 454 if (timeout > 0 && (uint32_t)t.read_ms() >= timeout) {
embeddedartists 0:5e5e9ec91fc8 455 ret = AR1021_ERR_TIMEOUT;
embeddedartists 0:5e5e9ec91fc8 456 break;
embeddedartists 0:5e5e9ec91fc8 457 }
embeddedartists 0:5e5e9ec91fc8 458
embeddedartists 0:5e5e9ec91fc8 459 // command response
embeddedartists 0:5e5e9ec91fc8 460 // ---------------
embeddedartists 0:5e5e9ec91fc8 461 // 0x55 len status cmd data
embeddedartists 0:5e5e9ec91fc8 462 // 0x55 = header
embeddedartists 0:5e5e9ec91fc8 463 // len = number of bytes following the len byte (should be 2)
embeddedartists 0:5e5e9ec91fc8 464 // status = status
embeddedartists 0:5e5e9ec91fc8 465 // cmd = command ID
embeddedartists 0:5e5e9ec91fc8 466 _i2c.start();
embeddedartists 0:5e5e9ec91fc8 467 _i2c.write(AR1021_ADDR + 1); //send read address
embeddedartists 0:5e5e9ec91fc8 468 char header = _i2c.read(1); //header should always be 0x55
embeddedartists 0:5e5e9ec91fc8 469 char length = _i2c.read(1); //data length
embeddedartists 0:5e5e9ec91fc8 470
embeddedartists 0:5e5e9ec91fc8 471 if (header != 0x55) {
embeddedartists 0:5e5e9ec91fc8 472 ret = AR1021_ERR_NO_HDR;
embeddedartists 0:5e5e9ec91fc8 473 break;
embeddedartists 0:5e5e9ec91fc8 474 }
embeddedartists 0:5e5e9ec91fc8 475 if (length < 2) {
embeddedartists 0:5e5e9ec91fc8 476 ret = AR1021_ERR_INV_LEN;
embeddedartists 0:5e5e9ec91fc8 477 break;
embeddedartists 0:5e5e9ec91fc8 478 }
embeddedartists 0:5e5e9ec91fc8 479 char status = _i2c.read(1); //status
embeddedartists 0:5e5e9ec91fc8 480 char cmd = _i2c.read(0); //command, should be NACK'ed
embeddedartists 0:5e5e9ec91fc8 481 _i2c.stop();
embeddedartists 0:5e5e9ec91fc8 482 if (status != AR1021_RESP_STAT_OK) {
embeddedartists 0:5e5e9ec91fc8 483 ret = -status;
embeddedartists 0:5e5e9ec91fc8 484 break;
embeddedartists 0:5e5e9ec91fc8 485 }
embeddedartists 0:5e5e9ec91fc8 486 if (cmd != AR1021_CMD_CALIBRATE_MODE) {
embeddedartists 0:5e5e9ec91fc8 487 ret = AR1021_ERR_INV_RESP;
embeddedartists 0:5e5e9ec91fc8 488 break;
embeddedartists 0:5e5e9ec91fc8 489 }
embeddedartists 0:5e5e9ec91fc8 490
embeddedartists 0:5e5e9ec91fc8 491 // success
embeddedartists 0:5e5e9ec91fc8 492 ret = 0;
embeddedartists 0:5e5e9ec91fc8 493
embeddedartists 0:5e5e9ec91fc8 494 } while (0);
embeddedartists 0:5e5e9ec91fc8 495
embeddedartists 0:5e5e9ec91fc8 496 return ret;
embeddedartists 0:5e5e9ec91fc8 497 }
embeddedartists 0:5e5e9ec91fc8 498
embeddedartists 0:5e5e9ec91fc8 499
embeddedartists 0:5e5e9ec91fc8 500 void AR1021I2C::readTouchIrq() {
embeddedartists 0:5e5e9ec91fc8 501 while(_siq.read() == 1) {
embeddedartists 0:5e5e9ec91fc8 502
embeddedartists 0:5e5e9ec91fc8 503 // touch coordinates are sent in a 5-byte data packet
embeddedartists 0:5e5e9ec91fc8 504 _i2c.start();
embeddedartists 0:5e5e9ec91fc8 505 _i2c.write(AR1021_ADDR + 1); //send read address
embeddedartists 0:5e5e9ec91fc8 506 int pen = _i2c.read(1);
embeddedartists 0:5e5e9ec91fc8 507 int xlo = _i2c.read(1);
embeddedartists 0:5e5e9ec91fc8 508 int xhi = _i2c.read(1);
embeddedartists 0:5e5e9ec91fc8 509 int ylo = _i2c.read(1);
embeddedartists 0:5e5e9ec91fc8 510 int yhi = _i2c.read(0);
embeddedartists 0:5e5e9ec91fc8 511 _i2c.stop();
embeddedartists 0:5e5e9ec91fc8 512
embeddedartists 0:5e5e9ec91fc8 513 // pen down
embeddedartists 0:5e5e9ec91fc8 514 if ((pen&AR1021_PEN_MASK) == (1<<7|1<<0)) {
embeddedartists 0:5e5e9ec91fc8 515 _pen = 1;
embeddedartists 0:5e5e9ec91fc8 516 }
embeddedartists 0:5e5e9ec91fc8 517 // pen up
embeddedartists 0:5e5e9ec91fc8 518 else if ((pen&AR1021_PEN_MASK) == (1<<7)){
embeddedartists 0:5e5e9ec91fc8 519 _pen = 0;
embeddedartists 0:5e5e9ec91fc8 520 }
embeddedartists 0:5e5e9ec91fc8 521 // invalid value
embeddedartists 0:5e5e9ec91fc8 522 else {
embeddedartists 0:5e5e9ec91fc8 523 continue;
embeddedartists 0:5e5e9ec91fc8 524 }
embeddedartists 0:5e5e9ec91fc8 525
embeddedartists 0:5e5e9ec91fc8 526 _x = ((xhi<<7)|xlo);
embeddedartists 0:5e5e9ec91fc8 527 _y = ((yhi<<7)|ylo);
embeddedartists 0:5e5e9ec91fc8 528 }
embeddedartists 0:5e5e9ec91fc8 529 }
embeddedartists 0:5e5e9ec91fc8 530
embeddedartists 0:5e5e9ec91fc8 531 bool AR1021I2C::info(int* verHigh, int* verLow, int* resBits, int* type)
embeddedartists 0:5e5e9ec91fc8 532 {
embeddedartists 0:5e5e9ec91fc8 533 char buff[3] = {0,0,0};
embeddedartists 0:5e5e9ec91fc8 534 int read = 3;
embeddedartists 0:5e5e9ec91fc8 535 int res = cmd(AR1021_CMD_GET_VERSION, NULL, 0, buff, &read);
embeddedartists 0:5e5e9ec91fc8 536 if (res == 0) {
embeddedartists 0:5e5e9ec91fc8 537 *verHigh = buff[0];
embeddedartists 0:5e5e9ec91fc8 538 *verLow = buff[1];
embeddedartists 0:5e5e9ec91fc8 539 switch(buff[2] & 3) {
embeddedartists 0:5e5e9ec91fc8 540 case 0:
embeddedartists 0:5e5e9ec91fc8 541 *resBits = 8;
embeddedartists 0:5e5e9ec91fc8 542 break;
embeddedartists 0:5e5e9ec91fc8 543 case 1:
embeddedartists 0:5e5e9ec91fc8 544 *resBits = 10;
embeddedartists 0:5e5e9ec91fc8 545 break;
embeddedartists 0:5e5e9ec91fc8 546 case 2:
embeddedartists 0:5e5e9ec91fc8 547 *resBits = 12;
embeddedartists 0:5e5e9ec91fc8 548 break;
embeddedartists 0:5e5e9ec91fc8 549 case 3:
embeddedartists 0:5e5e9ec91fc8 550 *resBits = 12;
embeddedartists 0:5e5e9ec91fc8 551 break;
embeddedartists 0:5e5e9ec91fc8 552 default:
embeddedartists 0:5e5e9ec91fc8 553 res = 25;
embeddedartists 0:5e5e9ec91fc8 554 printf("Invalid resolution %d\n", buff[2]&3);
embeddedartists 0:5e5e9ec91fc8 555 break;
embeddedartists 0:5e5e9ec91fc8 556 }
embeddedartists 0:5e5e9ec91fc8 557 *type = buff[2]>>2;
embeddedartists 0:5e5e9ec91fc8 558 }
embeddedartists 0:5e5e9ec91fc8 559 return (res == 0);
embeddedartists 0:5e5e9ec91fc8 560 }