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