starting OpenOCD app and client changes for JTAG work that didn't go in earlier.
authordwhuseby <dwhuseby@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Wed, 9 Feb 2011 10:28:27 +0000 (10:28 +0000)
committerdwhuseby <dwhuseby@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Wed, 9 Feb 2011 10:28:27 +0000 (10:28 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@901 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETJTAG.py
client/GoodFETXSCALE.py
client/goodfet.jtag [new file with mode: 0755]
client/goodfet.xscale
firmware/Makefile
firmware/apps/jtag/openocd.c
firmware/include/openocd.h

index 4dc4061..b579d74 100644 (file)
@@ -16,6 +16,13 @@ EXEC  = 0x31
 NOK   = 0x7E
 OK    = 0x7F
 
+# JTAG commands
+JTAG_RESET_TAP              = 0x82
+JTAG_RESET_TARGET           = 0x83
+JTAG_DETECT_IR_WIDTH        = 0x84
+JTAG_DETECT_CHAIN_LENGTH    = 0x85
+JTAG_GET_DEVICE_ID          = 0x86
+
 from GoodFET import GoodFET
 from intelhex import IntelHex
 
@@ -26,13 +33,50 @@ class GoodFETJTAG(GoodFET):
     JTAGAPP=0x10;
     APP=JTAGAPP;
  
+    def _check_return(self, verb, length=0):
+        if (self.app == self.APP) and \
+           (self.verb == verb) and \
+           (len(self.data) == length):
+            print "OK"
+            return True
+        print "Failed!"
+        return False
+
     def setup(self):
         """Move the FET into the JTAG configuration."""
-        print "Initializing JTAG..."
-        #self.writecmd(self.APP, SETUP, 0, self.data)
+        sys.stdout.write("Initializing JTAG...")
+        self.writecmd(self.APP, SETUP)
+        self._check_return(SETUP)
+
+    def reset_tap(self):
+        sys.stdout.write("Resetting TAP...")
+        self.writecmd(self.APP, JTAG_RESET_TAP)
+        self._check_return(JTAG_RESET_TAP)
+
+    def reset_target(self):
+        sys.stdout.write("Resseting target device...")
+        self.writecmd(self.APP, JTAG_RESET_TARGET)
+        self._check_return(JTAG_RESET_TARGET)
+
+    def detect_ir_width(self):
+        sys.stdout.write("Detecting IR width...")
+        self.writecmd(self.APP, JTAG_DETECT_IR_WIDTH)
+        self._check_return(JTAG_DETECT_IR_WIDTH, 2)
+        width = struct.unpack("!H", self.data)[0]
+        return width
+
+    def detect_chain_length(self):
+        sys.stdout.write("Detecting chain length...")
+        self.writecmd(self.APP, JTAG_DETECT_CHAIN_LENGTH)
+        self._check_return(JTAG_DETECT_CHAIN_LENGTH, 2)
+        length = struct.unpack("!H", self.data)[0]
+        return length
 
-    def detect(self):
-        """Detect the JTAG IR width."""
-        pass
+    def get_device_id(self, chip):
+        sys.stdout.write("Getting ID for device %d..." % chip)
+        self.writecmd(self.APP, JTAG_GET_DEVICE_ID, 2, struct.pack("!H", chip))
+        self._check_return(JTAG_GET_DEVICE_ID, 4)
+        id = struct.unpack("!L", self.data)[0]
+        return id
 
 
index f71b52e..f9b0c33 100644 (file)
@@ -17,7 +17,7 @@ NOK   = 0x7E
 OK    = 0x7F
 
 # XSCALE JTAG verbs
-GET_CHIP_ID         = 0xF1
+# verbs start at 0xF0
 
 from GoodFETJTAG import GoodFETJTAG
 from intelhex import IntelHex
@@ -28,37 +28,23 @@ class GoodFETXSCALE(GoodFETJTAG):
 
     XSCALEAPP=0x15;
     APP=XSCALEAPP;
+
     def setup(self):
         """Move the FET into the JTAG ARM application."""
-        print "Initializing XScale..."
-        self.writecmd(self.APP, SETUP, 0, self.data)
+        sys.stdout.write("Initializing XScale...")
+        self.writecmd(self.APP, SETUP)
+        self._check_return(SETUP)
 
     def start(self):
         """Start debugging."""
-        print "Staring debug..."
-        self.writecmd(self.APP, START, 0, self.data)
+        sys.stdout.write("Staring session...")
+        self.writecmd(self.APP, START)
+        self._check_return(START)
 
     def stop(self):
         """Stop debugging."""
-        print "Stopping debug..."
-        self.writecmd(self.APP, STOP, 0, self.data)
-
-    def get_id(self):
-        """Get the Chip ID."""
-        
-        # send the get chip ID command
-        self.writecmd(self.APP, GET_CHIP_ID, 0, [])
-
-        # get the response
-        ident = struct.unpack("<L", "".join(self.data[0:4]))[0]
-
-        version = ident >> 28
-        part_number = (ident >> 12) & 0x10
-        manufacturer = ident & 0xFFF
-
-        print "XScale ID --\n\tmfg: %x\n\tpart: %x\n\tver: %x\n\t(%x)" % (version, part_number, manufacturer, ident)
+        sys.stdout.write("Stopping session...")
+        self.writecmd(self.APP, STOP)
+        self._check_return(STOP)
 
-        return ident
-    
 
diff --git a/client/goodfet.jtag b/client/goodfet.jtag
new file mode 100755 (executable)
index 0000000..e91c476
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# GoodFET Basic JTAG
+# 
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+# (C) 2011 Dave Huseby <dave at linuxprogrammer.org>
+#
+# This code is being rewritten and refactored.  You've been warned!
+
+import sys;
+import binascii;
+
+from GoodFETJTAG import GoodFETJTAG
+from intelhex import IntelHex
+
+if len(sys.argv) == 1:
+    print "Usage: %s verb [objects]\n" % sys.argv[0]
+    print "%s reset -- resets the target device" % sys.argv[0]
+    print "%s chain -- detects JTAG chain length" % sys.argv[0]
+    print "%s chipid <chip #> -- gets the chip ID of the chip specified" % sys.argv[0]
+    print "%s ir -- detects the total bits in the IR register" % sys.argv[0]
+    print "%s detect -- detects chain length and gets chip IDs" % sys.argv[0]
+    sys.exit();
+
+#Initailize FET and set baud rate
+client = GoodFETJTAG()
+client.serInit()
+
+#Connect to target
+client.setup()
+
+
+if sys.argv[1] == "reset":
+    client.reset_target()
+
+elif sys.argv[1] == "chain":
+    length = client.detect_chain_length()
+    print "\tChain length: %d" % length
+
+elif sys.argv[1] == "chipid":
+    if len(sys.argv) < 3:
+        print "missing argument"
+        sys.exit()
+    idx = int(sys.argv[2])
+    id = client.get_device_id(idx)
+    print "\tDevice %d ID: 0x%s" % (idx, hex(id)[2:].zfill(8).upper())
+
+elif sys.argv[1] == "ir":
+    width = client.detect_ir_width()
+    print "\tIR width: %d" % width
+
+elif sys.argv[1] == "detect":
+    length = client.detect_chain_length()
+    print "\tChain length: %d" % length
+    for i in range(0, length):
+        id = client.get_device_id(i)
+        print "\tDevice %d ID: 0x%s" % (i, hex(id)[2:].zfill(8).upper())
+
index 7c6e95b..f3be147 100755 (executable)
@@ -12,10 +12,11 @@ import binascii;
 from GoodFETXSCALE import GoodFETXSCALE
 from intelhex import IntelHex
 
-#if(len(sys.argv) == 1):
-#    print "Usage: %s verb [objects]\n" % sys.argv[0]
-#    print "%s chipid" % sys.argv[0]
-#    sys.exit();
+if len(sys.argv) == 1:
+    print "Usage: %s verb [objects]\n" % sys.argv[0]
+    print "%s reset" % sys.argv[0]
+    print "%s chipid <index>" % sys.argv[0]
+    sys.exit();
 
 #Initailize FET and set baud rate
 client = GoodFETXSCALE()
@@ -25,9 +26,15 @@ client.serInit()
 client.setup()
 client.start()
 
-print 'arg: %s' % sys.argv[1]
-if(sys.argv[1] == 'chipid'):
-    print 'Getting XScale Chip ID...'
-    client.get_id()
+if sys.argv[1] == "reset":
+    client.reset_target()
 
-client.stop();
+if sys.argv[1] == "chipid":
+    if len(sys.argv) < 3:
+        print "missing argument"
+        sys.exit()
+    idx = int(sys.argv[2])
+    id = client.get_device_id(idx)
+    print "\tDevice %d ID: 0x%s" % (idx, hex(id)[2:].zfill(8).upper())
+
+client.stop()
index a4ffb43..51e8ba6 100644 (file)
@@ -50,6 +50,7 @@ CC=msp430-gcc -Wall -Os -g -mmcu=$(mcu) -D$(mcu) -D$(platform) -Dplatform=$(plat
 # jtagarm7 -- ARM7TDMI JTAG
 # ejtag -- MIPS JTAG
 # jtagxscale -- XScale JTAG
+# openocd -- OpenOCD bitbang device
 
 #  Microcontrollers:
 # chipcon -- Chipcon radio 8051 debugging
@@ -89,6 +90,9 @@ CC=msp430-gcc -Wall -Os -g -mmcu=$(mcu) -D$(mcu) -D$(platform) -Dplatform=$(plat
 # XScale PXA255 JTAG
 # config = monitor jtagxscale
 
+# OpenOCD bit-bang device
+config = monitor openocd
+
 # Old Default Config
 # config = monitor sbw  chipcon nrf ccspi spi jtagarm7 jtag430 jtag430x2 avr
 
@@ -217,6 +221,17 @@ ifeq ($(filter jtagxscale, $(config)), jtagxscale)
        hdrs+= jtagxscale.h
 endif
 
+# include openocd app
+ifeq ($(filter openocd, $(config)), openocd)
+       # add in base jtag code if not already
+       ifneq ($(filter apps/jtag/jtag.o, $(apps)), apps/jtag/jtag.o)
+               apps+= apps/jtag/jtag.o
+               hdrs+= jtag.h
+       endif
+       apps+= apps/jtag/openocd.o
+       hdrs+= openocd.h
+endif
+
 # include chipcon app
 ifeq ($(filter chipcon, $(config)), chipcon)
        apps+= apps/chipcon/chipcon.o
index 6a0e4c1..feb8e57 100644 (file)
@@ -6,6 +6,8 @@
 
 #include "platform.h"
 #include "command.h"
+#include "openocd.h"
+#include "jtag.h"
 
 #define OPENOCD_APP
 
@@ -27,9 +29,115 @@ app_t const openocd_app = {
        "OpenOCD",
 
        /* desc */
-       "\tThe OpenOCD app handles the OpenOCD protocol.\n"
+       "\tThe OpenOCD app handles the OpenOCD bitbang protocol.\n"
 };
 
+//! Clock the JTAG clock line
+static void openocd_tcktock() 
+{
+       CLRTCK; 
+       SETTCK; 
+}
+
+//! reset the cpu
+static void openocd_reset_cpu(void)
+{
+       SETRST;
+       msdelay(100);
+       CLRRST;
+       msdelay(100);
+       SETRST;
+       msdelay(100);
+}
+
+//! reset the tap logic
+static void openocd_reset_test_logic(void)
+{
+       CLRMOSI;
+       SETTMS;
+       openocd_tcktock();
+       openocd_tcktock();
+       openocd_tcktock();
+       openocd_tcktock();
+       openocd_tcktock(); // now in reset-test-logic
+       CLRTMS;
+       openocd_tcktock();  // now in run-test-idle state
+}
+
+//! sets the LED value
+void openocd_led(int led)
+{
+       if (led)
+               /* turn the LED on */
+               PLEDDIR |= PLEDPIN;
+       else
+               /* turn the LED off */
+               PLEDOUT &= ~PLEDPIN;
+}
+
+//! resets the device/JTAG logic
+void openocd_reset(int trst, int srst)
+{
+       if(srst && trst)
+       {
+               // we need to drive TST from low to high at
+               // the same time as the RST
+               SETTST;
+               SETRST;
+               msdelay(100);
+               CLRTST;
+               CLRRST;
+               msdelay(100);
+               SETTST;
+               SETRST;
+               msdelay(100);
+       }
+       else if (!srst && trst)
+       {
+               openocd_reset_test_logic();
+       }
+       else if(srst && !trst)
+       {
+               openocd_reset_cpu();
+       }
+}
+
+//! updates the tck, tms, and tdi values
+void openocd_write(int tck, int tms, int tdi)
+{
+       if(tms)
+               SETTMS;
+       else
+               CLRTMS;
+
+       if(tdi)
+               SETMOSI;
+       else
+               CLRMOSI;
+
+       if(tck)
+               SETTCK;
+       else
+               CLRTCK;
+}
+
+//! Stop JTAG, release pins
+void openocd_stop()
+{
+       P5OUT=0;
+       P4OUT=0;
+}
+
+//! Set up the pins for JTAG mode.
+void openocd_setup()
+{
+       P5DIR|=MOSI+SCK+TMS;
+       P5DIR&=~MISO;
+       P4DIR|=TST;
+       P2DIR|=RST;
+       msdelay(100);
+}
+
 //! handles OpenOCD commands
 void openocd_handle_fn(uint8_t const app,
                                           uint8_t const verb,
@@ -38,15 +146,38 @@ void openocd_handle_fn(uint8_t const app,
        switch(verb)
        {
                case START:
-                       txdata(app,verb,0);
+                       /* do nothing...*/
+                       txdata(app,OK,0);
                        break;
 
                case STOP:
-                       txdata(app,verb,0);
+                       openocd_stop();
+                       txdata(app,OK,0);
                        break;
 
                case SETUP:
-                       txdata(app,verb,0);
+                       openocd_setup();
+                       txdata(app,OK,0);
+                       break;
+
+               case OPENOCD_RESET:
+                       openocd_reset(cmddata[0], cmddata[1]);
+                       txdata(app,OK,0);
+                       break;
+
+               case OPENOCD_READ:
+                       cmddata[0] = READMISO;
+                       txdata(app,OK,1);
+                       break;
+
+               case OPENOCD_WRITE:
+                       openocd_write(cmddata[0], cmddata[1], cmddata[2]);
+                       txdata(app,OK,0);
+                       break;
+
+               case OPENOCD_LED:
+                       openocd_led(cmddata[0]);
+                       txdata(app,OK,0);
                        break;
 
                default:
index 59f8384..196b2e0 100644 (file)
@@ -8,8 +8,15 @@
 
 #include "app.h"
 
+// OpenOCD app number
 #define OPENOCD 0x18
 
-extern app_t const jtag_app;
+// OpenOCD app verbs
+#define OPENOCD_RESET  0x80
+#define OPENOCD_READ   0x81
+#define OPENOCD_WRITE  0x82
+#define OPENOCD_LED            0x83
+
+extern app_t const openocd_app;
 
 #endif