2 \author Travis Goodspeed and Mark Rages
3 \brief Spy-Bi-Wire Mod of JTAG430 and JTAG430X
5 As SBW is merely a multiplexed method of handling JTAG signals, this
6 module works by replacing preprocessor definitions in the
7 traditional modules to make them SBW compatible. Function pointers
8 would be size efficient, but so it goes.
19 // define the sbw app's app_t
20 app_t const sbw_app = {
31 "\tThe SBW app adds to the basic JTAG app\n"
32 "\tsupport for SBW'ing MSP430 devices with two wires.\n"
35 //! Shift 8 bits in and out.
36 unsigned char sbwtrans8(unsigned char byte){
39 for (bit = 0; bit < 8; bit++) {
40 /* write MOSI on trailing edge of previous clock */
48 SETTMS;//TMS high on last bit to exit.
51 /* read MISO on trailing edge */
63 //! Shift n bits in and out.
64 unsigned long sbwtransn(unsigned long word,
65 unsigned int bitcount){
68 unsigned long high=0x8000;
77 for (bit = 0; bit < bitcount; bit++) {
78 /* write MOSI on trailing edge of previous clock */
86 SETTMS;//TMS high on last bit to exit.
89 /* read MISO on trailing edge */
94 word = ((word << 16) | (word >> 4)) & 0x000FFFFF;
108 //! Shift all bits of the DR.
109 u32 sbw_dr_shift20(unsigned long in){
119 // shift DR, then idle
120 return(sbwtransn(in,20));
124 //! Shift 16 bits of the DR.
125 u16 sbw_dr_shift16(unsigned int in){
135 // shift DR, then idle
136 return(sbwtransn(in,16));
140 //! Shift 8 bits of the IR.
141 u8 sbw_ir_shift8(unsigned char in){
153 // shift IR, then idle.
154 return(sbwtrans8(in));
158 //FIXME these should be prefixed with sbw
159 //to prevent name pollution.
160 int tms=1, tdi=1, tdo=0;
172 P5DIR &= ~SBWTDIO; //input mode
173 P5OUT &= ~SBWTCK; //Drop Metaclock
174 tdo=!!(P5IN & SBWTDIO);
175 P5OUT |= SBWTCK; //output mode
176 P5DIR |= SBWTDIO; //Raise Metaclock
186 SETSBWIO(1);asm("nop");asm("nop");
187 SETSBWIO(0);asm("nop");asm("nop");
188 SETSBWIO(1);asm("nop");asm("nop");
189 SETSBWIO(0);asm("nop");asm("nop");
190 SETSBWIO(1);asm("nop");asm("nop");
196 //tdo=!!(P5IN & SBWTDIO);
205 SETSBWIO(0);asm("nop");asm("nop");
206 SETSBWIO(1);asm("nop");asm("nop");
207 SETSBWIO(0);asm("nop");asm("nop");
208 SETSBWIO(1);asm("nop");asm("nop");
209 SETSBWIO(0);asm("nop");asm("nop");
215 //tdo=!!(P5IN & SBWTDIO);
223 //! Set the program counter.
224 void sbw430_setpc(unsigned int adr){
225 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
226 sbw_dr_shift16(0x3401);// release low byte
227 sbw_ir_shift8(IR_DATA_16BIT);
228 sbw_dr_shift16(0x4030);//Instruction to load PC
231 sbw_dr_shift16(adr);// Value for PC
233 sbw_ir_shift8(IR_ADDR_CAPTURE);
235 CLRTCLK ;// Now PC is set to "PC_Value"
236 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
237 sbw_dr_shift16(0x2401);// low byte controlled by SBW
241 void sbw430_haltcpu(){
242 //sbw430_setinstrfetch();
244 sbw_ir_shift8(IR_DATA_16BIT);
245 sbw_dr_shift16(0x3FFF);//JMP $+0
248 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
249 sbw_dr_shift16(0x2409);//set SBW_HALT bit
254 void sbw430_releasecpu(){
256 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
257 sbw_dr_shift16(0x2401);
258 sbw_ir_shift8(IR_ADDR_CAPTURE);
262 //! Read data from address
263 unsigned int sbw430_readmem(unsigned int adr){
268 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
271 sbw_dr_shift16(0x2409);//word read
273 sbw_dr_shift16(0x2419);//byte read
274 sbw_ir_shift8(IR_ADDR_16BIT);
275 sbw_dr_shift16(adr);//address
276 sbw_ir_shift8(IR_DATA_TO_ADDR);
280 toret=sbw_dr_shift16(0x0000);//16 bit return
285 //! Write data to address.
286 void sbw430_writemem(unsigned int adr, unsigned int data){
288 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
290 sbw_dr_shift16(0x2408);//word write
292 sbw_dr_shift16(0x2418);//byte write
293 sbw_ir_shift8(IR_ADDR_16BIT);
295 sbw_ir_shift8(IR_DATA_TO_ADDR);
296 sbw_dr_shift16(data);
300 //! Write data to flash memory. Must be preconfigured.
301 void sbw430_writeflashword(unsigned int adr, unsigned int data){
304 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
305 sbw_dr_shift16(0x2408);//word write
306 sbw_ir_shift8(IR_ADDR_16BIT);
308 sbw_ir_shift8(IR_DATA_TO_ADDR);
309 sbw_dr_shift16(data);
312 //Return to read mode.
314 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
315 sbw_dr_shift16(0x2409);
318 sbw430_writemem(adr,data);
320 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
321 sbw_dr_shift16(0x2409);
324 debugstr("ERROR: Haven't got ASM to flash-pulse SBW.");
327 //sbw430_tclk_flashpulses(35); //35 standard
330 //! Configure flash, then write a word.
331 void sbw430_writeflash(unsigned int adr, unsigned int data){
334 //FCTL1=0xA540, enabling flash write
335 sbw430_writemem(0x0128, 0xA540);
336 //FCTL2=0xA540, selecting MCLK as source, DIV=1
337 sbw430_writemem(0x012A, 0xA540);
338 //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
339 sbw430_writemem(0x012C, 0xA500); //all but info flash.
341 //Write the word itself.
342 sbw430_writeflashword(adr,data);
344 //FCTL1=0xA500, disabling flash write
345 sbw430_writemem(0x0128, 0xA500);
347 //sbw430_releasecpu();
357 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
358 sbw_dr_shift16(0x2C01); // apply
359 sbw_dr_shift16(0x2401); // remove
365 sbwid = sbw_ir_shift8(IR_ADDR_CAPTURE); // get SBW identifier
368 sbw430_writemem(0x0120, 0x5A80); // Diabled Watchdog
373 #define ERASE_GLOB 0xA50E
374 #define ERASE_ALLMAIN 0xA50C
375 #define ERASE_MASS 0xA506
376 #define ERASE_MAIN 0xA504
377 #define ERASE_SGMT 0xA502
379 //! Configure flash, then write a word.
380 void sbw430_eraseflash(unsigned int mode, unsigned int adr, unsigned int count){
384 sbw430_writemem(0x0128, mode);
385 //FCTL2=0xA540, selecting MCLK as source, DIV=1
386 sbw430_writemem(0x012A, 0xA540);
387 //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
388 sbw430_writemem(0x012C, 0xA500);
390 //Write the erase word.
391 sbw430_writemem(adr, 0x55AA);
392 //Return to read mode.
394 sbw_ir_shift8(IR_CNTRL_SIG_16BIT);
395 sbw_dr_shift16(0x2409);
398 debugstr("ERROR: Haven't got ASM to flash-pulse SBW.");
399 //sbw430_tclk_flashpulses(count);
401 //FCTL1=0xA500, disabling flash write
402 sbw430_writemem(0x0128, 0xA500);
404 //sbw430_releasecpu();
408 //! Reset the TAP state machine.
409 void sbw430_resettap(){
417 // Navigate to reset state.
418 // Should be at least six.
432 Sometimes this isn't necessary. */
446 /* To select the 2-wire SBW mode, the SBWTDIO line is held high and
447 the first clock is applied on SBWTCK. After this clock, the
448 normal SBW timings are applied starting with the TMS slot, and
449 the normal JTAG patterns can be applied, typically starting with
450 the Tap Reset and Fuse Check sequence. The SBW mode is exited by
451 holding the TEST/SWBCLK low for more than 100 μs.
458 P5DIR |= SBWTDIO|SBWTCK;
465 // now we're in SBW mode
469 //! Start SBW, take pins
473 //Known-good starting position.
474 //Might be unnecessary.
481 //Perform a reset and disable watchdog.
483 sbw430_writemem(0x120,0x5a80);//disable watchdog
487 //! Start normally, not SBW.
489 debugstr("Exiting SBW.");
492 //Known-good starting position.
493 //Might be unnecessary.
499 //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 SBW
508 //! Set CPU to Instruction Fetch
509 void sbw430_setinstrfetch(){
511 sbw_ir_shift8(IR_CNTRL_SIG_CAPTURE);
513 // Wait until instruction fetch state.
515 if (sbw_dr_shift16(0x0000) & 0x0080)
523 //! Stop JTAG, release pins
531 //! Handles classic MSP430 SBW commands. Forwards others to SBW.
533 void sbw_handler_fn(u8 app, u8 verb, u32 len){
539 * Sometimes SBW doesn't init correctly.
540 * This restarts the connection if the masked-rom
541 * chip ID cannot be read. Should print warning
542 * for testing server.
544 while((i=sbw430_readmem(0xff0))==0xFFFF){
561 //TAP setup, fuse check
564 cmddata[0]=sbw_ir_shift8(IR_BYPASS);
565 //cmddata[0]=0x89; //STINT
572 case JTAG430_HALTCPU:
576 case JTAG430_RELEASECPU:
580 case JTAG430_SETINSTRFETCH:
581 sbw430_setinstrfetch();
585 case JTAG430_READMEM:
589 //Fetch large blocks for bulk fetches,
590 //small blocks for individual peeks.
592 len=(cmddataword[2]);//always even.
595 len&=~1;//clear lsbit
597 txhead(app,verb,len);
600 val=sbw430_readmem(at);
604 serial_tx((val&0xFF00)>>8);
607 case JTAG430_WRITEMEM:
610 sbw430_writemem(cmddataword[0],cmddataword[2]);
611 cmddataword[0]=sbw430_readmem(cmddataword[0]);
615 case JTAG430_WRITEFLASH:
618 for(i=0;i<(len>>1)-2;i++){
619 //debugstr("Poking flash memory.");
620 sbw430_writeflash(at+(i<<1),cmddataword[i+2]);
621 //Reflash if needed. Try this twice to save grace?
622 if(cmddataword[i]!=sbw430_readmem(at))
623 sbw430_writeflash(at+(i<<1),cmddataword[i+2]);
626 //Return result of first write as a word.
627 cmddataword[0]=sbw430_readmem(cmddataword[0]);
631 case JTAG430_ERASEFLASH:
632 sbw430_eraseflash(ERASE_MASS,0xFFFE,0x3000);
637 sbw430_setpc(cmddataword[0]);
642 case JTAG430_COREIP_ID:
643 case JTAG430_DEVICE_ID:
650 //sbwhandle(app,verb,len);
651 debugstr("ERROR, classic JTAG instruction in SBW.");
654 //sbw430_resettap(); //DO NOT UNCOMMENT