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