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