X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Fjtag%2Fjtag430x2.c;h=965c2626eef287344aaff2bed93d6b53dda390a4;hp=e49634679000aa620a88d734d0ec5b5a2cd74e51;hb=1283fdb830f9ecd0e27e10ef66927562aff674a7;hpb=4b2f28239ea1c0f76117e813fc8838f8a368d2bf diff --git a/firmware/apps/jtag/jtag430x2.c b/firmware/apps/jtag/jtag430x2.c index e496346..965c262 100644 --- a/firmware/apps/jtag/jtag430x2.c +++ b/firmware/apps/jtag/jtag430x2.c @@ -46,24 +46,61 @@ unsigned char jtag430x2_start(){ return jtag430x2_jtagid(); } +//! Grab the core ID. unsigned int jtag430_coreid(){ jtag_ir_shift8(IR_COREIP_ID); return jtag_dr_shift16(0); } +//! Grab the device ID. unsigned long jtag430_deviceid(){ jtag_ir_shift8(IR_DEVICE_ID); return jtag_dr_shift20(0); } +//! Write data to address +void jtag430x2_writemem(unsigned long adr, + unsigned int data){ + jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE); + if(jtag_dr_shift16(0) & 0x0301){ + CLRTCLK; + jtag_ir_shift8(IR_CNTRL_SIG_16BIT); + if(adr>=0x100) + jtag_dr_shift16(0x0500);//word mode + else + jtag_dr_shift16(0x0510);//byte mode + jtag_ir_shift8(IR_ADDR_16BIT); + jtag_dr_shift20(adr); + + SETTCLK; + + jtag_ir_shift8(IR_DATA_TO_ADDR); + jtag_dr_shift16(data);//16 word + + CLRTCLK; + jtag_ir_shift8(IR_CNTRL_SIG_16BIT); + jtag_dr_shift16(0x0501); + SETTCLK; + + CLRTCLK; + SETTCLK; + //init state + }else{ + while(1) P1OUT^=1; //loop if locked up + } +} + //! 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){ @@ -71,8 +108,9 @@ unsigned int jtag430x2_readmem(unsigned long adr){ }else{ jtag_dr_shift16(0x0511);//byte read } + jtag_ir_shift8(IR_ADDR_16BIT); - jtag_dr_shift20(adr); + jtag_dr_shift20(adr); //20 jtag_ir_shift8(IR_DATA_TO_ADDR); SETTCLK; @@ -80,23 +118,84 @@ 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 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; - return toret; + // 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 } -//! Handles classic MSP430 JTAG commands. Forwards others to JTAG. +//! 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 MSP430X2 JTAG commands. Forwards others to JTAG. void jtag430x2handle(unsigned char app, - unsigned char verb, - unsigned char len){ + unsigned char verb, + unsigned char len){ + register char blocks; + + unsigned int i,val; + unsigned long at; + + //jtag430_resettap(); switch(verb){ case START: @@ -116,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]=jtag430_readmem(cmddataword[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); @@ -135,10 +262,17 @@ 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(cmddatalong[0], + cmddataword[2]); + cmddataword[0]=jtag430x2_readmem(cmddatalong[0]); + txdata(app,verb,2); + break; case JTAG430_WRITEFLASH: case JTAG430_ERASEFLASH: case JTAG430_SETPC: