From: dodge-this Date: Wed, 11 Aug 2010 15:16:20 +0000 (+0000) Subject: jtagtransn reworked. testing looks good so far. X-Git-Url: http://git.rot13.org/?p=goodfet;a=commitdiff_plain;h=d85d45d823dda71280f4ed9083717ec8e5ce28ae;hp=8776829cc0b0dc7601698bb73cdca227af95ef60 jtagtransn reworked. testing looks good so far. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@689 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- diff --git a/client/GoodFETARM.py b/client/GoodFETARM.py index 4573425..b549416 100644 --- a/client/GoodFETARM.py +++ b/client/GoodFETARM.py @@ -67,6 +67,12 @@ SETWATCH0 = 0xa1 SETWATCH1 = 0xa2 CHAIN0 = 0xa3 + +MSB = 0 +LSB = 1 +NOEND = 2 +NORETIDLE = 4 + PM_usr = 0b10000 PM_fiq = 0b10001 PM_irq = 0b10010 @@ -332,11 +338,11 @@ class GoodFETARM(GoodFET): return (self.data) def ARM_nop(self, bkpt): return self.ARMdebuginstr(ARM_INSTR_NOP, bkpt) - def ARMset_IR(self, IR, RETIDLE=1): - self.writecmd(0x13,SET_IR,2, [IR, RETIDLE]) + def ARMset_IR(self, IR, noretidle=0): + self.writecmd(0x13,SET_IR,2, [IR, LSB|noretidle]) return self.data - def ARMshiftDR(self, data, bits, LSB, END, RETIDLE): - self.writecmd(0x13,SHIFT_DR,8,[bits&0xff, LSB&0xff, END&0xff, RETIDLE&0xff, data&0xff,(data>>8)&0xff,(data>>16)&0xff,(data>>24)&0xff]) + def ARMshiftDR(self, data, bits, flags): + self.writecmd(0x13,SHIFT_DR,8,[bits&0xff, flags&0xff, 0, 0, data&0xff,(data>>8)&0xff,(data>>16)&0xff,(data>>24)&0xff]) return self.data def ARMwaitDBG(self, timeout=0xff): self.writecmd(0x13,WAIT_DBG,2,[timeout&0xf,timeout>>8]) diff --git a/firmware/apps/jtag/jtag.c b/firmware/apps/jtag/jtag.c index d0d2118..415f36a 100644 --- a/firmware/apps/jtag/jtag.c +++ b/firmware/apps/jtag/jtag.c @@ -22,7 +22,125 @@ void jtagsetup(){ msdelay(100); } +/************************** JTAG Primitives ****************************/ +// these have been turned into functions to save flash space +void jtag_tcktock() { + //delay(1); // FIXME: Should never wait this long... + CLRTCK; + PLEDOUT^=PLEDPIN; + //delay(1); // FIXME: Should never wait this long... + SETTCK; + PLEDOUT^=PLEDPIN; +} + +void jtag_goto_shift_ir() { + SETTMS; + jtag_tcktock(); + jtag_tcktock(); + CLRTMS; + jtag_tcktock(); + jtag_tcktock(); + +} +void jtag_goto_shift_dr() { + SETTMS; + jtag_tcktock(); + CLRTMS; + jtag_tcktock(); + jtag_tcktock(); +} + +void jtag_reset_to_runtest_idle() { + SETTMS; + jtag_tcktock(); + jtag_tcktock(); + jtag_tcktock(); + jtag_tcktock(); + jtag_tcktock(); // now in Reset state + CLRTMS; + jtag_tcktock(); // now in Run-Test/Idle state +} + + int savedtclk=0; +// NOTE: important: THIS MODULE REVOLVES AROUND RETURNING TO RUNTEST/IDLE, OR THE FUNCTIONAL EQUIVALENT +//! Shift N bits over TDI/TDO. May choose LSB or MSB, and select whether to terminate (TMS-high on last bit) and whether to return to RUNTEST/IDLE +// flags should be 0 for most uses. +// for the extreme case, flags should be (NOEND|NORETDLE|LSB) +// other edge cases can involve a combination of those three flags +// +// the max bit-size that can be be shifted is 32-bits. +// for longer shifts, use the NOEND flag (which infers NORETIDLE so the additional flag is unnecessary) +// +// NORETIDLE is used for special cases where (as with arm) the debug subsystem does not want to +// return to the RUN-TEST/IDLE state between setting IR and DR +unsigned long jtagtransn(unsigned long word, unsigned char bitcount, unsigned char flags){ + unsigned char bit; + unsigned long high = 1L; + unsigned long mask; + + //for (bit=(bitcount-1)/8; bit>0; bit--) + // high <<= 8; + //high <<= ((bitcount-1)%8); + high <<= (bitcount-1); + + mask = high-1; + + SAVETCLK; + if (flags & LSB) { + for (bit = bitcount; bit > 0; bit--) { + /* write MOSI on trailing edge of previous clock */ + if (word & 1) + {SETMOSI;} + else + {CLRMOSI;} + word >>= 1; + + if (bit==1 && !(flags & NOEND)) + SETTMS;//TMS high on last bit to exit. + + jtag_tcktock(); + + /* read MISO on trailing edge */ + if (READMISO){ + word += (high); + } + } + } else { + for (bit = bitcount; bit > 0; bit--) { + /* write MOSI on trailing edge of previous clock */ + if (word & high) + {SETMOSI;} + else + {CLRMOSI;} + word = (word & mask) << 1; + + if (bit==1 && !(flags & NOEND)) + SETTMS;//TMS high on last bit to exit. + + jtag_tcktock(); + + /* read MISO on trailing edge */ + word |= (READMISO); + } + } + + + RESTORETCLK; + //SETMOSI; + + if (!(flags & NOEND)){ + // exit state + jtag_tcktock(); + // update state + if (!(flags & NORETIDLE)){ + CLRTMS; + jtag_tcktock(); + } + } + return word; +} + //! Shift 8 bits in and out. unsigned char jtagtrans8(unsigned char byte){ unsigned int bit; @@ -54,7 +172,7 @@ unsigned char jtagtrans8(unsigned char byte){ } //! Shift n bits in and out. -unsigned long jtagtransn(unsigned long word, +/*unsigned long jtagtransn(unsigned long word, unsigned int bitcount){ unsigned int bit; //0x8000 @@ -68,7 +186,7 @@ unsigned long jtagtransn(unsigned long word, SAVETCLK; for (bit = 0; bit < bitcount; bit++) { - /* write MOSI on trailing edge of previous clock */ + //* write MOSI on trailing edge of previous clock * if (word & high) {SETMOSI;} else @@ -79,7 +197,7 @@ unsigned long jtagtransn(unsigned long word, SETTMS;//TMS high on last bit to exit. TCKTOCK; - /* read MISO on trailing edge */ + //* read MISO on trailing edge * word |= READMISO; } @@ -97,7 +215,7 @@ unsigned long jtagtransn(unsigned long word, return word; } - +*/ //! Stop JTAG, release pins void jtag_stop(){ @@ -118,7 +236,7 @@ unsigned long jtag_dr_shift20(unsigned long in){ TCKTOCK; // shift DR, then idle - return(jtagtransn(in,20)); + return(jtagtransn(in,20,0)); } @@ -134,7 +252,7 @@ unsigned int jtag_dr_shift16(unsigned int in){ TCKTOCK; // shift DR, then idle - return(jtagtransn(in,16)); + return(jtagtransn(in,16,0)); } //! Shift native width of the DR @@ -151,7 +269,7 @@ unsigned long jtag_dr_shiftadr(unsigned long in){ TCKTOCK; - out=jtagtransn(in,drwidth); + out=jtagtransn(in,drwidth,0); // shift DR, then idle return(out); diff --git a/firmware/apps/jtag/jtagarm7tdmi.c b/firmware/apps/jtag/jtagarm7tdmi.c index e4225ed..a0449ee 100644 --- a/firmware/apps/jtag/jtagarm7tdmi.c +++ b/firmware/apps/jtag/jtagarm7tdmi.c @@ -93,44 +93,6 @@ for this module, we keep tck high for all changes/sampling, and then bounce it. -/************************** JTAGARM7TDMI Primitives ****************************/ -void jtag_goto_shift_ir() { - SETTMS; - jtag_arm_tcktock(); - jtag_arm_tcktock(); - CLRTMS; - jtag_arm_tcktock(); - jtag_arm_tcktock(); - -} -void jtag_goto_shift_dr() { - SETTMS; - jtag_arm_tcktock(); - CLRTMS; - jtag_arm_tcktock(); - jtag_arm_tcktock(); -} - -void jtag_reset_to_runtest_idle() { - SETTMS; - jtag_arm_tcktock(); - jtag_arm_tcktock(); - jtag_arm_tcktock(); - jtag_arm_tcktock(); - jtag_arm_tcktock(); // now in Reset state - CLRTMS; - jtag_arm_tcktock(); // now in Run-Test/Idle state -} - -void jtag_arm_tcktock() { - delay(1); // FIXME: Should never wait this long... - CLRTCK; - PLEDOUT^=PLEDPIN; - delay(1); // FIXME: Should never wait this long... - SETTCK; - PLEDOUT^=PLEDPIN; -} - // ! Start JTAG, setup pins, reset TAP and return IDCODE unsigned long jtagarm7tdmi_start() { @@ -149,7 +111,7 @@ void jtagarm7tdmi_resettap(){ // PROVEN // NOTE: important: THIS MODULE REVOLVES AROUND RETURNING TO RUNTEST/IDLE, OR THE FUNCTIONAL EQUIVALENT - +/* //! Shift N bits over TDI/TDO. May choose LSB or MSB, and select whether to terminate (TMS-high on last bit) and whether to return to RUNTEST/IDLE unsigned long jtagarmtransn(unsigned long word, unsigned char bitcount, unsigned char lsb, unsigned char end, unsigned char retidle){ // PROVEN unsigned char bit; @@ -163,9 +125,10 @@ unsigned long jtagarmtransn(unsigned long word, unsigned char bitcount, unsigned mask = high-1; + SAVETCLK; if (lsb) { for (bit = bitcount; bit > 0; bit--) { - /* write MOSI on trailing edge of previous clock */ + /* write MOSI on trailing edge of previous clock * if (word & 1) {SETMOSI;} else @@ -177,14 +140,14 @@ unsigned long jtagarmtransn(unsigned long word, unsigned char bitcount, unsigned jtag_arm_tcktock(); - /* read MISO on trailing edge */ + //* read MISO on trailing edge * if (READMISO){ word += (high); } } } else { for (bit = bitcount; bit > 0; bit--) { - /* write MOSI on trailing edge of previous clock */ + //* write MOSI on trailing edge of previous clock * if (word & high) {SETMOSI;} else @@ -196,13 +159,14 @@ unsigned long jtagarmtransn(unsigned long word, unsigned char bitcount, unsigned jtag_arm_tcktock(); - /* read MISO on trailing edge */ + //* read MISO on trailing edge * word |= (READMISO); } } - SETMOSI; + RESTORETCLK; + //SETMOSI; if (end){ // exit state @@ -215,7 +179,7 @@ unsigned long jtagarmtransn(unsigned long word, unsigned char bitcount, unsigned } return word; } - +*/ /************************************************************************ @@ -235,9 +199,9 @@ unsigned long jtagarmtransn(unsigned long word, unsigned char bitcount, unsigned unsigned long jtagarm7tdmi_idcode(){ // PROVEN jtagarm7tdmi_resettap(); jtag_goto_shift_ir(); - jtagarmtransn(ARM7TDMI_IR_IDCODE, 4, LSB, END, RETIDLE); + jtagtransn(ARM7TDMI_IR_IDCODE, 4, LSB); jtag_goto_shift_dr(); - return jtagarmtransn(0,32, LSB, END, RETIDLE); + return jtagtransn(0,32, LSB); } //! Connect Bypass Register to TDO/TDI @@ -268,7 +232,7 @@ unsigned long jtagarm7tdmi_idcode(){ // PROVEN unsigned long jtagarm7tdmi_restart() { unsigned long retval; jtag_goto_shift_ir(); - retval = jtagarmtransn(ARM7TDMI_IR_RESTART, 4, LSB, END, RETIDLE); + retval = jtagtransn(ARM7TDMI_IR_RESTART, 4, LSB); current_chain = -1; //jtagarm7tdmi_resettap(); return retval; @@ -310,9 +274,9 @@ state” to the “Select DR” state each time the “Update” state is reache //if (current_chain != chain) { // //debugstr("===change chains==="); jtag_goto_shift_ir(); - jtagarmtransn(ARM7TDMI_IR_SCAN_N, 4, LSB, END, NORETIDLE); + jtagtransn(ARM7TDMI_IR_SCAN_N, 4, LSB | NORETIDLE); jtag_goto_shift_dr(); - retval = jtagarmtransn(chain, 4, LSB, END, NORETIDLE); + retval = jtagtransn(chain, 4, LSB | NORETIDLE); // put in test mode... //jtag_goto_shift_ir(); //jtagarmtransn(testmode, 4, LSB, END, RETIDLE); @@ -323,7 +287,7 @@ state” to the “Select DR” state each time the “Update” state is reache //} // put in test mode... jtag_goto_shift_ir(); - jtagarmtransn(testmode, 4, LSB, END, RETIDLE); + jtagtransn(testmode, 4, LSB); return(retval); } @@ -353,10 +317,10 @@ unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){ CLRMOSI; count_dbgspd_instr_since_debug++; } - jtag_arm_tcktock(); + jtag_tcktock(); // Now shift in the 32 bits - retval = jtagarmtransn(instr, 32, MSB, END, RETIDLE); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock. + retval = jtagtransn(instr, 32, 0); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock. return(retval); } @@ -442,9 +406,9 @@ unsigned long eice_write(unsigned char reg, unsigned long data){ jtagarm7tdmi_scan_intest(2); // Now shift in the 32 bits jtag_goto_shift_dr(); - retval = jtagarmtransn(data, 32, LSB, NOEND, NORETIDLE); // send in the data - 32-bits lsb - temp = jtagarmtransn(reg, 5, LSB, NOEND, NORETIDLE); // send in the register address - 5 bits lsb - jtagarmtransn(1, 1, LSB, END, RETIDLE); // send in the WRITE bit + retval = jtagtransn(data, 32, LSB| NOEND| NORETIDLE); // send in the data - 32-bits lsb + temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE); // send in the register address - 5 bits lsb + jtagtransn(1, 1, LSB); // send in the WRITE bit return(retval); } @@ -458,14 +422,14 @@ unsigned long eice_read(unsigned char reg){ // PROVEN // send in the register address - 5 bits LSB jtag_goto_shift_dr(); - temp = jtagarmtransn(reg, 5, LSB, NOEND, NORETIDLE); + temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE); // clear TDI to select "read only" - jtagarmtransn(0L, 1, LSB, END, RETIDLE); + jtagtransn(0L, 1, LSB); jtag_goto_shift_dr(); // Now shift out the 32 bits - retval = jtagarmtransn(0L, 32, LSB, END, RETIDLE); // atmel arm jtag docs pp.10-11: LSB first + retval = jtagtransn(0L, 32, LSB); // atmel arm jtag docs pp.10-11: LSB first //debughex32(retval); return(retval); // atmel arm jtag docs pp.10-11: LSB first @@ -981,7 +945,7 @@ void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len case JTAGARM7TDMI_SET_IR: //jtagarm7tdmi_resettap(); jtag_goto_shift_ir(); - cmddataword[0] = jtagarmtransn(cmddata[0], 4, LSB, END, cmddata[1]); + cmddataword[0] = jtagtransn(cmddata[0], 4, cmddata[1]); current_chain = -1; txdata(app,verb,2); break; @@ -992,7 +956,7 @@ void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len case JTAGARM7TDMI_SHIFT_DR: jtagarm7tdmi_resettap(); jtag_goto_shift_dr(); - cmddatalong[0] = jtagarmtransn(cmddatalong[1],cmddata[0],cmddata[1],cmddata[2],cmddata[3]); + cmddatalong[0] = jtagtransn(cmddatalong[1],cmddata[0],cmddata[1]); txdata(app,verb,4); break; case JTAGARM7TDMI_CHAIN0: @@ -1002,10 +966,10 @@ void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len debughex(cmddataword[4]); debughex32(cmddatalong[1]); debughex32(cmddatalong[3]); - cmddatalong[0] = jtagarmtransn(cmddatalong[0], 32, LSB, NOEND, NORETIDLE); - cmddatalong[2] = jtagarmtransn(cmddataword[4], 9, MSB, NOEND, NORETIDLE); - cmddatalong[1] = jtagarmtransn(cmddatalong[1], 32, MSB, NOEND, NORETIDLE); - cmddatalong[3] = jtagarmtransn(cmddatalong[3], 32, MSB, END, RETIDLE); + cmddatalong[0] = jtagtransn(cmddatalong[0], 32, LSB| NOEND| NORETIDLE); + cmddatalong[2] = jtagtransn(cmddataword[4], 9, MSB| NOEND| NORETIDLE); + cmddatalong[1] = jtagtransn(cmddatalong[1], 32, MSB| NOEND| NORETIDLE); + cmddatalong[3] = jtagtransn(cmddatalong[3], 32, MSB); txdata(app,verb,16); break; case JTAGARM7TDMI_SETWATCH0: diff --git a/firmware/include/jtag.h b/firmware/include/jtag.h index 432c23d..aab18fe 100644 --- a/firmware/include/jtag.h +++ b/firmware/include/jtag.h @@ -10,7 +10,6 @@ #include #include - extern unsigned int drwidth; #define MSP430MODE 0 @@ -22,7 +21,8 @@ extern unsigned int jtag430mode; //! Shift n bytes. unsigned long jtagtransn(unsigned long word, - unsigned int bitcount); + unsigned char bitcount, + unsigned char flags); //! Shift the address width. unsigned long jtag_dr_shiftadr(unsigned long in); //! Shift 8 bits of the IR. @@ -155,6 +155,11 @@ void jtag430_por(); #define JTAG_DR_SHIFT 0x81 #define JTAG_DR_SHIFT20 0x91 +#define MSB 0 +#define LSB 1 +#define NOEND 2 +#define NORETIDLE 4 + //JTAG430 commands #include "jtag430.h" diff --git a/firmware/include/jtagarm7tdmi.h b/firmware/include/jtagarm7tdmi.h index 3e2045d..37960fe 100644 --- a/firmware/include/jtagarm7tdmi.h +++ b/firmware/include/jtagarm7tdmi.h @@ -130,14 +130,6 @@ The least significant bit of the instruction register is scanned in and scanned #define EICE_WP1CTRLMASK 21 -#define NOEND 0 -#define END 1 -#define MSB 0 -#define LSB 1 -#define NORETIDLE 0 -#define RETIDLE 1 - - //JTAGARM7TDMI commands #define JTAGARM7TDMI_GET_DEBUG_CTRL 0x80 #define JTAGARM7TDMI_SET_DEBUG_CTRL 0x81