Repair of 16-bit MSP430 JTAG nearly complete, dump works well.
[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 "jtag.h"
9
10
11 unsigned int jtag430mode=MSP430X2MODE;
12
13 //! Set the program counter.
14 void jtag430_setpc(unsigned int adr){
15   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
16   jtag_dr_shift16(0x3401);// release low byte
17   jtag_ir_shift8(IR_DATA_16BIT);
18   jtag_dr_shift16(0x4030);//Instruction to load PC
19   CLRTCLK;
20   SETTCLK;
21   jtag_dr_shift16(adr);// Value for PC
22   CLRTCLK;
23   jtag_ir_shift8(IR_ADDR_CAPTURE);
24   SETTCLK;
25   CLRTCLK ;// Now PC is set to "PC_Value"
26   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
27   jtag_dr_shift16(0x2401);// low byte controlled by JTAG
28 }
29
30 //! Halt the CPU
31 void jtag430_haltcpu(){
32   //jtag430_setinstrfetch();
33   
34   jtag_ir_shift8(IR_DATA_16BIT);
35   jtag_dr_shift16(0x3FFF);//JMP $+0
36   
37   CLRTCLK;
38   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
39   jtag_dr_shift16(0x2409);//set JTAG_HALT bit
40   SETTCLK;
41 }
42
43 //! Release the CPU
44 void jtag430_releasecpu(){
45   CLRTCLK;
46   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
47   jtag_dr_shift16(0x2401);
48   jtag_ir_shift8(IR_ADDR_CAPTURE);
49   SETTCLK;
50 }
51
52 //! Read data from address
53 unsigned int jtag430_readmem(unsigned int adr){
54   unsigned int toret;
55   
56   CLRTCLK;
57   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
58   
59   if(adr>0xFF)
60     jtag_dr_shift16(0x2409);//word read
61   else
62     jtag_dr_shift16(0x2419);//byte read
63   jtag_ir_shift8(IR_ADDR_16BIT);
64   jtag_dr_shift16(adr);//address
65   jtag_ir_shift8(IR_DATA_TO_ADDR);
66   SETTCLK;
67
68   CLRTCLK;
69   toret=jtag_dr_shift16(0x0000);//16 bit return
70   
71   return toret;
72 }
73
74 //! Write data to address.
75 void jtag430_writemem(unsigned int adr, unsigned int data){
76   CLRTCLK;
77   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
78   if(adr>0xFF)
79     jtag_dr_shift16(0x2408);//word write
80   else
81     jtag_dr_shift16(0x2418);//byte write
82   jtag_ir_shift8(IR_ADDR_16BIT);
83   jtag_dr_shift16(adr);
84   jtag_ir_shift8(IR_DATA_TO_ADDR);
85   jtag_dr_shift16(data);
86   SETTCLK;
87 }
88
89 //! Write data to flash memory.  Must be preconfigured.
90 void jtag430_writeflashword(unsigned int adr, unsigned int data){
91   /*
92   CLRTCLK;
93   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
94   jtag_dr_shift16(0x2408);//word write
95   jtag_ir_shift8(IR_ADDR_16BIT);
96   jtag_dr_shift16(adr);
97   jtag_ir_shift8(IR_DATA_TO_ADDR);
98   jtag_dr_shift16(data);
99   SETTCLK;
100   
101   //Return to read mode.
102   CLRTCLK;
103   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
104   jtag_dr_shift16(0x2409);
105   */
106   
107   jtag430_writemem(adr,data);
108   CLRTCLK;
109   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
110   jtag_dr_shift16(0x2409);
111   
112   //Pulse TCLK
113   jtag430_tclk_flashpulses(35); //35 standard
114   
115 }
116
117 //! Configure flash, then write a word.
118 void jtag430_writeflash(unsigned int adr, unsigned int data){
119   jtag430_haltcpu();
120   
121   //FCTL1=0xA540, enabling flash write
122   jtag430_writemem(0x0128, 0xA540);
123   //FCTL2=0xA540, selecting MCLK as source, DIV=1
124   jtag430_writemem(0x012A, 0xA540);
125   //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
126   jtag430_writemem(0x012C, 0xA500);
127   
128   //Write the word itself.
129   jtag430_writeflashword(adr,data);
130   
131   //FCTL1=0xA500, disabling flash write
132   jtag430_writemem(0x0128, 0xA500);
133   
134   jtag430_releasecpu();
135 }
136
137
138
139 //! Power-On Reset
140 void jtag430_por(){
141   unsigned int jtagid;
142
143   // Perform Reset
144   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
145   jtag_dr_shift16(0x2C01); // apply
146   jtag_dr_shift16(0x2401); // remove
147   CLRTCLK;
148   SETTCLK;
149   CLRTCLK;
150   SETTCLK;
151   CLRTCLK;
152   jtagid = jtag_ir_shift8(IR_ADDR_CAPTURE); // get JTAG identifier
153   SETTCLK;
154   
155   jtag430_writemem(0x0120, 0x5A80);   // Diabled Watchdog
156 }
157
158
159
160 #define ERASE_GLOB 0xA50E
161 #define ERASE_ALLMAIN 0xA50C
162 #define ERASE_MASS 0xA506
163 #define ERASE_MAIN 0xA504
164 #define ERASE_SGMT 0xA502
165
166 //! Configure flash, then write a word.
167 void jtag430_eraseflash(unsigned int mode, unsigned int adr, unsigned int count){
168   jtag430_haltcpu();
169   
170   //FCTL1= erase mode
171   jtag430_writemem(0x0128, mode);
172   //FCTL2=0xA540, selecting MCLK as source, DIV=1
173   jtag430_writemem(0x012A, 0xA540);
174   //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
175   jtag430_writemem(0x012C, 0xA500);
176   
177   //Write the erase word.
178   jtag430_writemem(adr, 0x55AA);
179   //Return to read mode.
180   CLRTCLK;
181   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
182   jtag_dr_shift16(0x2409);
183   
184   //Send the pulses.
185   jtag430_tclk_flashpulses(count);
186   
187   //FCTL1=0xA500, disabling flash write
188   jtag430_writemem(0x0128, 0xA500);
189   
190   jtag430_releasecpu();
191 }
192
193
194 //! Reset the TAP state machine.
195 void jtag430_resettap(){
196   int i;
197   // Settle output
198   SETTDI; //430X2
199   SETTMS;
200   //SETTDI; //classic
201   SETTCK;
202
203   // Navigate to reset state.
204   // Should be at least six.
205   for(i=0;i<4;i++){
206     CLRTCK;
207     SETTCK;
208   }
209
210   // test-logic-reset
211   CLRTCK;
212   CLRTMS;
213   SETTCK;
214   SETTMS;
215   // idle
216
217     
218   /* sacred, by spec.
219      Sometimes this isn't necessary.  */
220   // fuse check
221   CLRTMS;
222   delay(50);
223   SETTMS;
224   CLRTMS;
225   delay(50);
226   SETTMS;
227   /**/
228   
229 }
230
231 //! Start JTAG, take pins
232 void jtag430_start(){
233   jtagsetup();
234   
235   //Known-good starting position.
236   //Might be unnecessary.
237   SETTST;
238   SETRST;
239   delay(0xFFFF);
240   
241   //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG
242   CLRRST;
243   delay(100); //100
244   CLRTST;
245   delay(50);  //50
246   SETTST;
247   delay(50);  //50
248   SETRST;
249   P5DIR&=~RST;
250   delay(0xFFFF);
251   
252   //Perform a reset and disable watchdog.
253   jtag430_por();
254 }
255
256 //! Set CPU to Instruction Fetch
257 void jtag430_setinstrfetch(){
258   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
259
260   // Wait until instruction fetch state.
261   while(1){
262     if (jtag_dr_shift16(0x0000) & 0x0080)
263       return;
264     CLRTCLK;
265     SETTCLK;
266   }
267 }
268
269
270 //! Handles classic MSP430 JTAG commands.  Forwards others to JTAG.
271 void oldjtag430handle(unsigned char app,
272                    unsigned char verb,
273                    unsigned char len){
274   register char blocks;
275   unsigned long at;
276   unsigned int i, val;
277   
278   switch(verb){
279   case START:
280     //Enter JTAG mode.
281     jtag430_start();
282     //TAP setup, fuse check
283     jtag430_resettap();
284     
285     txdata(app,verb,0);
286     break;
287   case JTAG430_HALTCPU:
288     jtag430_haltcpu();
289     txdata(app,verb,0);
290     break;
291   case JTAG430_RELEASECPU:
292     jtag430_releasecpu();
293     txdata(app,verb,0);
294     break;
295   case JTAG430_SETINSTRFETCH:
296     jtag430_setinstrfetch();
297     txdata(app,verb,0);
298     break;
299     
300   case JTAG430_READMEM:
301   case PEEK:
302     /*
303     cmddataword[0]=jtag430_readmem(cmddataword[0]);
304     txdata(app,verb,2);
305     */
306     blocks=(len>4?cmddata[4]:1);
307     at=cmddatalong[0];
308     
309     len=0x80;
310     serial_tx(app);
311     serial_tx(verb);
312     serial_tx(len);
313     
314     while(blocks--){
315       for(i=0;i<len;i+=2){
316         jtag430_resettap();
317         delay(10);
318         
319         val=jtag430_readmem(at);
320                 
321         at+=2;
322         serial_tx(val&0xFF);
323         serial_tx((val&0xFF00)>>8);
324       }
325     }
326     
327     
328     
329     break;
330   case JTAG430_WRITEMEM:
331   case POKE:
332     jtag430_writemem(cmddatalong[0],cmddataword[2]);
333     cmddataword[0]=jtag430_readmem(cmddatalong[0]);
334     txdata(app,verb,2);
335     break;
336   case JTAG430_WRITEFLASH:
337     jtag430_writeflash(cmddataword[0],cmddataword[1]);
338     cmddataword[0]=jtag430_readmem(cmddataword[0]);
339     txdata(app,verb,2);
340     break;
341   case JTAG430_ERASEFLASH:
342     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
343     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
344     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
345     txdata(app,verb,0);
346     break;
347   case JTAG430_SETPC:
348     jtag430_setpc(cmddataword[0]);
349     txdata(app,verb,0);
350     break;
351     
352   case JTAG430_COREIP_ID:
353   case JTAG430_DEVICE_ID:
354     cmddataword[0]=0;
355     cmddataword[1]=0;
356     txdata(app,verb,4);
357     break;
358     
359   default:
360     jtaghandle(app,verb,len);
361   }
362   jtag430_resettap();
363 }
364
365 //! Handles unique MSP430 JTAG commands.  Forwards others to JTAG.
366 void jtag430handle(unsigned char app,
367                    unsigned char verb,
368                    unsigned char len){
369   switch(jtag430mode){
370   case MSP430MODE:
371     return oldjtag430handle(app,verb,len);
372   case MSP430X2MODE:
373     return jtag430x2handle(app,verb,len);
374   default:
375     txdata(app,NOK,0);
376   }
377 }