Dropped ugly 'blocks' kludge for a 16-bit length field.
[goodfet] / firmware / apps / jtag / jtag.c
index cffec3d..73a6750 100644 (file)
@@ -1,22 +1,23 @@
-//GoodFET JTAG Application
-//Handles basic I/O
+/*! \file jtag.c
+  \author Travis Goodspeed <travis at radiantmachines.com>
+  \brief Low-level JTAG
+*/
 
-//Higher level left to client application.
 
 #include "platform.h"
 #include "command.h"
 #include "jtag.h"
 
 
-
-
 //! Set up the pins for JTAG mode.
-unsigned char jtagsetup(){
+void jtagsetup(){
   P5DIR|=MOSI+SCK+TMS;
   P5DIR&=~MISO;
   P5OUT|=0xFFFF;
+  P5OUT=0;
   P4DIR|=TST;
   P2DIR|=RST;
+  msdelay(100);
 }
 
 int savedtclk=0;
@@ -27,9 +28,9 @@ unsigned char jtagtrans8(unsigned char byte){
   for (bit = 0; bit < 8; bit++) {
     /* write MOSI on trailing edge of previous clock */
     if (byte & 0x80)
-      SETMOSI;
+      {SETMOSI;}
     else
-      CLRMOSI;
+      {CLRMOSI;}
     byte <<= 1;
     
     if(bit==7)
@@ -53,17 +54,66 @@ unsigned char jtagtrans8(unsigned char byte){
   return byte;
 }
 
-//! Shift 8 bits in and out.
-unsigned int jtagtrans16(unsigned int word){
+//! Shift n bits in and out.
+unsigned long jtagtransn(unsigned long word,
+                        unsigned int bitcount){
   unsigned int bit;
+  //0x8000
+  unsigned long high;
+  
+  if(bitcount==20)
+    high=0x80000;
+  if(bitcount==16)
+    high= 0x8000;
+  
   SAVETCLK;
   
-  for (bit = 0; bit < 16; bit++) {
+  for (bit = 0; bit < bitcount; bit++) {
     /* write MOSI on trailing edge of previous clock */
+    if (word & high)
+      {SETMOSI;}
+    else
+      {CLRMOSI;}
+    word <<= 1;
+    
+    if(bit==bitcount-1)
+      SETTMS;//TMS high on last bit to exit.
+    
+    CLRTCK;
+    SETTCK;
+    /* read MISO on trailing edge */
+    word |= READMISO;
+  }
+  
+  if(bitcount==20){
+    word = ((word << 16) | (word >> 4)) & 0x000FFFFF;
+  }
+  
+  RESTORETCLK;
+  
+  // exit state
+  CLRTCK;
+  SETTCK;
+  // update state
+  CLRTMS;
+  CLRTCK;
+  SETTCK;
+  
+  return word;
+}
+
+/*
+//! Shift 16 bits in and out.
+unsigned int jtagtrans16(unsigned int word){ //REMOVEME
+  unsigned int bit;
+  SAVETCLK;
+  
+  for (bit = 0; bit < 16; bit++) {
+    // write MOSI on trailing edge of previous clock 
     if (word & 0x8000)
-      SETMOSI;
+      {SETMOSI;}
     else
-      CLRMOSI;
+      {CLRMOSI;}
     word <<= 1;
     
     if(bit==15)
@@ -71,7 +121,7 @@ unsigned int jtagtrans16(unsigned int word){
     
     CLRTCK;
     SETTCK;
-     /* read MISO on trailing edge */
+    // read MISO on trailing edge 
     word |= READMISO;
   }
   RESTORETCLK;
@@ -85,7 +135,7 @@ unsigned int jtagtrans16(unsigned int word){
   SETTCK;
   
   return word;
-}
+}*/
 
 //! Stop JTAG, release pins
 void jtag_stop(){
@@ -93,6 +143,25 @@ void jtag_stop(){
   P4OUT=0;
 }
 
+unsigned int drwidth=20;
+//! Shift all bits of the DR.
+unsigned long jtag_dr_shift20(unsigned long in){
+  // idle
+  SETTMS;
+  CLRTCK;
+  SETTCK;
+  // select DR
+  CLRTMS;
+  CLRTCK;
+  SETTCK;
+  // capture IR
+  CLRTCK;
+  SETTCK;
+  
+  // shift DR, then idle
+  return(jtagtransn(in,20));
+}
+
 
 //! Shift 16 bits of the DR.
 unsigned int jtag_dr_shift16(unsigned int in){
@@ -107,9 +176,9 @@ unsigned int jtag_dr_shift16(unsigned int in){
   // capture IR
   CLRTCK;
   SETTCK;
-
+  
   // shift DR, then idle
-  return(jtagtrans16(in));
+  return(jtagtransn(in,16));
 }
 
 
@@ -137,7 +206,7 @@ unsigned char jtag_ir_shift8(unsigned char in){
 //! Handles a monitor command.
 void jtaghandle(unsigned char app,
               unsigned char verb,
-              unsigned char len){
+              unsigned long len){
   switch(verb){
     //START handled by specific JTAG
   case STOP: