#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
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;}
{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;
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;
// 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);
}
#include "jtag.h"
+unsigned int jtag430mode=MSP430X2MODE;
+
//! Set the program counter.
void jtag430_setpc(unsigned int adr){
jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
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){
jtag430_releasecpu();
}
+
+
//! Power-On Reset
void jtag430_por(){
unsigned int jtagid;
}
}
-//! 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.
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);
+ }
+}
--- /dev/null
+/*! \file jtag430x2.c
+ \author Travis Goodspeed <travis at radiantmachines.com>
+
+ 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();
+}
case JTAG:\r
jtaghandle(app,verb,len);\r
break;\r
- case JTAG430:\r
- jtag430handle(app,verb,len);\r
+ case JTAG430: //Also JTAG430X, JTAG430X2\r
+ jtag430x2handle(app,verb,len);\r
break;\r
default:\r
#ifdef HANDLEOTHER\r
\r
init();\r
\r
- \r
- //Ready\r
- //txdata(MONITOR,OK,0);\r
- //while (1){\r
- // txdata(0xFF,0xff,0x0);\r
- // delay(1000);\r
- //}\r
- //delay(0xffff);\r
- //while(*((int*)0x1001));\r
- \r
- //while(1)\r
- // txdata(0xFF,0xFF,0);\r
- \r
txstring(MONITOR,OK,"http://goodfet.sf.net/");\r
\r
//Command loop. There's no end!\r
//! Delay
void delay(unsigned int count);
+//! MSDelay
+void msdelay(unsigned int ms);
void monitorhandle(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);
+
#include <iomacros.h>
+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.
//! 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);
#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
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.
+}