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
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
OK = 0x7F
# XSCALE JTAG verbs
-GET_CHIP_ID = 0xF1
+# verbs start at 0xF0
from GoodFETJTAG import GoodFETJTAG
from intelhex import IntelHex
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
-
--- /dev/null
+#!/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())
+
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()
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()
# jtagarm7 -- ARM7TDMI JTAG
# ejtag -- MIPS JTAG
# jtagxscale -- XScale JTAG
+# openocd -- OpenOCD bitbang device
# Microcontrollers:
# chipcon -- Chipcon radio 8051 debugging
# 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
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
#include "platform.h"
#include "command.h"
+#include "openocd.h"
+#include "jtag.h"
#define 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,
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:
#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