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;
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;
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);
/************************* 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
//! 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();
// 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);
}
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);
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]);
}
}
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();
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);
case JTAG_RESET_TARGET:
//FIXME: BORKEN
debugstr("RESET TARGET");
- debughex((P3OUT&RST));
+ //debughex((P3OUT&RST));
CLRRST;
- debughex((P3OUT&RST));
+ //debughex((P3OUT&RST));
delay(cmddataword[0]);
SETRST;
- debughex((P3OUT&RST));
+ //debughex((P3OUT&RST));
txdata(app,verb,4);
break;
}
}
+#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];
+}