mbed code for Farrari board

Dependencies:   DDRO_Farrari mbed

Fork of DDRO_Farrari by Liangzhen Lai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers jtag.cpp Source File

jtag.cpp

00001 #include "jtag.h"
00002 #include "mbed.h"
00003 #include "pinout.h"
00004 #include "mmap.h"
00005 #include "lcd.h"
00006 
00007 using namespace std;
00008 
00009 
00010 
00011 //-----------------------------------------
00012 // Memory
00013 
00014 unsigned int JTAG::memRead(unsigned int baseaddr, unsigned int readdata[], int size, bool check, bool print)
00015 {
00016     unsigned int mismatch = 0;
00017 
00018     writeBanksel(0);
00019     writeAPACC(0x23000052, AP_CSW);
00020 
00021     unsigned int addr = baseaddr;
00022 
00023     int i = 0;
00024     while(i*1024 < size) {
00025         writeAPACC(addr, AP_TAR, false);
00026 
00027         readAPACC(AP_DRW, false, false);
00028         unsigned int j;
00029         for(j=1024*i+1; j<1024*(i+1) && j<size; j++) {
00030             unsigned int word = readAPACC(AP_DRW, false, false);
00031             if(check) {
00032                 if(readdata[j-1] != word) {
00033                     mismatch++;
00034                     if(print) {
00035                         pc.printf("Mismatch line %x, was %x, expected %x\r\n", j-1, word, readdata[j-1]);
00036                     }
00037                 }
00038             }
00039             readdata[j-1] = word;
00040         }
00041         unsigned int word = rdBuff(false);
00042         if(check) {
00043             if(readdata[j-1] != word) {
00044                 mismatch++;
00045                 if(print) {
00046                     pc.printf("Mismatch line %x, was %x, expected %x\r\n", j-1, word, readdata[j-1]);
00047                 }
00048             }
00049         }
00050         readdata[j-1] = word;
00051 
00052         addr = addr + 1024*4;
00053         i++;
00054     }
00055     return mismatch;
00056 }
00057 
00058 void JTAG::memWrite(unsigned int baseaddr, unsigned int writedata[], int size, bool zero)
00059 {
00060     if(zero){
00061        pc.printf("Called with %x, %x\r\n",  baseaddr, size);
00062     }
00063     writeBanksel(0);
00064     writeAPACC(0x23000052, AP_CSW);
00065 
00066     unsigned int addr = baseaddr;
00067 
00068     int i = 0;
00069     while(i*1024 < size) {
00070         writeAPACC(addr, AP_TAR, false);
00071 
00072         for(int j=1024*i; j<1024*(i+1) && j<size; j++) {
00073             if(zero) {
00074                 writeAPACC(0,            AP_DRW, false);
00075             } else {
00076                 writeAPACC(writedata[j], AP_DRW, false);
00077             }
00078         }
00079 
00080         addr = addr + 1024*4;
00081         i++;
00082     }
00083 }
00084 
00085 unsigned int JTAG::readMemory(unsigned int address)
00086 {
00087     writeBanksel(0);
00088     writeAPACC(0x23000052, AP_CSW);
00089     writeAPACC(address, AP_TAR);
00090     return readAPACC(AP_DRW);
00091 }
00092 
00093 void JTAG::writeMemory(unsigned int address, unsigned int value)
00094 {
00095     writeBanksel(0);
00096     writeAPACC(0x23000052, AP_CSW);
00097     writeAPACC(address, AP_TAR);
00098     writeAPACC(value, AP_DRW);
00099     //rdBuff();
00100 }
00101 
00102 int JTAG::loadProgram()
00103 {
00104     unsigned int address;
00105     unsigned int value;
00106     //dual_printf("Halting Core");
00107 
00108     PowerupDAP();
00109 
00110     address = DHCSR_ADDR;
00111     value = DHCSR_DBGKEY | DHCSR_C_HALT | DHCSR_C_DEBUGEN;
00112     writeMemory(address, value);
00113     value = readMemory(address);
00114 
00115     if (! ((value & DHCSR_C_HALT) && (value & DHCSR_C_DEBUGEN)) ) {
00116         pc.printf("cannot halt the core, check DHCSR...\r\n");
00117         return -1;
00118     }
00119 
00120    // dual_printf("Reading Program HEX");
00121    // pc.printf("loading program\r\n");
00122     
00123     FILE *fp = fopen("/local/program.txt", "r");
00124    // pc.printf("Program open\r\n");
00125     if (fp == NULL) {
00126         pc.printf("Error in open /local/program.txt\r\n");
00127         return -1;
00128     }
00129 
00130     // Similar to MemWrite here
00131   //  dual_printf("Load prog in Imem");
00132     writeBanksel(0);
00133     writeAPACC(0x23000052, AP_CSW);
00134     unsigned int addr = 0x10000000;
00135 
00136     while(!feof(fp)) {
00137         writeAPACC(addr, AP_TAR, false);
00138         for(int j=0; j<1024 && !feof(fp); j++) {
00139             unsigned int d;
00140             fscanf(fp, "%X", &d);
00141             writeAPACC(d, AP_DRW, false);
00142         }
00143         addr = addr + 1024*4;
00144     }
00145 
00146    // dual_printf("Check prog in Imem");
00147     unsigned int mismatch = 0;
00148 
00149     writeBanksel(0);
00150     writeAPACC(0x23000052, AP_CSW);
00151     addr = 0x10000000;
00152 
00153     while(!feof(fp)) {
00154         writeAPACC(addr, AP_TAR, false);
00155 
00156         readAPACC(AP_DRW, false, false);
00157         unsigned int j;
00158         for(j=1; j<1024 && !feof(fp); j++) {
00159             unsigned int word = readAPACC(AP_DRW, false, false);
00160             unsigned int d;
00161             fscanf(fp, "%X", &d);
00162             if(d != word) {
00163                 mismatch++;
00164                 pc.printf("Mismatch line %x, was %x, expected %x\r\n", j-1, word, d);
00165             }
00166         }
00167         if(!feof(fp)){
00168             unsigned int word = rdBuff(false);
00169             unsigned int d;
00170             fscanf(fp, "%X", &d);
00171             if(d != word) {
00172                 mismatch++;
00173                 pc.printf("Mismatch line %x, was %x, expected %x\r\n", j-1, word, d);
00174             }
00175         }
00176         addr = addr + 1024*4;
00177     }
00178     if(mismatch) {
00179         dual_printf("Mem Load Failed");
00180         return -1;
00181     }
00182 
00183     fclose(fp);
00184 
00185     //dual_printf("Map Imem to addr 0");
00186     writeMemory(set_imem, 1);
00187     return 0;
00188 }
00189 
00190 // ------------------------------------------------
00191 // DP/AP Config
00192 
00193 unsigned int JTAG::rdBuff(bool set_ir=true)
00194 {
00195     if(set_ir) {
00196         setIR(JTAG_DPACC);
00197     }
00198     return shiftData(0, DP_RDBUFF, READ);
00199 }
00200 
00201 unsigned int JTAG::readDPACC(unsigned char addr, bool set_ir, bool rdthis)
00202 {
00203     if(set_ir) {
00204         setIR(JTAG_DPACC);
00205     }
00206     unsigned int retdata = shiftData(0, addr, READ);
00207     if(rdthis) {
00208         return rdBuff();
00209     } else {
00210         return retdata;
00211     }
00212 }
00213 unsigned int JTAG::readAPACC(unsigned char addr, bool set_ir, bool rdthis)
00214 {
00215     if(set_ir) {
00216         setIR(JTAG_APACC);
00217     }
00218     unsigned int retdata = shiftData(0, addr, READ);
00219     if(rdthis) {
00220         return rdBuff();
00221     } else {
00222         return retdata;
00223     }
00224 }
00225 
00226 void JTAG::writeAPACC(unsigned int data, unsigned char addr, bool set_ir)
00227 {
00228     if(set_ir) {
00229         setIR(JTAG_APACC);
00230     }
00231     shiftData(data, addr, WRITE);
00232 }
00233 
00234 void JTAG::writeDPACC(unsigned int data, unsigned char addr, bool set_ir)
00235 {
00236     if(set_ir) {
00237         setIR(JTAG_DPACC);
00238     }
00239     shiftData(data, addr, WRITE);
00240 }
00241 
00242 void JTAG::writeBanksel(unsigned int banksel, bool set_ir)
00243 {
00244     if(set_ir) {
00245         setIR(JTAG_DPACC);
00246     }
00247     shiftData(banksel << 4, DP_SELECT, WRITE);
00248 }
00249 
00250 void JTAG::DAP_enable(void)
00251 {
00252     setState('r');
00253     leaveState();
00254     // write CTRL to enable DAP
00255 
00256     writeDPACC(0x50000000, DP_CTRLSTAT);
00257     writeDPACC(0x00000000, AP_SELECT);
00258     writeAPACC(0x23000042, AP_CSW);
00259 }
00260 
00261 
00262 void JTAG::PowerupDAP()
00263 {
00264     writeDPACC(0x12345678, DP_SELECT);
00265     int rd = readDPACC(DP_SELECT);
00266     if(rd != 0x12000070) {
00267         pc.printf("DP SELECT %x", rd);
00268         exit(1);
00269     }
00270     writeDPACC(0xedcba987, DP_SELECT);
00271     rd = readDPACC(DP_SELECT);
00272     if(rd != 0xed000080) {
00273         pc.printf("DP SELECT %x", rd);
00274         exit(1);
00275     }
00276     writeDPACC(0x10000000, DP_CTRLSTAT);
00277     rd = readDPACC(DP_CTRLSTAT);//////////////////////////////////////////////////////////////
00278     if(rd != 0x30000000) {
00279         pc.printf("DP CTRL %x", rd);
00280         exit(1);
00281     }
00282     writeDPACC(0x40000000, DP_CTRLSTAT);
00283     rd = readDPACC(DP_CTRLSTAT);
00284     if(rd != 0xc0000000) {
00285         pc.printf("DP CTRL %x", rd);
00286         exit(1);
00287     }
00288     writeDPACC(0x50000000, DP_CTRLSTAT);
00289     rd = readDPACC(DP_CTRLSTAT);
00290     if(rd != 0xf0000000) {
00291         pc.printf("DP CTRL %x", rd);
00292         exit(1);
00293     }
00294     writeBanksel(0xf);
00295     rd = readAPACC(AP_IDR);
00296     if(rd != 0x24770011) {
00297         pc.printf("AP IDR %x", rd);
00298         exit(1);
00299     }
00300    //dual_printf("DAP Activated");
00301 }
00302 
00303 // --------------------------------
00304 // State Manipulation
00305 
00306 void JTAG::setIR(unsigned char A)
00307 {
00308     setState('i');
00309     char one = shiftBits(A, 4);
00310     if(one != 1) {
00311         dual_printf("ERROR: JTAG IR");
00312         pc.printf("Got %x instead of 1\r\n", one);
00313     }
00314     leaveState();
00315 }
00316 
00317 //moves to specified state from IDLE (reset from anywhere)
00318 void JTAG::setState(unsigned char c)
00319 {
00320     switch (c) {
00321         case 'n':
00322             break;
00323         case 'r':
00324             reset();
00325             break;
00326         case 'd':
00327             TMSHigh();
00328             clockTicks(1);
00329             TMSLow();
00330             clockTicks(2);
00331             state = 'd';
00332             break;
00333         case 'i':
00334             TMSHigh();
00335             clockTicks(2);
00336             TMSLow();
00337             clockTicks(2);
00338             state = 'i';
00339             break;
00340         default:
00341             break;
00342     }
00343 }
00344 
00345 //leave from current state to idle state
00346 void JTAG::leaveState(void)
00347 {
00348     switch (state) {
00349         case 'n':
00350             break;
00351         case 'r':
00352             TMSLow();
00353             clockTicks(1);
00354             state = 'n';
00355             break;
00356         case 'i':
00357             TMSHigh();
00358             clockTicks(2);
00359             TMSLow();
00360             clockTicks(1);
00361             state = 'n';
00362             break;
00363         case 'd':
00364             TMSHigh();
00365             clockTicks(2);
00366             TMSLow();
00367             clockTicks(1);
00368             state = 'n';
00369             break;
00370         default:
00371             break;
00372     }
00373 }
00374 
00375 void JTAG::reset(void)
00376 {
00377     TMSHigh();
00378     clockTicks(10);
00379     TMSLow();
00380     state = 'r';
00381     return;
00382 }
00383 
00384 unsigned int JTAG::readID(void)
00385 {
00386     setIR(JTAG_IDCODE);
00387     setState('d');
00388     unsigned int id = shiftBits(0, 32);
00389     leaveState();
00390 
00391     return id;
00392 }
00393 
00394 // --------------------------------------------
00395 // Data Shifting
00396 
00397 unsigned int JTAG::shiftBits(unsigned int data, int n)
00398 {
00399     unsigned int c=0;
00400     clockLow();
00401     int i;
00402     for (i=0; i<n; i++) {
00403         if (TDO) {
00404             c+=(0x1 << i);
00405         }
00406 
00407         clockTicks(1);
00408 
00409         if ( (data & 1)== 0 ) {
00410             DataLow();
00411         } else {
00412             DataHigh();
00413         }
00414         data=data>>1;
00415     }
00416 
00417     return c;
00418 }
00419 
00420 unsigned int JTAG::shiftData(unsigned int data, char addr, bool rw)
00421 {
00422     bool gotwait = true;
00423     while(gotwait) {
00424         gotwait = false;
00425 
00426         setState('d');
00427         // First 3 bits are either OK/FAULT 010, or WAIT 001
00428         int okstat = shiftBits(rw, 1);
00429         okstat |= (shiftBits(addr >> 2, 2) << 1);
00430 
00431         if(okstat == 1) {
00432             wait_indicator = !wait_indicator;
00433             leaveState();
00434             gotwait = true;
00435         } else if(okstat == 2) {
00436             // Got OK/FAULT
00437         } else {
00438             dual_printf("invalid OK Stat");
00439             leaveState();
00440             exit(1);
00441         }
00442     }
00443 
00444     unsigned int retdata = shiftBits(data, 32);
00445     leaveState();
00446     return retdata;
00447 }
00448 
00449 
00450 // ----------------------------------
00451 // Toggle Functions
00452 
00453 void JTAG::DataLow(void)
00454 {
00455     wait_us(delay);
00456     TDI = 0;
00457 }
00458 void JTAG::DataHigh(void)
00459 {
00460     wait_us(delay);
00461     TDI = 1;
00462 }
00463 
00464 void JTAG::clockLow(void)
00465 {
00466     wait_us(delay);
00467     TCK = 0;
00468 }
00469 
00470 void JTAG::clockHigh(void)
00471 {
00472     wait_us(delay);
00473     TCK = 1;
00474 }
00475 
00476 void JTAG::clockTicks(unsigned char c)
00477 {
00478     int i;
00479     clockLow();
00480     for (i=0; i<c; i++) {
00481         clockLow();
00482         clockHigh();
00483     }
00484     clockLow();
00485 }
00486 
00487 void JTAG::TMSHigh(void)
00488 {
00489     wait_us(delay);
00490     TMS = 1;
00491 }
00492 
00493 void JTAG::TMSLow(void)
00494 {
00495     wait_us(delay);
00496     TMS = 0;
00497 }
00498 
00499 // --------------------------------
00500 // Initializing and Config
00501 
00502 JTAG::JTAG()
00503 {
00504     //TDO.mode(PullUp);
00505     delay = 0;
00506     TMS = 0;
00507     TCK = 0;
00508     TDI = 0;
00509     reset();
00510     leaveState();
00511     return;
00512 }
00513 
00514 void JTAG::setJTAGspeed(int speed)
00515 {
00516     delay = 1000/speed;
00517     return;
00518 }