X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Fjtag%2Fjtagarm7.c;h=5b5421542793fc2111591f1a811cea595a8fd316;hp=2a1642119736d730d63fbc72d30286bbd10b2dde;hb=00468511c745e7923221cc688e705d28fc5d5e5c;hpb=f7fdc48f01ada713d5034763a2f3395fe2a7c51b diff --git a/firmware/apps/jtag/jtagarm7.c b/firmware/apps/jtag/jtagarm7.c index 2a16421..5b54215 100644 --- a/firmware/apps/jtag/jtagarm7.c +++ b/firmware/apps/jtag/jtagarm7.c @@ -34,6 +34,8 @@ unsigned char last_sysstate = 0; unsigned char last_ir = -1; unsigned char last_scanchain = -1; unsigned char current_dbgstate = -1; +unsigned char g_jtag_ir_size = 4; +unsigned char g_jtagarm_scan_n_bitsize = 4; //unsigned char last_halt_debug_state = -1; //unsigned long last_halt_pc = -1; @@ -44,9 +46,9 @@ GoodFET -> 7TDMI 20-pin connector (HE-10 connector) 3 5 (TDI) 5 7 (TMS) 7 9 (TCK) - 8 15 (nRST) 9 4,6,8,10,12,14,16,18,20 (GND) - 11 17/3 (nTRST) (different sources suggest 17 or 3 alternately) + 11 15 (nRST) + // no longer... (11 17/3 (nTRST) (different sources suggest 17 or 3 alternately)) ********************************/ /**** 14-pin Connection Information (pin1 is on top-right for both connectors)**** @@ -56,9 +58,9 @@ GoodFET -> 7TDMI 14-pin connector 3 5 (TDI) 5 7 (TMS) 7 9 (TCK) - 8 12 (nRST) 9 2,4,6,8,10,14 (GND) - 11 3 (nTRST) + 11 12 (nRST) + // no longer... (11 3 (nTRST)) http://hri.sourceforge.net/tools/jtag_faq_org.html ********************************/ @@ -90,7 +92,7 @@ u8 jtagarm_shift_ir(u8 ir, u8 flags){ if (last_ir != ir){ jtag_capture_ir(); jtag_shift_register(); - retval = jtag_trans_n(ir, 4, LSB|flags); + retval = jtag_trans_n(ir, g_jtag_ir_size, LSB|flags); last_ir = ir; } return retval; @@ -110,7 +112,7 @@ state” to the “Select DR” state each time the “Update” state is reache last_scanchain = chain; jtag_capture_dr(); jtag_shift_register(); - retval = jtag_trans_n(chain, 4, LSB | NORETIDLE); + retval = jtag_trans_n(chain, g_jtagarm_scan_n_bitsize, LSB | NORETIDLE); } jtagarm_shift_ir(testmode, NORETIDLE); return(retval); @@ -120,23 +122,23 @@ state” to the “Select DR” state each time the “Update” state is reache /************************* EmbeddedICE Primitives ****************************/ //! shifter for writing to chain2 (EmbeddedICE). unsigned long eice_write(unsigned char reg, unsigned long data){ - unsigned long retval, temp; + unsigned long retval; jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST); jtag_capture_dr(); jtag_shift_register(); retval = jtag_trans_n(data, 32, LSB| NOEND| NORETIDLE); // send in the data - 32-bits lsb - temp = jtag_trans_n(reg, 5, LSB| NOEND| NORETIDLE); // send in the register address - 5 bits lsb + jtag_trans_n(reg, 5, LSB| NOEND| NORETIDLE); // send in the register address - 5 bits lsb jtag_trans_n(1, 1, LSB); // send in the WRITE bit return(retval); } //! shifter for reading from chain2 (EmbeddedICE). unsigned long eice_read(unsigned char reg){ // PROVEN - unsigned long temp, retval; + unsigned long retval; jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST); jtag_capture_dr(); jtag_shift_register(); // send in the register address - 5 bits LSB - temp = jtag_trans_n(reg, 5, LSB| NOEND| NORETIDLE); + jtag_trans_n(reg, 5, LSB| NOEND| NORETIDLE); jtag_trans_n(0L, 1, LSB); // clear TDI to select "read only" jtag_capture_dr(); jtag_shift_register(); // Now shift out the 32 bits @@ -148,11 +150,8 @@ unsigned long eice_read(unsigned char reg){ // PROVEN //! push an instruction into the pipeline unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){ // PROVEN unsigned long retval = 0; - //debugstr("jtagarm7tdmi_instr_primitive"); jtagarm7tdmi_scan(1, ARM7TDMI_IR_INTEST); - //debugstr("instruction:"); - //debughex32(instr); //if (!(last_instr == instr && last_sysstate == breakpt)) { jtag_capture_dr(); @@ -171,14 +170,34 @@ unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){ // Now shift in the 32 bits retval = jtag_trans_n(instr, 32, 0); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock. - //debugstr("hot off the pipeline!"); - //debughex32(retval); last_instr = instr; last_sysstate = breakpt; - }// else - //{ // this assumes we don't want retval! wtfo!? - // jtag_tcktock(); - //} + } + return(retval); +} + +//! push an instruction into the pipeline +unsigned long jtagarm_instr_primitive(unsigned char *instr, char breakpt){ + unsigned long retval = 0; + jtagarm7tdmi_scan(1, ARM7TDMI_IR_INTEST); + + //if (!(last_instr == instr && last_sysstate == breakpt)) + { + jtag_capture_dr(); + jtag_shift_register(); + + // if the next instruction is to run using MCLK (master clock), set TDI + if (breakpt) + { SETMOSI; } + else + { CLRMOSI; } + jtag_tcktock(); + + // Now shift in the 32 bits + retval = jtag_trans_many(instr, 32, 0); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock. + last_instr = *instr; + last_sysstate = breakpt; + } return(retval); } @@ -304,6 +323,14 @@ void jtagarm7_handle_fn( uint8_t const app, jtagarm7tdmi_start(); txdata(app,verb,0); break; + case JTAGARM7_SCAN_N_SIZE: + g_jtagarm_scan_n_bitsize = cmddata[0]; + txdata(app,verb,1); + break; + case JTAGARM7_IR_SIZE: + g_jtag_ir_size = cmddata[0]; + txdata(app,verb,1); + break; case JTAG_IR_SHIFT: cmddataword[0] = jtagarm_shift_ir(cmddata[0], cmddata[1]); txdata(app,verb,1); @@ -314,25 +341,26 @@ void jtagarm7_handle_fn( uint8_t const app, val = cmddata[0]; if (cmddata[0] > 32) { - debughex32(cmddatalong[0]); - debughex32(cmddatalong[1]); + //debughex32(cmddatalong[0]); + //debughex32(cmddatalong[1]); cmddatalong[1] = jtag_trans_n(cmddatalong[2], val - 32 ,cmddata[1] | NOEND |NORETIDLE); cmddatalong[0] = jtag_trans_n(cmddatalong[2], 32, cmddata[1]); } else { - debughex32(cmddatalong[0]); + //debughex32(cmddatalong[0]); cmddatalong[0] = jtag_trans_n(cmddatalong[1], val, cmddata[1]); } txdata(app,verb,val/8); break; case JTAG_DR_SHIFT_MORE: // assumes you just executed JTAG_DR_SHIFT with NOEND flag set + debugstr("JTAG_DR_SHIFT_MORE"); val = cmddata[0]; if (cmddata[0] > 32) { - debughex32(cmddatalong[0]); - debughex32(cmddatalong[1]); + //debughex32(cmddatalong[0]); + //debughex32(cmddatalong[1]); cmddatalong[1] = jtag_trans_n(cmddatalong[2], val - 32 ,cmddata[1] | NOEND |NORETIDLE); cmddatalong[0] = jtag_trans_n(cmddatalong[2], 32, cmddata[1]); } @@ -343,6 +371,13 @@ void jtagarm7_handle_fn( uint8_t const app, } txdata(app,verb,val/8); break; + case JTAG_DR_SHIFT_MANY: + jtag_capture_dr(); + jtag_shift_register(); + val = cmddata[0]; + jtag_trans_many(&cmddata[2], val, cmddata[1] ); + txdata(app,verb,((val+7)/8)+2); + break; case JTAGARM7_CHAIN0: jtagarm7tdmi_scan(0, ARM7TDMI_IR_INTEST); jtag_capture_dr(); @@ -362,6 +397,10 @@ void jtagarm7_handle_fn( uint8_t const app, cmddatalong[0] = jtagarm7tdmi_instr_primitive(cmddatalong[0],cmddata[4]); txdata(app,verb,4); break; + case JTAGARM_SCAN1_MANY: + cmddatalong[0] = jtagarm_instr_primitive(&cmddata[1],cmddata[0]); + txdata(app,verb,4); + break; case JTAGARM7_EICE_READ: cmddatalong[0] = eice_read(cmddata[0]); txdata(app,verb,0x4); @@ -382,9 +421,12 @@ void jtagarm7_handle_fn( uint8_t const app, case JTAG_RESET_TARGET: //FIXME: BORKEN debugstr("RESET TARGET"); + //debughex((P3OUT&RST)); CLRRST; + //debughex((P3OUT&RST)); delay(cmddataword[0]); SETRST; + //debughex((P3OUT&RST)); txdata(app,verb,4); break; @@ -403,4 +445,144 @@ void jtagarm7_handle_fn( uint8_t const app, } } +#define min(x,y) ( (x>y) ? y : x ) +#define max(x,y) ( (x>y) ? x : y ) +uint8_t* jtag_trans_many(uint8_t *data, + uint8_t bitcount, + enum eTransFlags flags) +{ + uint8_t bit; + uint16_t high; + uint16_t mask; + uint16_t hmask; + uint8_t bitnum = 0; + + if (!in_state(SHIFT_IR | SHIFT_DR)) + { + debugstr("jtag_trans_many from invalid TAP state"); + return 0; + } + + SAVETCLK; + + if (flags & LSB) + { + high = (1L << (min(bitcount,8) - 1)); + mask = high - 1; + + for (bit = bitcount; bit > 0; bit--,bitnum++) + { + if (bitnum == 8) + { + high = (1L << (min(bit,8) - 1)); + mask = high - 1; + bitnum = 0; + data ++; + } + /* write MOSI on trailing edge of previous clock */ + if (*data & 1) + { + SETMOSI; + } + else + { + CLRMOSI; + } + *data >>= 1; + + if ((bit == 1) && !(flags & NOEND)) + SETTMS; //TMS high on last bit to exit. + + jtag_tcktock(); + + if ((bit == 1) && !(flags & NOEND)) + jtag_state <<= 1; // Exit1-DR or Exit1-IR + + /* read MISO on trailing edge */ + if (READMISO) + { + *data |= (high); + } + + } + hmask = (high<<1) - 1; + *data &= hmask; + } + else + { + // MSB... we need to start at the end of the byte array + data += (bitcount/8); + bitnum = bitcount % 8; + high = (1L << (min(bitnum,8) - 1)); + mask = high - 1; + hmask = (high<<1) - 1; + + for (bit = bitcount; bit > 0; bit--,bitnum--) + { + if (bitnum == 0) + { + *data &= hmask; + + high = (1L << (min(bit,8) - 1)); + mask = high - 1; + hmask = (high<<1) - 1; + bitnum = 8; + + data --; + } + + /* write MOSI on trailing edge of previous clock */ + if (*data & high) + { + SETMOSI; + } + else + { + CLRMOSI; + } + *data = (*data & mask) << 1; + + if ((bit==1) && !(flags & NOEND)) + SETTMS; //TMS high on last bit to exit. + + jtag_tcktock(); + + if ((bit == 1) && !(flags & NOEND)) + jtag_state <<= 1; // Exit1-DR or Exit1-IR + + /* read MISO on trailing edge */ + *data |= (READMISO); + + } + } + + //This is needed for 20-bit MSP430 chips. + //Might break another 20-bit chip, if one exists. + // + //UGH... this needs to be fixed... doesn't work with char* +/* if(bitcount==20){ + *data = ((*data << 16) | (*data >> 4)) & 0x000FFFFF; + }*/ + + RESTORETCLK; + + if (!(flags & NOEND)) + { + // exit state + jtag_tcktock(); + + jtag_state <<= 3; // Update-DR or Update-IR + + // update state + if (!(flags & NORETIDLE)) + { + CLRTMS; + jtag_tcktock(); + + jtag_state = RUN_TEST_IDLE; + } + } + + return &data[2]; +}