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