Closer to MSP430X2 support.
[goodfet] / firmware / apps / jtag / jtag430.c
1 /*! \file jtag430.c
2   \author Travis Goodspeed <travis at radiantmachines.com>
3   \brief MSP430 JTAG (16-bit)
4 */
5
6 #include "platform.h"
7 #include "command.h"
8 #include "jtag430.h"
9
10 //! Handles classic MSP430 JTAG commands.  Forwards others to JTAG.
11 void jtag430_handle_fn(uint8_t const app,
12                        uint8_t const verb,
13                        uint32_t const len);
14
15 // define the jtag430 app's app_t
16 app_t const jtag430_app = {
17
18         /* app number */
19         JTAG430,
20
21         /* handle fn */
22         jtag430_handle_fn,
23
24         /* name */
25         "JTAG430",
26
27         /* desc */
28         "\tThe JTAG430 app adds to the basic JTAG app\n"
29         "\tsupport for JTAG'ing MSP430 devices.\n"
30 };
31
32 unsigned int jtag430mode=MSP430X2MODE;
33
34 //! Set a register.
35 void jtag430_setr(u8 reg, u16 val){
36   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
37   jtag_dr_shift16(0x3401);// release low byte
38   jtag_ir_shift8(IR_DATA_16BIT);
39   
40   //0x4030 is "MOV #foo, r0"
41   //Right-most field is register, so 0x4035 loads r5
42   jtag_dr_shift16(0x4030+reg);
43   CLRTCLK;
44   SETTCLK;
45   jtag_dr_shift16(val);// Value for the register
46   CLRTCLK;
47   jtag_ir_shift8(IR_ADDR_CAPTURE);
48   SETTCLK;
49   CLRTCLK ;// Now reg is set to new value.
50   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
51   jtag_dr_shift16(0x2401);// low byte controlled by JTAG
52 }
53
54 //! Set the program counter.
55 void jtag430_setpc(unsigned int adr){
56   jtag430_setr(0,adr);
57 }
58
59 //! Halt the CPU
60 void jtag430_haltcpu(){
61   //jtag430_setinstrfetch();
62   
63   jtag_ir_shift8(IR_DATA_16BIT);
64   jtag_dr_shift16(0x3FFF);//JMP $+0
65   
66   CLRTCLK;
67   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
68   jtag_dr_shift16(0x2409);//set JTAG_HALT bit
69   SETTCLK;
70 }
71
72 //! Release the CPU
73 void jtag430_releasecpu(){
74   CLRTCLK;
75   //debugstr("Releasing target MSP430.");
76   
77   /*
78   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
79   jtag_dr_shift16(0x2C01); //Apply reset.
80   jtag_dr_shift16(0x2401); //Release reset.
81   */
82   jtag_ir_shift8(IR_CNTRL_SIG_RELEASE);
83   SETTCLK;
84 }
85
86 //! Read data from address
87 unsigned int jtag430_readmem(unsigned int adr){
88   unsigned int toret;
89   jtag430_haltcpu();
90   
91   CLRTCLK;
92   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
93   
94   if(adr>0xFF)
95     jtag_dr_shift16(0x2409);//word read
96   else
97     jtag_dr_shift16(0x2419);//byte read
98   jtag_ir_shift8(IR_ADDR_16BIT);
99   jtag_dr_shiftadr(adr);//address
100   jtag_ir_shift8(IR_DATA_TO_ADDR);
101   SETTCLK;
102
103   CLRTCLK;
104   toret=jtag_dr_shift16(0x0000);//16 bit return
105   
106   return toret;
107 }
108
109 //! Write data to address.
110 void jtag430_writemem(unsigned int adr, unsigned int data){
111   CLRTCLK;
112   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
113   if(adr>0xFF)
114     jtag_dr_shift16(0x2408);//word write
115   else
116     jtag_dr_shift16(0x2418);//byte write
117   jtag_ir_shift8(IR_ADDR_16BIT);
118   jtag_dr_shiftadr(adr);
119   jtag_ir_shift8(IR_DATA_TO_ADDR);
120   jtag_dr_shift16(data);
121   SETTCLK;
122 }
123
124 //! Write data to flash memory.  Must be preconfigured.
125 void jtag430_writeflashword(unsigned int adr, unsigned int data){
126   
127   CLRTCLK;
128   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
129   jtag_dr_shift16(0x2408);//word write
130   jtag_ir_shift8(IR_ADDR_16BIT);
131   jtag_dr_shiftadr(adr);
132   jtag_ir_shift8(IR_DATA_TO_ADDR);
133   jtag_dr_shift16(data);
134   SETTCLK;
135   
136   //Return to read mode.
137   CLRTCLK;
138   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
139   jtag_dr_shift16(0x2409);
140   
141   /*
142   jtag430_writemem(adr,data);
143   CLRTCLK;
144   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
145   jtag_dr_shift16(0x2409);
146   */
147   
148   //Pulse TCLK
149   jtag430_tclk_flashpulses(35); //35 standard
150 }
151
152 //! Configure flash, then write a word.
153 void jtag430_writeflash(unsigned int adr, unsigned int data){
154   jtag430_haltcpu();
155   
156   //FCTL1=0xA540, enabling flash write
157   jtag430_writemem(0x0128, 0xA540);
158   //FCTL2=0xA540, selecting MCLK as source, DIV=1
159   jtag430_writemem(0x012A, 0xA540);
160   //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
161   jtag430_writemem(0x012C, 0xA500); //all but info flash.
162   //if(jtag430_readmem(0x012C));
163   
164   //Write the word itself.
165   jtag430_writeflashword(adr,data);
166   
167   //FCTL1=0xA500, disabling flash write
168   jtag430_writemem(0x0128, 0xA500);
169   
170   //jtag430_releasecpu();
171 }
172
173
174
175 //! Power-On Reset
176 void jtag430_por(){
177   // Perform Reset
178   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
179   jtag_dr_shift16(0x2C01); // apply
180   jtag_dr_shift16(0x2401); // remove
181   CLRTCLK;
182   SETTCLK;
183   CLRTCLK;
184   SETTCLK;
185   CLRTCLK;
186   jtagid = jtag_ir_shift8(IR_ADDR_CAPTURE); // get JTAG identifier
187   SETTCLK;
188   
189   jtag430_writemem(0x0120, 0x5A80);   // Diabled Watchdog
190 }
191
192
193
194 #define ERASE_GLOB 0xA50E
195 #define ERASE_ALLMAIN 0xA50C
196 #define ERASE_MASS 0xA506
197 #define ERASE_MAIN 0xA504
198 #define ERASE_SGMT 0xA502
199
200 //! Configure flash, then write a word.
201 void jtag430_eraseflash(unsigned int mode, unsigned int adr, unsigned int count,
202                         unsigned int info){
203   jtag430_haltcpu();
204   
205   //FCTL1= erase mode
206   jtag430_writemem(0x0128, mode);
207   //FCTL2=0xA540, selecting MCLK as source, DIV=1
208   jtag430_writemem(0x012A, 0xA540);
209   //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
210   if(info)
211     jtag430_writemem(0x012C, 0xA540);
212   else
213     jtag430_writemem(0x012C, 0xA500);
214   
215   //Write the erase word.
216   jtag430_writemem(adr, 0x55AA);
217   //Return to read mode.
218   CLRTCLK;
219   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
220   jtag_dr_shift16(0x2409);
221   
222   //Send the pulses.
223   jtag430_tclk_flashpulses(count);
224   
225   //FCTL1=0xA500, disabling flash write
226   jtag430_writemem(0x0128, 0xA500);
227   
228   //jtag430_releasecpu();
229 }
230
231
232 //! Reset the TAP state machine.
233 void jtag430_resettap(){
234   int i;
235   // Settle output
236   SETTDI; //430X2
237   SETTMS;
238   //SETTDI; //classic
239   TCKTOCK;
240
241   // Navigate to reset state.
242   // Should be at least six.
243   for(i=0;i<4;i++){
244     TCKTOCK;
245   }
246
247   // test-logic-reset
248   CLRTMS;
249   TCKTOCK;
250   SETTMS;
251   // idle
252
253     
254   /* sacred, by spec.
255      Sometimes this isn't necessary.  */
256   // fuse check
257   CLRTMS;
258   delay(50);
259   SETTMS;
260   CLRTMS;
261   delay(50);
262   SETTMS;
263   /**/
264   
265 }
266
267
268 //! Get the JTAG ID
269 unsigned char jtag430x2_jtagid(){
270   jtag430_resettap();
271   jtagid=jtag_ir_shift8(IR_BYPASS);
272   if(jtagid!=0x89 && jtagid!=0x91){
273     debugstr("Unknown JTAG ID");
274     debughex(jtagid);
275   }
276   return jtagid;
277 }
278 //! Start JTAG, take pins
279 unsigned char jtag430x2_start(){
280   jtagsetup();
281   
282   //Known-good starting position.
283   //Might be unnecessary.
284   SETTST;
285   SETRST;
286   
287   delay(0xFFFF);
288   
289   //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG
290   CLRRST;
291   delay(20);//10
292   CLRTST;
293
294   delay(10);//5
295   SETTST;
296   msdelay(10);//5
297   SETRST;
298   P5DIR&=~RST;
299   
300   delay(0xFFFF);
301   
302   //Perform a reset and disable watchdog.
303   return jtag430x2_jtagid();
304 }
305
306
307 //! Start JTAG, take pins
308 void jtag430_start(){
309   jtagsetup();
310   
311   //Known-good starting position.
312   //Might be unnecessary.
313   SETTST;
314   SETRST;
315   delay(0xFFFF);
316
317
318   #ifndef SBWREWRITE
319   //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG
320   CLRRST;
321   delay(100); //100
322   CLRTST;
323   delay(50);  //50
324   SETTST;
325   delay(50);  //50
326   SETRST;
327   P5DIR&=~RST;
328   delay(0xFFFF);
329   #endif
330   
331   //Perform a reset and disable watchdog.
332   jtag430_por();
333   jtag430_writemem(0x120,0x5a80);//disable watchdog
334   
335   jtag430_haltcpu();
336 }
337
338 //! Stop JTAG.
339 void jtag430_stop(){
340   debugstr("Exiting JTAG.");
341   jtagsetup();
342   
343   //Known-good starting position.
344   //Might be unnecessary.
345   //SETTST;
346   CLRTST;
347   SETRST;
348   delay(0xFFFF);
349   
350   //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG
351   CLRRST;
352   delay(0xFFFF);
353   SETRST;
354   //P5DIR&=~RST;
355   //delay(0xFFFF);
356   
357 }
358
359 //! Set CPU to Instruction Fetch
360 void jtag430_setinstrfetch(){
361   
362   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
363
364   // Wait until instruction fetch state.
365   while(1){
366     if (jtag_dr_shift16(0x0000) & 0x0080)
367       return;
368     CLRTCLK;
369     SETTCLK;
370   }
371 }
372
373
374
375
376
377 //! Handles classic MSP430 JTAG commands.  Forwards others to JTAG.
378 void jtag430_handle_fn(uint8_t const app,
379                                            uint8_t const verb,
380                                            uint32_t const len)
381 {
382   unsigned long at, l;
383   unsigned int i, val;
384   
385   
386   /* FIXME
387    * Sometimes JTAG doesn't init correctly.
388    * This restarts the connection if the masked-rom
389    * chip ID cannot be read.  Should print warning
390    * for testing server.
391    */
392   if (jtagid!=0)
393     while((i=jtag430_readmem(0xff0))==0xFFFF){
394       debugstr("Reconnecting to target MSP430.");
395       jtag430x2_start();
396       PLEDOUT^=PLEDPIN;
397     }
398   PLEDOUT&=~PLEDPIN;
399   
400   
401   switch(verb){
402   case START:
403     /* old method, classic MSP430. 
404     //Enter JTAG mode.
405     jtag430x2_start();
406     //TAP setup, fuse check
407     jtag430_resettap();
408     
409     cmddata[0]=jtag_ir_shift8(IR_BYPASS);    
410     txdata(app,verb,1);
411     */
412     
413     jtag430x2_start();
414     cmddata[0]=jtagid;
415     
416     if(jtagid!=MSP430JTAGID){
417       debugstr("Using JTAG430 (instead of JTAG430X2)!");
418     }
419     jtag430mode=MSP430MODE;
420     
421     /* So the way this works is that a width of 20 does some
422        backward-compatibility finagling, causing the correct value
423        to be exchanged for addresses on 16-bit chips as well as the
424        new MSP430X chips.  (This has only been verified on the
425        MSP430F2xx family.  TODO verify for others.)
426     */
427     
428     drwidth=20;
429     
430     //Perform a reset and disable watchdog.
431     jtag430_por();
432     jtag430_writemem(0x120,0x5a80);//disable watchdog
433     
434     jtag430_haltcpu();
435     
436     jtag430_resettap();
437     txdata(app,verb,1);
438     
439     break;
440   case STOP:
441     jtag430_stop();
442     txdata(app,verb,0);
443     break;
444   case JTAG430_HALTCPU:
445     jtag430_haltcpu();
446     txdata(app,verb,0);
447     break;
448   case JTAG430_RELEASECPU:
449     jtag430_releasecpu();
450     txdata(app,verb,0);
451     break;
452   case JTAG430_SETINSTRFETCH:
453     jtag430_setinstrfetch();
454     txdata(app,verb,0);
455     break;
456     
457   case JTAG430_READMEM:
458   case PEEK:
459     at=cmddatalong[0];
460     
461     //Fetch large blocks for bulk fetches,
462     //small blocks for individual peeks.
463     if(len>5)
464       l=(cmddataword[2]);//always even.
465     else
466       l=2;
467     l&=~1;//clear lsbit
468     
469     txhead(app,verb,l);
470     for(i = 0; i < l; i += 2) {
471       jtag430_resettap();
472       val=jtag430_readmem(at);
473       
474       at+=2;
475       serial_tx(val&0xFF);
476       serial_tx((val&0xFF00)>>8);
477     }
478     break;
479   case JTAG430_WRITEMEM:
480   case POKE:
481     jtag430_haltcpu();
482     jtag430_writemem(cmddataword[0],cmddataword[2]);
483     cmddataword[0]=jtag430_readmem(cmddataword[0]);
484     txdata(app,verb,2);
485     break;
486     /*
487   case JTAG430_WRITEFLASH:
488
489     //debugstr("Poking flash memory.");
490     jtag430_writeflash(cmddataword[0],cmddataword[2]);
491     
492     //Try again if failure.
493     //if(cmddataword[2]!=jtag430_readmem(cmddataword[0]))
494     //  jtag430_writeflash(cmddataword[0],cmddataword[2]);
495     
496     //Return result.
497     cmddataword[0]=jtag430_readmem(cmddataword[0]);
498     
499     txdata(app,verb,2);
500     break; */
501   case JTAG430_WRITEFLASH:
502     at=cmddataword[0];
503     
504     for(i=0;i<(len>>1)-2;i++){
505       //debugstr("Poking flash memory.");
506       jtag430_writeflash(at+(i<<1),cmddataword[i+2]);
507       //Reflash if needed.  Try this twice to save grace?
508       if(cmddataword[i]!=jtag430_readmem(at))
509         jtag430_writeflash(at+(i<<1),cmddataword[i+2]);
510     }
511     
512     //Return result of first write as a word.
513     cmddataword[0]=jtag430_readmem(cmddataword[0]);
514     
515     txdata(app,verb,2);
516     break;
517   case JTAG430_ERASEFLASH:
518     jtag430_eraseflash(ERASE_MASS,0xFFFE,0x3000,0);
519     txdata(app,verb,0);
520     break;
521   case JTAG430_ERASEINFO:
522     jtag430_eraseflash(ERASE_SGMT,0x1000,0x3000,1);
523     txdata(app,verb,0);
524     break;
525   case JTAG430_SETPC:
526     jtag430_haltcpu();
527     //debughex("Setting PC.");
528     //debughex(cmddataword[0]);
529     jtag430_setpc(cmddataword[0]);
530     jtag430_releasecpu();
531     txdata(app,verb,0);
532     break;
533   case JTAG430_SETREG:
534     jtag430_setr(cmddata[0],cmddataword[1]);
535     txdata(app,verb,0);
536     break;
537   case JTAG430_GETREG:
538     //jtag430_getr(cmddata[0]);
539     debugstr("JTAG430_GETREG not yet implemented.");
540     cmddataword[0]=0xDEAD;
541     txdata(app,verb,2);
542     break;
543   case JTAG430_COREIP_ID:
544     //cmddataword[0]=jtag430_coreid();
545     cmddataword[0]=0xdead;
546     txdata(app,verb,2);
547     break;
548   case JTAG430_DEVICE_ID:
549     //cmddatalong[0]=jtag430_deviceid();
550     cmddataword[0]=0xdead;
551     cmddataword[0]=0xbeef;
552     txdata(app,verb,4);
553     break;
554   default:
555     (*(jtag_app.handle))(app,verb,len);
556   }
557   //jtag430_resettap();  //DO NOT UNCOMMENT
558 }