touch screen handler for the microchip AR1020
Embed:
(wiki syntax)
Show/hide line numbers
ar1020.cpp
00001 /* 00002 * mbed AR1020 library 00003 * Copyright (c) 2010 Hendrik Lipka 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a copy 00006 * of this software and associated documentation files (the "Software"), to deal 00007 * in the Software without restriction, including without limitation the rights 00008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 * copies of the Software, and to permit persons to whom the Software is 00010 * furnished to do so, subject to the following conditions: 00011 * 00012 * The above copyright notice and this permission notice shall be included in 00013 * all copies or substantial portions of the Software. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 * THE SOFTWARE. 00022 */ 00023 00024 #include "ar1020.h" 00025 #include "wait_api.h" 00026 00027 AR1020::AR1020(PinName mosi, PinName miso, PinName clk, PinName enable, PinName siq, PinName power) { 00028 _mosi=new DigitalOut(mosi); 00029 _miso=new DigitalIn(miso); 00030 _clk=new DigitalOut(clk); 00031 _clk->write(0); 00032 00033 _enable=new DigitalOut(enable); 00034 _enable->write(1); 00035 _irq=new InterruptIn(siq); 00036 _siq=new DigitalIn(siq); 00037 _x=-1; 00038 _y=-1; 00039 _pen=0; 00040 _oldPen=false; 00041 _led=new DigitalOut(LED1); 00042 _power=new DigitalOut(power); 00043 _power->write(0); 00044 } 00045 00046 AR1020::~AR1020() { 00047 delete _enable; 00048 delete _irq; 00049 } 00050 00051 void AR1020::init() { 00052 bool ok=false; 00053 while (!ok) 00054 { 00055 printf("power on AR1020\n"); 00056 _power->write(0); 00057 wait_ms(400); 00058 _power->write(1); 00059 wait_ms(200); 00060 int r=cmd(0x13,NULL,0); 00061 printf("disable touch=%i\n",r); 00062 if (0!=r) 00063 continue; 00064 00065 int regStart=cmd(0x22,NULL,0); 00066 printf("reg offset=%i\n",regStart); 00067 00068 if (regStart<0) 00069 continue; 00070 00071 char cid2[4]={0x00,0x0d+regStart,0x01,0x01}; 00072 r=cmd(0x21,cid2,4); 00073 printf("set mode=1 => %i\n",r); 00074 if (0!=r) 00075 continue; 00076 00077 r=cmd(0x23,NULL,0 ); 00078 printf("save regs => %i\n",r); 00079 if (0!=r) 00080 continue; 00081 00082 r=cmd(0x12,NULL,0); 00083 printf("enable touch=%i\n",r); 00084 if (0!=r) 00085 continue; 00086 ok=true; 00087 } 00088 _irq->rise(this, &AR1020::read); 00089 } 00090 00091 int AR1020::x() { 00092 return _x; 00093 } 00094 00095 int AR1020::y() { 00096 return _y; 00097 } 00098 00099 int AR1020::pen () { 00100 return _pen; 00101 } 00102 00103 00104 void AR1020::read() { 00105 while (1==_siq->read()) { 00106 _led->write(1); 00107 _enable->write(0); 00108 wait_us(60); 00109 00110 int pen =readByte(); 00111 wait_us(60); 00112 00113 int xlo=readByte(); 00114 wait_us(60); 00115 00116 int xhi=readByte(); 00117 wait_us(60); 00118 00119 int ylo=readByte(); 00120 wait_us(60); 00121 00122 int yhi=readByte(); 00123 _enable->write(1); 00124 00125 // printf("0x%x|0x%x|0x%x|0x%x|0x%x\n", pen,xlo,xhi,ylo,yhi); 00126 if (0x4d==pen || 0==pen || 255==pen) { 00127 // ignore invalid stuff, do nothing... 00128 } else if (0x81!=pen&0x81) { // pen set? 00129 _pen=0; 00130 int x=xlo+(xhi<<7); 00131 int y=ylo+(yhi<<7); 00132 if (0!=x&&0!=y) { 00133 _x=x; 00134 _y=y; 00135 } 00136 } else { 00137 _pen=1; 00138 int x=xlo+(xhi<<7); 00139 int y=ylo+(yhi<<7); 00140 if (0!=x&&0!=y) { 00141 _x=x; 00142 _y=y; 00143 } 00144 } 00145 _event.x=_x; 00146 _event.y=_y; 00147 _event.pen=_pen; 00148 if (_pen==1 && _oldPen==false) { // pen down 00149 _callbackPD.call((uint32_t)&_event); 00150 } else if (_pen==1 && _oldPen==true) { // pen moved 00151 _callbackPM.call((uint32_t)&_event); 00152 } else if (_pen==0 && _oldPen==true) { // pen up 00153 _callbackPU.call((uint32_t)&_event); 00154 } else { 00155 // happens on the first touch (the first report is send with pen=0). 00156 } 00157 _oldPen=(_pen==1); 00158 _led->write(0); 00159 if (1==_siq->read()) 00160 wait_ms(5); 00161 } 00162 } 00163 00164 int AR1020::cmd(char cmd,char* data, int len, bool doEnable) { 00165 if (doEnable) { 00166 _enable->write(1); 00167 wait_us(1000); 00168 _enable->write(0); 00169 } 00170 00171 wait_us(100); 00172 00173 writeByte(0x55); 00174 wait_us(100); 00175 00176 writeByte(len+1); 00177 wait_us(100); 00178 00179 writeByte(cmd); 00180 wait_us(100); 00181 00182 for (int i=0;i<len;i++) { 00183 writeByte(data[i]); 00184 wait_us(100); 00185 } 00186 Timer t; 00187 t.start(); 00188 while (true) { 00189 wait_us(100); 00190 if (1==_siq->read()) 00191 break; 00192 if (t.read_ms()>1000) 00193 { 00194 printf("timeout\n"); 00195 break; 00196 } 00197 } 00198 char rhead=readByte(); 00199 wait_us(100); 00200 if (rhead!=0x55) { 00201 if (doEnable) 00202 _enable->write(1); 00203 printf("rh=0x%x\n",rhead); 00204 return -1000; 00205 } 00206 char rlen=readByte(); 00207 wait_us(100); 00208 if (rlen==2) { 00209 char r=readByte(); 00210 wait_us(100); 00211 char rc=readByte(); 00212 wait_us(100); 00213 if (doEnable) 00214 _enable->write(1); 00215 if (rc!=cmd) 00216 return -2000; 00217 return -r; 00218 } else if (rlen==3) { 00219 char r=readByte(); 00220 wait_us(100); 00221 char rc=readByte(); 00222 wait_us(100); 00223 if (rc!=cmd) { 00224 if (doEnable) 00225 _enable->write(1); 00226 return -3000; 00227 } 00228 char rd=readByte(); 00229 wait_us(100); 00230 if (doEnable) 00231 _enable->write(1); 00232 if (r==0) 00233 return rd; 00234 return -r; 00235 } else { 00236 if (doEnable) 00237 _enable->write(1); 00238 return -4000; 00239 } 00240 } 00241 void AR1020::calibrate() { 00242 _irq->rise(NULL); 00243 00244 DigitalOut led1(LED1); 00245 DigitalOut led2(LED2); 00246 DigitalOut led3(LED3); 00247 DigitalOut led4(LED4); 00248 led1=0; 00249 led2=0; 00250 led3=1; 00251 led4=1; 00252 00253 int r=cmd(0x13,NULL,0); 00254 printf("disable touch=%i\n",r); 00255 wait_ms(100); 00256 if (r<0) 00257 return; 00258 led4=0; 00259 00260 int regStart=cmd(0x22,NULL,0); 00261 printf("reg offset=%i\n",regStart); 00262 00263 char cid[3]={0x00,0x0d+regStart,0x01}; 00264 int mode=cmd(0x20,cid,3); 00265 printf("mode=%i\n",mode); 00266 00267 if (regStart<0) 00268 return; 00269 printf("start calibrate\n"); 00270 led3=0; 00271 char cid2[4]={0x00,0x0e+regStart,0x01,0x19}; 00272 r=cmd(0x21,cid2,4); 00273 printf("set inset=%i\n",r); 00274 if (r<0) 00275 return; 00276 00277 _enable->write(1); 00278 wait_us(100); 00279 _enable->write(0); 00280 wait_us(10); 00281 char cid3[1]={0x04}; 00282 r=cmd(0x14,cid3,1,false); 00283 printf("start calibration=%i\n",r); 00284 if (r<0) 00285 return; 00286 00287 printf("start OK, press upper left\n"); 00288 led1=1; 00289 int resp=readCalibResponse(); 00290 printf("status=%i\n",resp); 00291 printf("press upper right\n"); 00292 led2=1; 00293 resp=readCalibResponse(); 00294 printf("status=%i\n",resp); 00295 printf("press lower right\n"); 00296 led3=1; 00297 resp=readCalibResponse(); 00298 printf("status=%i\n",resp); 00299 printf("press lower left\n"); 00300 led4=1; 00301 resp=readCalibResponse(); 00302 printf("status=%i\n",resp); 00303 printf("exit calibration mode\n"); 00304 00305 led1=0; 00306 led2=0; 00307 led3=0; 00308 led4=0; 00309 00310 _enable->write(1); 00311 wait_ms(1000); 00312 00313 r=cmd(0x23,NULL,0); 00314 printf("save registers=%i\n",r); 00315 00316 r=cmd(0x12,NULL,0); 00317 printf("enable touch=%i\n",r); 00318 00319 _irq->rise(this, &AR1020::read); 00320 00321 } 00322 00323 int AR1020::readCalibResponse() { 00324 while (true) { 00325 while (true) { 00326 wait_us(10); 00327 if (1==_siq->read()) 00328 break; 00329 } 00330 00331 int r=readByte(); 00332 if (r!=0x55) { 00333 // printf("1=0x%x\n",r); 00334 wait_ms(100); 00335 continue; 00336 } 00337 00338 wait_us(100); 00339 r=readByte(); 00340 if (r!=0x02) { 00341 printf("2=0x%x\n",r); 00342 continue; 00343 } 00344 00345 wait_us(100); 00346 r=readByte(); 00347 if (r!=0x00) { 00348 printf("3=0x%x\n",r); 00349 continue; 00350 } 00351 00352 wait_us(100); 00353 int rc=readByte(); 00354 if (rc!=0x14) { 00355 printf("4=0x%x\n",r); 00356 continue; 00357 } 00358 00359 return r; 00360 } 00361 } 00362 00363 int AR1020::readByte() { 00364 _clk->write(0); 00365 wait_us(10); 00366 int r=0; 00367 for (int i=0;i<8;i++) { 00368 r=r<<1; 00369 _clk->write(1); 00370 wait_us(10); 00371 _clk->write(0); 00372 wait_us(10); 00373 int bit=_miso->read(); 00374 r+=bit; 00375 } 00376 // printf("<-%i\n",r); 00377 return r; 00378 } 00379 00380 void AR1020::writeByte(char byte) { 00381 _clk->write(0); 00382 wait_us(10); 00383 // printf("->0x%x\n",byte); 00384 for (int i=0;i<8;i++) { 00385 int bit=byte>127; 00386 // printf("%i",bit); 00387 _clk->write(1); 00388 wait_us(10); 00389 _mosi->write(bit); 00390 wait_us(10); 00391 _clk->write(0); 00392 wait_us(10); 00393 byte=(char)(byte<<1); 00394 00395 } 00396 // printf("\n"); 00397 }
Generated on Tue Jul 12 2022 18:15:37 by 1.7.2