From b606e1a567586b0498a0632142904ad1a79d6e44 Mon Sep 17 00:00:00 2001 From: dwhuseby Date: Wed, 9 Feb 2011 10:28:27 +0000 Subject: [PATCH] starting OpenOCD app and client changes for JTAG work that didn't go in earlier. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@901 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- client/GoodFETJTAG.py | 54 ++++++++++++-- client/GoodFETXSCALE.py | 36 +++------ client/goodfet.jtag | 57 ++++++++++++++ client/goodfet.xscale | 25 ++++--- firmware/Makefile | 15 ++++ firmware/apps/jtag/openocd.c | 139 ++++++++++++++++++++++++++++++++++- firmware/include/openocd.h | 9 ++- 7 files changed, 291 insertions(+), 44 deletions(-) create mode 100755 client/goodfet.jtag diff --git a/client/GoodFETJTAG.py b/client/GoodFETJTAG.py index 4dc4061..b579d74 100644 --- a/client/GoodFETJTAG.py +++ b/client/GoodFETJTAG.py @@ -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 diff --git a/client/GoodFETXSCALE.py b/client/GoodFETXSCALE.py index f71b52e..f9b0c33 100644 --- a/client/GoodFETXSCALE.py +++ b/client/GoodFETXSCALE.py @@ -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("> 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 index 0000000..e91c476 --- /dev/null +++ b/client/goodfet.jtag @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# GoodFET Basic JTAG +# +# (C) 2009 Travis Goodspeed +# (C) 2011 Dave Huseby +# +# 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 -- 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()) + diff --git a/client/goodfet.xscale b/client/goodfet.xscale index 7c6e95b..f3be147 100755 --- a/client/goodfet.xscale +++ b/client/goodfet.xscale @@ -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 " % 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() diff --git a/firmware/Makefile b/firmware/Makefile index a4ffb43..51e8ba6 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -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 diff --git a/firmware/apps/jtag/openocd.c b/firmware/apps/jtag/openocd.c index 6a0e4c1..feb8e57 100644 --- a/firmware/apps/jtag/openocd.c +++ b/firmware/apps/jtag/openocd.c @@ -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: diff --git a/firmware/include/openocd.h b/firmware/include/openocd.h index 59f8384..196b2e0 100644 --- a/firmware/include/openocd.h +++ b/firmware/include/openocd.h @@ -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 -- 2.20.1