jtagtransn reworked. testing looks good so far.
authordodge-this <dodge-this@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Wed, 11 Aug 2010 15:16:20 +0000 (15:16 +0000)
committerdodge-this <dodge-this@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Wed, 11 Aug 2010 15:16:20 +0000 (15:16 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@689 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETARM.py
firmware/apps/jtag/jtag.c
firmware/apps/jtag/jtagarm7tdmi.c
firmware/include/jtag.h
firmware/include/jtagarm7tdmi.h

index 4573425..b549416 100644 (file)
@@ -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])
index d0d2118..415f36a 100644 (file)
@@ -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);
index e4225ed..a0449ee 100644 (file)
@@ -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:
index 432c23d..aab18fe 100644 (file)
@@ -10,7 +10,6 @@
 #include <io.h>
 #include <iomacros.h>
 
-
 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"
index 3e2045d..37960fe 100644 (file)
@@ -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