(ord(self.data[2])<<16)+(ord(self.data[3])<<24));
return DeviceID;
def MSP430peek(self,adr):
- """Read the contents of memory at an address."""
+ """Read a word at an address."""
self.data=[adr&0xff, (adr&0xff00)>>8,
- (adr&0xff0000)>>16,(adr&0xff000000)>>24];
- self.writecmd(self.MSP430APP,0x02,4,self.data);
+ (adr&0xff0000)>>16,(adr&0xff000000)>>24,
+ ];
+ self.writecmd(self.MSP430APP,0x02,4,self.data,1);
return ord(self.data[0])+(ord(self.data[1])<<8);
+ def MSP430peekblock(self,adr,blocks=1):
+ """Grab a few block from an SPI Flash ROM. Block size is unknown"""
+ data=[adr&0xff, (adr&0xff00)>>8,
+ (adr&0xff0000)>>16,(adr&0xff000000)>>24,
+ blocks];
+
+ self.writecmd(self.MSP430APP,0x02,5,data,blocks);
+ return self.data;
+
def MSP430poke(self,adr,val):
"""Write the contents of memory at an address."""
- self.data=[adr&0xff, (adr&0xff00)>>8, val&0xff, (val&0xff00)>>8];
- self.writecmd(self.MSP430APP,0x03,4,self.data);
+ self.data=[adr&0xff, (adr&0xff00)>>8,
+ (adr&0xff0000)>>16,(adr&0xff000000)>>24,
+ val&0xff, (val&0xff00)>>8];
+ self.writecmd(self.MSP430APP,0x03,6,self.data);
return ord(self.data[0])+(ord(self.data[1])<<8);
def MSP430start(self):
"""Start debugging."""
self.writecmd(self.MSP430APP,0x20,0,self.data);
self.JTAGID=ord(self.data[0]);
- #print "Identified as %02x." % id;
- if(self.JTAGID==0x89 or self.JTAGID==0x91):
- print "Successfully connected."
- else:
+ #print "Identified as %02x." % self.JTAGID;
+ if(not (self.JTAGID==0x89 or self.JTAGID==0x91)):
print "Error, misidentified as %02x." % id;
-
+
def MSP430haltcpu(self):
"""Halt the CPU."""
self.writecmd(self.MSP430APP,0xA0,0,self.data);
if(self.JTAGID==0x89):
i=self.MSP430peek(0x0ff0);
ident=((i&0xFF00)>>8)+((i&0xFF)<<8)
+
if(self.JTAGID==0x91):
i=self.MSP430peek(0x1A04);
ident=((i&0xFF00)>>8)+((i&0xFF)<<8)
+ #ident=0x0091;
+
return ident;
def MSP430test(self):
"""Test MSP430 JTAG. Requires that a chip be attached."""
if self.MSP430ident()==0xffff:
print "Is anything connected?";
- print "Testing RAM.";
- temp=self.MSP430peek(0x0200);
- self.MSP430poke(0x0200,0xdead);
- if(self.MSP430peek(0x0200)!=0xdead):
- print "Poke of 0x0200 did not set to 0xDEAD properly.";
- return;
- self.MSP430poke(0x0200,temp); #restore old value.
+ print "Testing RAM from 1c00 to 1d00.";
+ for a in range(0x1c00,0x1d00):
+ self.MSP430poke(a,0);
+ if(self.MSP430peek(a)!=0):
+ print "Fault at %06x" % a;
+ self.MSP430poke(a,0xffff);
+ if(self.MSP430peek(a)!=0xffff):
+ print "Fault at %06x" % a;
+ print "RAM Test Complete."
+ for a in range(1,5):
+ print "Identity %04x" % self.MSP430ident();
+
def MSP430flashtest(self):
self.MSP430masserase();
i=0x2500;
import binascii;
from GoodFETMSP430 import GoodFETMSP430;
-from intelhex import IntelHex16bit;
+from intelhex import IntelHex16bit, IntelHex;
#Connect to target
client.MSP430setup();
+#print "setup"
#Identify model number.
client.MSP430start();
+#print "started"
if(sys.argv[1]=="info"):
- print "Model %04x " % client.MSP430coreid();
- print "Core %08x " % client.MSP430deviceid();
+ print "Model %08x " % client.MSP430deviceid();
+ print "Core %04x " % client.MSP430coreid();
print "Identity %04x" % client.MSP430ident();
if(sys.argv[1]=="test"):
client.MSP430test();
stop=int(sys.argv[4],16);
print "Dumping from %04x to %04x as %s." % (start,stop,f);
- h = IntelHex16bit(None);
+ #h = IntelHex16bit(None);
+ h = IntelHex(None);
i=start;
- while i<stop:
- h[i>>1]=client.MSP430peek(i);
- if(i%0x100==0):
- print "Dumped %04x."%i;
- i+=2;
+ while i<=stop:
+ data=client.MSP430peekblock(i,0x20);
+ print "Dumped %06x."%i;
+ for j in data:
+ if i<=stop: h[i]=ord(j);
+ i+=1;
h.write_hex_file(f);
if(sys.argv[1]=="erase"):
client.MSP430masserase();
P5DIR|=MOSI+SCK+TMS;
P5DIR&=~MISO;
P5OUT|=0xFFFF;
+ P5OUT=0;
P4DIR|=TST;
P2DIR|=RST;
+ msdelay(100);
}
int savedtclk=0;
void jtag430_resettap(){
int i;
// Settle output
+ SETTDI; //430X2
SETTMS;
- SETTDI;
+ //SETTDI; //classic
SETTCK;
// Navigate to reset state.
/* sacred, by spec.
- Sometimes this isn't necessary. */
+ Sometimes this isn't necessary. */
// fuse check
CLRTMS;
delay(50);
jtag430_start();
//TAP setup, fuse check
jtag430_resettap();
+
txdata(app,verb,0);
break;
case JTAG430_HALTCPU:
jtag430_setinstrfetch();
txdata(app,verb,0);
break;
-
case JTAG430_READMEM:
case PEEK:
break;
case JTAG430_WRITEMEM:
case POKE:
- jtag430_writemem(cmddataword[0],cmddataword[1]);
- cmddataword[0]=jtag430_readmem(cmddataword[0]);
+ jtag430_writemem(cmddatalong[0],cmddataword[2]);
+ cmddataword[0]=jtag430_readmem(cmddatalong[0]);
txdata(app,verb,2);
break;
case JTAG430_WRITEFLASH:
//! Write data to address
-unsigned int jtag430x2_writemem(unsigned long adr,
- unsigned long data){
+void jtag430x2_writemem(unsigned long adr,
+ unsigned int data){
jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
- if(jtag_ir_shift8(0) & 0x0301){
+ if(jtag_dr_shift16(0) & 0x0301){
CLRTCLK;
jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
if(adr>=0x100)
//! Read data from address
unsigned int jtag430x2_readmem(unsigned long adr){
unsigned int toret=0;
-
- jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
+
+ do{
+ jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
+ }while(!(jtag_dr_shift16(0) & 0x0301));
+
if(jtag_dr_shift16(0) & 0x0301){
- // Read Memory
+ // Read Memory
CLRTCLK;
jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
if(adr>=0x100){
}else{
jtag_dr_shift16(0x0511);//byte read
}
+
jtag_ir_shift8(IR_ADDR_16BIT);
jtag_dr_shift20(adr); //20
toret = jtag_dr_shift16(0x0000);
SETTCLK;
- // one or more cycle, so CPU is driving correct MAB
-
+
+ //Cycle a bit.
CLRTCLK;
SETTCLK;
- // Processor is now again in Init State
}else{
- return 0xDEAD;
+ return 0xBABE;
}
return toret;
}
+//! Syncs a POR.
+unsigned int jtag430x2_syncpor(){
+ jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
+ jtag_dr_shift16(0x1501); //JTAG mode
+ while(!(jtag_dr_shift16(0) & 0x200));
+ return jtag430x2_por();
+}
+
+//! Executes an MSP430X2 POR
+unsigned int jtag430x2_por(){
+ unsigned int i = 0;
+
+ // tick
+ CLRTCLK;
+ SETTCLK;
+
+ jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
+ jtag_dr_shift16(0x0C01);
+ jtag_dr_shift16(0x0401);
+
+ //cycle
+ for (i = 0; i < 10; i++){
+ CLRTCLK;
+ SETTCLK;
+ }
+
+ jtag_dr_shift16(0x0501);
+
+ // tick
+ CLRTCLK;
+ SETTCLK;
+
+
+ // Disable WDT
+ jtag430x2_writemem(0x015C, 0x5A80);
+
+ // check state
+ jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
+ if(jtag_dr_shift16(0) & 0x0301)
+ return(1);//ok
+
+ return 0;//error
+}
+
+
+//! Check the fuse.
+unsigned int jtag430x2_fusecheck(){
+ int i;
+ for(i=0;i<3;i++){
+ jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
+ if(jtag_dr_shift16(0xAAAA)==0x5555)
+ return 1;//blown
+ }
+ return 0;//unblown
+}
-//! Handles classic MSP430 JTAG commands. Forwards others to JTAG.
+
+//! Handles MSP430X2 JTAG commands. Forwards others to JTAG.
void jtag430x2handle(unsigned char app,
- unsigned char verb,
- unsigned char len){
- jtag430_resettap();
+ unsigned char verb,
+ unsigned char len){
+ register char blocks;
+
+ unsigned int i,val;
+ unsigned long at;
+
+ //jtag430_resettap();
+
switch(verb){
case START:
//Enter JTAG mode.
return;
}
- //TAP setup, fuse check
- //jtag430_resettap();
+ jtag430x2_fusecheck();
+
+ jtag430x2_syncpor();
+
+ jtag430_resettap();
+
txdata(app,verb,1);
break;
case JTAG430_READMEM:
case PEEK:
- //cmddataword[0]=jtag430x2_readmem(cmddataword[0]);
- cmddataword[0]=jtag430x2_readmem(cmddatalong[0]);
+ blocks=(len>4?cmddata[4]:1);
+ at=cmddatalong[0];
+
+ /*
+ cmddataword[0]=jtag430x2_readmem(at);
txdata(app,verb,2);
break;
+ */
+
+ len=0x80;
+ serial_tx(app);
+ serial_tx(verb);
+ serial_tx(len);
+
+ while(blocks--){
+ for(i=0;i<len;i+=2){
+ jtag430_resettap();
+ delay(10);
+
+ val=jtag430x2_readmem(at);
+
+ at+=2;
+ serial_tx(val&0xFF);
+ serial_tx((val&0xFF00)>>8);
+ }
+ }
+
+ break;
case JTAG430_COREIP_ID:
cmddataword[0]=jtag430_coreid();
txdata(app,verb,2);
txdata(app,verb,4);
break;
case JTAG430_HALTCPU:
+ //jtag430x2_haltcpu();
+ break;
case JTAG430_RELEASECPU:
case JTAG430_SETINSTRFETCH:
case JTAG430_WRITEMEM:
case POKE:
- jtag430x2_writemem(cmddataword[0],
- cmddataword[1]);
- cmddataword[0]=jtag430x2_readmem(cmddataword[0]);
+ jtag430x2_writemem(cmddatalong[0],
+ cmddataword[2]);
+ cmddataword[0]=jtag430x2_readmem(cmddatalong[0]);
txdata(app,verb,2);
break;
case JTAG430_WRITEFLASH:
unsigned char verb,
unsigned char len){
register char blocks=(len>3?cmddata[3]:1);
- unsigned char i,j;
+ unsigned char i;
P5OUT&=~SS; //Drop !SS to begin transaction.
spitrans8(0x03);//Flash Read Command
unsigned char len){
unsigned char i;
-
//Raise !SS to end transaction, just in case we forgot.
P5OUT|=SS;
unsigned char jtag_ir_shift8(unsigned char);
//! Shift 16 bits of the DR.
unsigned int jtag_dr_shift16(unsigned int);
+//! Shift 20 bits of the DR, MSP430 specific.
+unsigned long jtag_dr_shift20(unsigned long in);
//! Stop JTAG, release pins
void jtag_stop();
+//! Setup the JTAG pin directions.
void jtagsetup();
// JTAG430 Commands
#define MSP430JTAGID 0x89
//MSP430X2 only
#define MSP430X2JTAGID 0x91
+
+//! Syncs a POR.
+unsigned int jtag430x2_syncpor();
+//! Executes an MSP430X2 POR
+unsigned int jtag430x2_por();