From 0fb25630e9970a4e6d18e190c484f654490565b0 Mon Sep 17 00:00:00 2001 From: travisutk Date: Fri, 4 Sep 2009 06:37:08 +0000 Subject: [PATCH] JTAG430X2 works at 16MHz, not at 3MHz. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@119 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- firmware/Makefile | 2 +- firmware/apps/jtag/jtag.c | 63 ++++++++++++++++++++++----- firmware/apps/jtag/jtag430.c | 44 +++++++++---------- firmware/apps/jtag/jtag430x2.c | 79 ++++++++++++++++++++++++++++++++++ firmware/goodfet.c | 17 +------- firmware/include/command.h | 5 +++ firmware/include/jtag.h | 16 ++++++- firmware/lib/command.c | 10 +++++ 8 files changed, 186 insertions(+), 50 deletions(-) create mode 100644 firmware/apps/jtag/jtag430x2.c diff --git a/firmware/Makefile b/firmware/Makefile index 2317458..41c9edf 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -19,7 +19,7 @@ CC=msp430-gcc -Wall -g -mmcu=$(mcu) -DGCC $(GCCINC) -I include $(CCEXTRA) #Define extra modules here. moreapps?= -apps= $(moreapps) apps/monitor/monitor.o apps/spi/spi.o apps/i2c/i2c.o apps/chipcon/chipcon.o apps/jtag/jtag.o apps/jtag/jtag430.o +apps= $(moreapps) apps/monitor/monitor.o apps/spi/spi.o apps/i2c/i2c.o apps/chipcon/chipcon.o apps/jtag/jtag.o apps/jtag/jtag430.o apps/jtag/jtag430x2.o libs= lib/$(mcu).o lib/command.o apps/jtag/jtag430asm.o app= goodfet diff --git a/firmware/apps/jtag/jtag.c b/firmware/apps/jtag/jtag.c index ea02b40..4dc7021 100644 --- a/firmware/apps/jtag/jtag.c +++ b/firmware/apps/jtag/jtag.c @@ -51,12 +51,13 @@ 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; SAVETCLK; - for (bit = 0; bit < 16; bit++) { + for (bit = 0; bit < bitcount; bit++) { /* write MOSI on trailing edge of previous clock */ if (word & 0x8000) {SETMOSI;} @@ -64,12 +65,12 @@ unsigned int jtagtrans16(unsigned int word){ {CLRMOSI;} word <<= 1; - if(bit==15) + if(bit==bitcount-1) SETTMS;//TMS high on last bit to exit. CLRTCK; SETTCK; - /* read MISO on trailing edge */ + /* read MISO on trailing edge */ word |= READMISO; } RESTORETCLK; @@ -85,15 +86,50 @@ unsigned int jtagtrans16(unsigned int word){ 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;} + else + {CLRMOSI;} + word <<= 1; + + if(bit==15) + SETTMS;//TMS high on last bit to exit. + + CLRTCK; + SETTCK; + // read MISO on trailing edge + word |= READMISO; + } + RESTORETCLK; + + // exit state + CLRTCK; + SETTCK; + // update state + CLRTMS; + CLRTCK; + SETTCK; + + return word; +}*/ + //! Stop JTAG, release pins void jtag_stop(){ P5OUT=0; P4OUT=0; } - -//! Shift 16 bits of the DR. -unsigned int jtag_dr_shift16(unsigned int in){ +unsigned int drwidth=20; +//! Shift all bits of the DR. +unsigned long jtag_dr_shift(unsigned long in){ // idle SETTMS; CLRTCK; @@ -105,9 +141,16 @@ unsigned int jtag_dr_shift16(unsigned int in){ // capture IR CLRTCK; SETTCK; - + // shift DR, then idle - return(jtagtrans16(in)); + return(jtagtransn(in,drwidth)); +} + + +//! Shift 16 bits of the DR. +unsigned int jtag_dr_shift16(unsigned int in){ + //This name is deprecated, kept around to find 16-bit dependent code. + return jtag_dr_shift(in); } diff --git a/firmware/apps/jtag/jtag430.c b/firmware/apps/jtag/jtag430.c index 123eefa..d518ca1 100644 --- a/firmware/apps/jtag/jtag430.c +++ b/firmware/apps/jtag/jtag430.c @@ -4,6 +4,8 @@ #include "jtag.h" +unsigned int jtag430mode=MSP430X2MODE; + //! Set the program counter. void jtag430_setpc(unsigned int adr){ jtag_ir_shift8(IR_CNTRL_SIG_16BIT); @@ -79,27 +81,6 @@ void jtag430_writemem(unsigned int adr, unsigned int data){ SETTCLK; } -//! Defined in jtag430asm.S -void jtag430_tclk_flashpulses(int); -/* //! Pulse TCLK at 350kHz +/- 100kHz */ -/* void jtag430_tclk_flashpulses(register i){ */ -/* //TODO check this on a scope. */ -/* register j=0; */ - -/* //At 2MHz, 350kHz is obtained with 5 clocks of delay */ - -/* /\** Pondering: */ -/* What happens if the frequency is too low or to high? */ -/* Is there any risk of damaging the chip, or only of a poor write? */ -/* *\/ */ -/* while(j++!=i){ */ -/* SETTCLK; */ -/* _NOP(); */ -/* _NOP(); */ -/* _NOP(); */ -/* CLRTCLK; */ -/* } */ -/* } */ //! Write data to flash memory. Must be preconfigured. void jtag430_writeflashword(unsigned int adr, unsigned int data){ @@ -149,6 +130,8 @@ void jtag430_writeflash(unsigned int adr, unsigned int data){ jtag430_releasecpu(); } + + //! Power-On Reset void jtag430_por(){ unsigned int jtagid; @@ -278,10 +261,12 @@ void jtag430_setinstrfetch(){ } } -//! Handles unique MSP430 JTAG commands. Forwards others to JTAG. -void jtag430handle(unsigned char app, + +//! Handles classic MSP430 JTAG commands. Forwards others to JTAG. +void oldjtag430handle(unsigned char app, unsigned char verb, unsigned char len){ + switch(verb){ case START: //Enter JTAG mode. @@ -336,3 +321,16 @@ void jtag430handle(unsigned char app, jtag430_resettap(); } +//! Handles unique MSP430 JTAG commands. Forwards others to JTAG. +void jtag430handle(unsigned char app, + unsigned char verb, + unsigned char len){ + switch(jtag430mode){ + case MSP430MODE: + return oldjtag430handle(app,verb,len); + case MSP430X2MODE: + return jtag430x2handle(app,verb,len); + default: + txdata(app,NOK,0); + } +} diff --git a/firmware/apps/jtag/jtag430x2.c b/firmware/apps/jtag/jtag430x2.c new file mode 100644 index 0000000..0de9a44 --- /dev/null +++ b/firmware/apps/jtag/jtag430x2.c @@ -0,0 +1,79 @@ +/*! \file jtag430x2.c + \author Travis Goodspeed + + This is an implementation of the MSP430X2 JTAG protocol + for the GoodFET project at http://goodfet.sf.net/ + + See the license file for details of proper use. +*/ + +#include "platform.h" +#include "command.h" +#include "jtag.h" + +unsigned char jtagid; + +//! Get the JTAG ID +unsigned char jtag430x2_jtagid(){ + jtag430_resettap(); + return jtagid=jtag_ir_shift8(IR_BYPASS); +} +//! Start JTAG, take pins +unsigned char jtag430x2_start(){ + jtagsetup(); + P1OUT^=1; + + //Known-good starting position. + //Might be unnecessary. + SETTST; + SETRST; + + delay(0xFFFF); + + //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG + CLRRST; + delay(10); + CLRTST; + delay(5); + SETTST; + msdelay(5); + SETRST; + P5DIR&=~RST; + + delay(0xFFFF); + + //Perform a reset and disable watchdog. + return jtag430x2_jtagid(); +} + + +//! Handles classic MSP430 JTAG commands. Forwards others to JTAG. +void jtag430x2handle(unsigned char app, + unsigned char verb, + unsigned char len){ + + switch(verb){ + case START: + //Enter JTAG mode. + do cmddata[0]=jtag430x2_start(); + while(cmddata[0]==00 || cmddata[0]==0xFF); + + //TAP setup, fuse check + //jtag430_resettap(); + txdata(app,verb,1); + break; + case JTAG430_HALTCPU: + case JTAG430_RELEASECPU: + case JTAG430_SETINSTRFETCH: + case JTAG430_READMEM: + case PEEK: + case JTAG430_WRITEMEM: + case POKE: + case JTAG430_WRITEFLASH: + case JTAG430_ERASEFLASH: + case JTAG430_SETPC: + default: + jtaghandle(app,verb,len); + } + jtag430_resettap(); +} diff --git a/firmware/goodfet.c b/firmware/goodfet.c index 7d4a88a..00dd921 100644 --- a/firmware/goodfet.c +++ b/firmware/goodfet.c @@ -46,8 +46,8 @@ void handle(unsigned char app, case JTAG: jtaghandle(app,verb,len); break; - case JTAG430: - jtag430handle(app,verb,len); + case JTAG430: //Also JTAG430X, JTAG430X2 + jtag430x2handle(app,verb,len); break; default: #ifdef HANDLEOTHER @@ -67,19 +67,6 @@ int main(void) init(); - - //Ready - //txdata(MONITOR,OK,0); - //while (1){ - // txdata(0xFF,0xff,0x0); - // delay(1000); - //} - //delay(0xffff); - //while(*((int*)0x1001)); - - //while(1) - // txdata(0xFF,0xFF,0); - txstring(MONITOR,OK,"http://goodfet.sf.net/"); //Command loop. There's no end! diff --git a/firmware/include/command.h b/firmware/include/command.h index 8cc3f4f..78f3302 100644 --- a/firmware/include/command.h +++ b/firmware/include/command.h @@ -88,6 +88,8 @@ void txstring(unsigned char app, //! Delay void delay(unsigned int count); +//! MSDelay +void msdelay(unsigned int ms); void monitorhandle(unsigned char, unsigned char, unsigned char); @@ -96,3 +98,6 @@ void i2chandle(unsigned char, unsigned char, unsigned char); void cchandle(unsigned char, unsigned char, unsigned char); void jtaghandle(unsigned char, unsigned char, unsigned char); void jtag430handle(unsigned char, unsigned char, unsigned char); +void jtag430x2handle(unsigned char app, unsigned char verb, + unsigned char len); + diff --git a/firmware/include/jtag.h b/firmware/include/jtag.h index 1551d79..c1abdf3 100644 --- a/firmware/include/jtag.h +++ b/firmware/include/jtag.h @@ -4,8 +4,18 @@ #include +extern unsigned int drwidth; + +#define MSP430MODE 0 +#define MSP430XMODE 1 +#define MSP430X2MODE 2 +extern unsigned int jtag430mode; + // Generic Commands +//! Shift n bytes. +unsigned long jtagtransn(unsigned long word, + unsigned int bitcount); //! Shift 8 bits of the IR. unsigned char jtag_ir_shift8(unsigned char); //! Shift 16 bits of the DR. @@ -22,6 +32,9 @@ void jtag430_start(); //! Reset the TAP state machine, check the fuse. void jtag430_resettap(); +//! Defined in jtag430asm.S +void jtag430_tclk_flashpulses(int); + //High-level Macros follow //! Write data to address. void jtag430_writemem(unsigned int adr, unsigned int data); @@ -84,7 +97,8 @@ extern int savedtclk; #define SAVETCLK savedtclk=P5OUT&TCLK; #define RESTORETCLK if(savedtclk) P5OUT|=TCLK; else P5OUT&=~TCLK -//JTAG commands, bit-swapped + +//16-bit MSP430 JTAG commands, bit-swapped #define IR_CNTRL_SIG_16BIT 0xC8 // 0x13 #define IR_CNTRL_SIG_CAPTURE 0x28 // 0x14 #define IR_CNTRL_SIG_RELEASE 0xA8 // 0x15 diff --git a/firmware/lib/command.c b/firmware/lib/command.c index 08a5cf7..f585e4c 100644 --- a/firmware/lib/command.c +++ b/firmware/lib/command.c @@ -36,3 +36,13 @@ void delay(unsigned int count){ volatile unsigned int i=count; while(i--) asm("nop"); } +//! MSDelay +void msdelay(unsigned int ms){ + volatile unsigned int i,j; + i=100; + while(i--){ + j=ms; + while(j--) asm("nop"); + } + //Using TimerA might be cleaner. +} -- 2.20.1