touch screen handler for the microchip AR1020

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ar1020.cpp Source File

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 }