From: travisutk Date: Sun, 13 Sep 2009 15:57:38 +0000 (+0000) Subject: MSP430F5xx stuff; 1xx support is probably broken right now. X-Git-Url: http://git.rot13.org/?p=goodfet;a=commitdiff_plain;h=1283fdb830f9ecd0e27e10ef66927562aff674a7;hp=2b654b579b948558edecc63dd7ab3aa4543f050d;ds=sidebyside MSP430F5xx stuff; 1xx support is probably broken right now. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@131 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- diff --git a/client/GoodFETMSP430.py b/client/GoodFETMSP430.py index cdb83bb..743ba55 100644 --- a/client/GoodFETMSP430.py +++ b/client/GoodFETMSP430.py @@ -36,26 +36,36 @@ class GoodFETMSP430(GoodFET): (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); @@ -81,21 +91,29 @@ class GoodFETMSP430(GoodFET): 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; diff --git a/client/goodfet.msp430 b/client/goodfet.msp430 index 368cb0f..1e1b8b9 100755 --- a/client/goodfet.msp430 +++ b/client/goodfet.msp430 @@ -4,7 +4,7 @@ import sys; import binascii; from GoodFETMSP430 import GoodFETMSP430; -from intelhex import IntelHex16bit; +from intelhex import IntelHex16bit, IntelHex; @@ -23,13 +23,15 @@ client.serInit() #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(); @@ -43,13 +45,15 @@ if(sys.argv[1]=="dump"): 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>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(); diff --git a/firmware/apps/jtag/jtag.c b/firmware/apps/jtag/jtag.c index af420c7..14e8761 100644 --- a/firmware/apps/jtag/jtag.c +++ b/firmware/apps/jtag/jtag.c @@ -13,8 +13,10 @@ void jtagsetup(){ P5DIR|=MOSI+SCK+TMS; P5DIR&=~MISO; P5OUT|=0xFFFF; + P5OUT=0; P4DIR|=TST; P2DIR|=RST; + msdelay(100); } int savedtclk=0; diff --git a/firmware/apps/jtag/jtag430.c b/firmware/apps/jtag/jtag430.c index 65d4e31..4b7e557 100644 --- a/firmware/apps/jtag/jtag430.c +++ b/firmware/apps/jtag/jtag430.c @@ -191,8 +191,9 @@ void jtag430_eraseflash(unsigned int mode, unsigned int adr, unsigned int count) void jtag430_resettap(){ int i; // Settle output + SETTDI; //430X2 SETTMS; - SETTDI; + //SETTDI; //classic SETTCK; // Navigate to reset state. @@ -211,7 +212,7 @@ void jtag430_resettap(){ /* sacred, by spec. - Sometimes this isn't necessary. */ + Sometimes this isn't necessary. */ // fuse check CLRTMS; delay(50); @@ -273,6 +274,7 @@ void oldjtag430handle(unsigned char app, jtag430_start(); //TAP setup, fuse check jtag430_resettap(); + txdata(app,verb,0); break; case JTAG430_HALTCPU: @@ -287,7 +289,6 @@ void oldjtag430handle(unsigned char app, jtag430_setinstrfetch(); txdata(app,verb,0); break; - case JTAG430_READMEM: case PEEK: @@ -296,8 +297,8 @@ void oldjtag430handle(unsigned char app, 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: diff --git a/firmware/apps/jtag/jtag430x2.c b/firmware/apps/jtag/jtag430x2.c index 5e76aa5..965c262 100644 --- a/firmware/apps/jtag/jtag430x2.c +++ b/firmware/apps/jtag/jtag430x2.c @@ -60,10 +60,10 @@ unsigned long jtag430_deviceid(){ //! 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) @@ -94,10 +94,13 @@ unsigned int jtag430x2_writemem(unsigned long adr, //! 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){ @@ -105,6 +108,7 @@ unsigned int jtag430x2_readmem(unsigned long adr){ }else{ jtag_dr_shift16(0x0511);//byte read } + jtag_ir_shift8(IR_ADDR_16BIT); jtag_dr_shift20(adr); //20 @@ -114,24 +118,85 @@ unsigned int jtag430x2_readmem(unsigned long adr){ 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. @@ -150,16 +215,44 @@ void jtag430x2handle(unsigned char app, 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>8); + } + } + + break; case JTAG430_COREIP_ID: cmddataword[0]=jtag430_coreid(); txdata(app,verb,2); @@ -169,13 +262,15 @@ void jtag430x2handle(unsigned char app, 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: diff --git a/firmware/apps/spi/spi.c b/firmware/apps/spi/spi.c index 21bf66a..e91ab61 100644 --- a/firmware/apps/spi/spi.c +++ b/firmware/apps/spi/spi.c @@ -151,7 +151,7 @@ void spiflash_peek(unsigned char app, 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 @@ -184,7 +184,6 @@ void spihandle(unsigned char app, unsigned char len){ unsigned char i; - //Raise !SS to end transaction, just in case we forgot. P5OUT|=SS; diff --git a/firmware/include/jtag.h b/firmware/include/jtag.h index a681e26..a766b06 100644 --- a/firmware/include/jtag.h +++ b/firmware/include/jtag.h @@ -20,9 +20,12 @@ unsigned long jtagtransn(unsigned long word, 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 @@ -126,3 +129,8 @@ extern int savedtclk; #define MSP430JTAGID 0x89 //MSP430X2 only #define MSP430X2JTAGID 0x91 + +//! Syncs a POR. +unsigned int jtag430x2_syncpor(); +//! Executes an MSP430X2 POR +unsigned int jtag430x2_por();